Web浏览器控件仿真问题(FEATURE_browser_emulation)
Web browser control emulation issue (FEATURE_BROWSER_EMULATION)
使用VS2013,我创建了一个非常简单的web浏览器控件应用程序,可以导航到http://demos.dojotoolkit.org/demos/calendar/demo.html
当注册表中没有为此应用程序设置FEATURE_BROWSER_EMULATION时,站点正常工作。当将应用程序添加到此注册表项(在HKLM下)时,它一直工作到IE9模拟,但IE10和IE11值失败(我的机器上有IE11)。
示例:
FEATURE_BROWSER_EMULATION
myApp=9999 - works
myApp=10001 - doesn't work
不起作用=月份日期选择器不起作用有什么建议吗?问题出在哪里?
谢谢,Guy
下面是我的WebBrowser
游乐场应用程序(C#),它能很好地与您的URL配合使用(http://demos.dojotoolkit.org/demos/calendar/demo.html)。
我相信,禁用FEATURE_NINPUT_LEGACY_MODE
是造成差异的原因。我还启用了一些其他设置。它还展示了如何使用HKEY_CURRENT_USER
而不是HKLM
,这样应用程序就不需要管理员权限。
using Microsoft.Win32;
using System;
using System.ComponentModel;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WebBrowserApp
{
public partial class MainForm : Form
{
const int POLL_DELAY = 250;
WebBrowser _webBrowser;
// set WebBrowser features, more info: http://stackoverflow.com/a/18333982/1768303
static void SetWebBrowserFeatures()
{
// don't change the registry if running in-proc inside Visual Studio
if (LicenseManager.UsageMode != LicenseUsageMode.Runtime)
return;
var appName = System.IO.Path.GetFileName(System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName);
var featureControlRegKey = @"HKEY_CURRENT_USERSoftwareMicrosoftInternet ExplorerMainFeatureControl";
Registry.SetValue(featureControlRegKey + "FEATURE_BROWSER_EMULATION",
appName, GetBrowserEmulationMode(), RegistryValueKind.DWord);
// enable the features which are "On" for the full Internet Explorer browser
Registry.SetValue(featureControlRegKey + "FEATURE_ENABLE_CLIPCHILDREN_OPTIMIZATION",
appName, 1, RegistryValueKind.DWord);
Registry.SetValue(featureControlRegKey + "FEATURE_AJAX_CONNECTIONEVENTS",
appName, 1, RegistryValueKind.DWord);
Registry.SetValue(featureControlRegKey + "FEATURE_GPU_RENDERING",
appName, 1, RegistryValueKind.DWord);
Registry.SetValue(featureControlRegKey + "FEATURE_WEBOC_DOCUMENT_ZOOM",
appName, 1, RegistryValueKind.DWord);
Registry.SetValue(featureControlRegKey + "FEATURE_NINPUT_LEGACYMODE",
appName, 0, RegistryValueKind.DWord);
}
static UInt32 GetBrowserEmulationMode()
{
int browserVersion = 0;
using (var ieKey = Registry.LocalMachine.OpenSubKey(@"SOFTWAREMicrosoftInternet Explorer",
RegistryKeyPermissionCheck.ReadSubTree,
System.Security.AccessControl.RegistryRights.QueryValues))
{
var version = ieKey.GetValue("svcVersion");
if (null == version)
{
version = ieKey.GetValue("Version");
if (null == version)
throw new ApplicationException("Microsoft Internet Explorer is required!");
}
int.TryParse(version.ToString().Split('.')[0], out browserVersion);
}
if (browserVersion < 7)
{
throw new ApplicationException("Unsupported version of Microsoft Internet Explorer!");
}
UInt32 mode = 11000; // Internet Explorer 11. Webpages containing standards-based !DOCTYPE directives are displayed in IE11 Standards mode.
switch (browserVersion)
{
case 7:
mode = 7000; // Webpages containing standards-based !DOCTYPE directives are displayed in IE7 Standards mode.
break;
case 8:
mode = 8000; // Webpages containing standards-based !DOCTYPE directives are displayed in IE8 mode.
break;
case 9:
mode = 9000; // Internet Explorer 9. Webpages containing standards-based !DOCTYPE directives are displayed in IE9 mode.
break;
case 10:
mode = 10000; // Internet Explorer 10.
break;
}
return mode;
}
// static constructor, runs first
static MainForm()
{
SetWebBrowserFeatures();
}
public MainForm()
{
InitializeComponent();
_webBrowser = new WebBrowser() { Dock = DockStyle.Fill };
this.Controls.Add(_webBrowser);
this.Size = new System.Drawing.Size(800, 600);
this.Load += MainForm_Load;
}
// start the task
async void MainForm_Load(object sender, EventArgs e)
{
try
{
dynamic document = await LoadDynamicPage("http://demos.dojotoolkit.org/demos/calendar/demo.html",
CancellationToken.None);
MessageBox.Show(new { document.documentMode, document.compatMode }.ToString());
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
// navigate and download
async Task<object> LoadDynamicPage(string url, CancellationToken token)
{
// navigate and await DocumentCompleted
var tcs = new TaskCompletionSource<bool>();
WebBrowserDocumentCompletedEventHandler handler = (s, arg) =>
tcs.TrySetResult(true);
using (token.Register(() => tcs.TrySetCanceled(), useSynchronizationContext: false))
{
this._webBrowser.DocumentCompleted += handler;
try
{
this._webBrowser.Navigate(url);
await tcs.Task; // wait for DocumentCompleted
}
finally
{
this._webBrowser.DocumentCompleted -= handler;
}
}
// get the root element
var documentElement = this._webBrowser.Document.GetElementsByTagName("html")[0];
// poll the current HTML for changes asynchronosly
var html = documentElement.OuterHtml;
while (true)
{
// wait asynchronously, this will throw if cancellation requested
await Task.Delay(POLL_DELAY, token);
// continue polling if the WebBrowser is still busy
if (this._webBrowser.IsBusy)
continue;
var htmlNow = documentElement.OuterHtml;
if (html == htmlNow)
break; // no changes detected, end the poll loop
html = htmlNow;
}
// consider the page fully rendered
token.ThrowIfCancellationRequested();
return this._webBrowser.Document.DomDocument;
}
}
}
这对我有效:
yourWebBrowser.ScriptErrorsSuppressed = true;
有关ScriptErrorsSuppressed 的信息,请查看以下网站
摘录自网站:
备注将此属性设置为false可调试在WebBrowser控件中显示的网页。当您使用控件将基于Web的控件和脚本代码添加到应用程序时,这非常有用。当您将控件用作常规浏览器时,它的用处较小。调试完应用程序后,请将此属性设置为true以抑制脚本错误。
注意
当ScriptErrorsSuppressed设置为true时,WebBrowser控件将隐藏源自底层ActiveX控件的所有对话框,而不仅仅是脚本错误。有时,您可能需要在显示对话框(例如用于浏览器安全设置和用户登录的对话框)时抑制脚本错误。在这种情况下,将ScriptErrorsSuppressed设置为false,并在HtmlWindow.Error事件的处理程序中抑制脚本错误。有关更多信息,请参阅本主题中的代码示例。