C#やVB.NETなどのアプリケーションで、WebサイトやHTMLなどを表示したい場合に使うWebBrowserコントロール。
このWebBrowserコントロールを使えば、簡単にInternet Explorer同等のWebページを表示できる。
でも、最近このWebBrowserコントロールで表示崩れが増えてきたような気がする。
例えば、ここのホームページを表示すると、メニューのスタイルが崩れてしまう。
↓WebBrowserコントロールで表示
↓Internet Explorer11で表示
WebBrowserコントロールでは、スタイルシートがうまく反映できていないみたい。
試しにuserAgentを確認してみる
スタイルシートの表示方法が、PCにインストールしてあるIE11と異なるのか?
試しにuserAgentを確認するために以下のJavaScriptを実行してみる。
<script> document.write(navigator.userAgent); </script>
↓IE11の実行結果。
Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; Touch; .NET4.0E; .NET4.0C; .NET CLR 3.5.30729; .NET CLR 2.0.50727; .NET CLR 3.0.30729; Tablet PC 2.0; MASPJS; rv:11.0) like Gecko
↓WebBrowserコントロールの実行結果。
Mozilla/4.0 (compatible; <font color=#FF0000>MSIE 7.0</font>; Windows NT 6.3; WOW64; Trident/7.0; .NET4.0E; .NET4.0C; .NET CLR 3.5.30729; .NET CLR 2.0.50727; .NET CLR 3.0.30729; Tablet PC 2.0; MASPJS)
となる。
なんか違うぞ!
WebBrowserコントロールの場合、IE7のレンダリングモードで動いているようで、
PCにインストールしてあるIE11と、WebBrowserコントロールのIEのレンダリングモードは違うみたい。
レンダリングモードを変更
じゃぁ、WebBrowserコントロールのレタリングモードを変えられないものなのか?
調べてみると、どうやらレジストリで弄ればレタリングモードを変えられるようだ。
でも、レジストリ変更はちょっと抵抗がある。
他に方法が無いか調べてみる。
WebBrowser.Version プロパティなんてのがあるから、これで表示モードを変えられないか期待したけど、getterしかなくインストール済みIEバージョンを取得するためのプロパティだった。。
う~ん困った。
しかも取得したIEバージョンはWebBrowserのレタリングモードの情報じゃなく、PCにインストールしたIEバージョンの情報。
しょうがないんで、レジストリでレンダリングモードを変更する方法でトライすることに。
どうやら、以下のレジストリキーを変更することで切り替えできるらしい。
例えばIE11に切り替えたい場合、以下のようにレジストリを設定。
- ユーザーエージェント
キー名: HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION 名前: exeファイル名 種類: DWORD(32bit)値 値: 11000(10進数)
- レンダリングモード
キー名: HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_DOCUMENT_COMPATIBLE_MODE 名前: exeファイル名 種類: DWORD(32bit)値 値: 110000(10進数)
サンプル
ついでに、モードをいろいろ切り替え試せるサンプルを作ってみた。
GUI
webBrowser、numericUpDown、button×2のコントロールを図のように配置。
C#ソースコード
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.IO; namespace WindowsFormsApplication1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } static bool loadingFlg = true; private void Form1_Load(object sender, EventArgs e) { // IEモード(IE7から、インストール済みIEバージョンまで) numericUpDown1.Minimum = 7; numericUpDown1.Maximum = webBrowser1.Version.Major; try { Microsoft.Win32.RegistryKey regkey = Microsoft.Win32.Registry.CurrentUser.CreateSubKey( @"Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION"); int ieVer = (int)regkey.GetValue(Path.GetFileName(Application.ExecutablePath)); numericUpDown1.Value = ieVer / 1000; regkey.Close(); } catch (Exception ex) { if (ex is IOException || ex is NullReferenceException) { numericUpDown1.Value = 7; } } loadingFlg = false; } // IEモードを切り替える // ※exeファイルから実行すること。 // ※exe再起動で設定反映される。 private void numericUpDown1_ValueChanged(object sender, EventArgs e) { if (loadingFlg) return; try { Microsoft.Win32.RegistryKey regkey1 = Microsoft.Win32.Registry.CurrentUser.CreateSubKey( @"Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION"); Microsoft.Win32.RegistryKey regkey2 = Microsoft.Win32.Registry.CurrentUser.CreateSubKey( @"Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_DOCUMENT_COMPATIBLE_MODE"); if (numericUpDown1.Value == numericUpDown1.Minimum) { regkey1.DeleteValue(Path.GetFileName(Application.ExecutablePath)); regkey2.DeleteValue(Path.GetFileName(Application.ExecutablePath)); } else { regkey1.SetValue( Path.GetFileName(Application.ExecutablePath), Convert.ToInt32(numericUpDown1.Value) * 1000); regkey2.SetValue( Path.GetFileName(Application.ExecutablePath), Convert.ToInt32(numericUpDown1.Value) * 10000); } regkey1.Close(); regkey2.Close(); } catch (Exception ex) { if (ex is IOException || ex is NullReferenceException) { numericUpDown1.Value = 7; } } } // UserAgentを表示する private void button1_Click(object sender, EventArgs e) { webBrowser1.DocumentText = "<script>document.write(navigator.userAgent);</script>"; } // Webを開く private void button2_Click(object sender, EventArgs e) { webBrowser1.Url = new Uri("http://www.osadasoft.com/"); } } }
実行
Visual Studio上からデバッグしながら実行すると、exeファイル名が”*.vshost.exe”などなってしまうため、このままでは動かない。
ビルドしたexeを直接実行するか、上記ソースの「Application.ExecutablePath」の部分を”*.vshost.exe”などの名前に書き換え実行する。
また、モードを切替えた場合、exeを再起動しないと設定反映されないので注意。
IE7モードでUserAgent表示:
IE11モードでUserAgent表示:
IE7モードでWebを表示:(メニューが崩れる)
IE11モードでWebを表示:(メニューは崩れない)
自作ソフトRSS速報でも表示崩れが起こっていたので、これと似たような方法で解決させた。
ソース中のPathには何を設定するのでしょうか?
Pathは、System.IOのクラスです。
10行目の「using System.IO;」を書いておくか、
「Path」の部分を「using System.IO.Path」として
使用してみてください。