使用 IE9 嵌入 WebBrowser 控件时覆盖 IE 设置
我有一个应用程序(使用 MFC 用 C++ 编写,但我认为这不是特别相关),它嵌入了 Internet Explorer ActiveX WebBrowser 控件,用于显示一些 HTML 页面。一项要求始终是使用应用程序的字体名称和大小设置作为 HTML 的默认设置,而不是 Internet Exporer 的默认设置。
为了实现此目的,应用程序实现 IDocHostUIHandler2 COM 接口,并将其传递给 WebBrowser 控件。这会导致控件调用应用程序的 GetOptionKeyPath 的实现,它允许应用程序设置 WebBrowser 控件从中获取其设置的注册表位置。借助 Sysinternals 的工具来查看 IE 使用哪些键来查找字体名称和大小,这足以满足我的需要。
然而,Internet Explorer 9 的出现却令人大吃一惊:在我测试过的所有安装了 IE9 的计算机上,WebBrowser 控件使用自己的设置,忽略应用程序的注册表位置。使用调试器进行测试表明 WebBrowser 控件从不调用提供的 GetOptionKeyPath。
更多实验表明 IE9 WebBrowser 控件正在调用类似(但不相同)的 GetOverrideKeyPath 方法:据称,这提供了一种覆盖 IE 设置的方法,如果在相关部分中找不到任何内容,则返回到 IE 的实际设置注册表的。不幸的是,这有两个问题:1)这不完全是我想要的,2)IE9 在进入 IE 默认注册表设置之前并不总是检查 GetOverrideKeyPath 注册表位置。
查看 GetOptionKeyPath MSDN 页面有一些类似的投诉,但没有解决方案。有没有人找到一种干净的方法来说服 WebBrowser 控件恢复到实际调用 GetOptionKeyPath 的 IE9 之前的行为(如文档所示)?
I have an application (written in C++ with MFC, but I don't think that that's particularly relevant) that embeds the Internet Explorer ActiveX WebBrowser control for the purpose of showing some HTML pages. One requirement has always been to use the application's font name and size settings as the default settings for the HTML, rather than Internet Exporer's defaults.
To achieve this, the application implements the IDocHostUIHandler2 COM interface, which it passes to the WebBrowser control. This causes the control to call the application's implementation of GetOptionKeyPath, which lets the application set the registry location that the WebBrowser control gets its settings from. Armed with Sysinternals' tools to see which keys IE uses to find the font name and size, this has been sufficient to do what I need.
However, the appeareance of Internet Explorer 9 has come as a nasty surprise: on all machines that I've tested with that have IE9 installed, the WebBrowser control uses its own settings, ignoring the registry location from the application. Testing with a debugger shows that the WebBrowser control never calls the provided GetOptionKeyPath.
A bit more experimentation shows that the IE9 WebBrowser control is calling the similar (but not identical) GetOverrideKeyPath method: this allegedly provides a way to override IE settings, while falling back to IE's actual settings if nothing is found in the relevant part of the registry. Unfortunately this has two problems: 1) It's not quite what I want, and 2) IE9 doesn't always check under the GetOverrideKeyPath registry location before going to the IE default registry settings.
Looking at the GetOptionKeyPath MSDN page there are a few complaints along similar lines, but no solutions. Has anyone found a clean way to persuade the WebBrowser control to revert to the pre-IE9 behaviour of actually calling GetOptionKeyPath as documented?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我想出了一个解决这个问题的方法,但我应该警告你:它并不漂亮。如果您很容易被冒犯,请立即停止阅读...
由于似乎没有办法让 IE9 使用 IDocHostUIHandler::GetOptionKeyPath() 方法,我使用 SysInternals 的工具来查看哪些 IE9 DLL 访问了注册表的相关部分加载 IE9 设置。这揭示了唯一的罪魁祸首是“mshtml.dll”和“iertutil.dll”,它们都调用 RegOpenKeyExW()。
然后的计划是在初始化 WebBrowser 控件之前加载这些 DLL,并对它们进行修补,以便将调用重定向到我的代码,在代码中我可以使用 dbghelp.dll 谎报我打开的注册表项。因此,首先,在初始化 WebBrowser 控件之前:
现在,执行扫描 DLL 导入地址表并修补所请求函数的邪恶工作的代码(省略错误处理以减少代码大小):
最后,该函数我已经修补了 DLL 以在我的代码中调用,以代替 RegOpenKeyExW():
令人惊讶的是,这个可怕的 hack 确实有效。但是微软,如果你在听的话,请在 IE10 中正确修复这个问题。
I've come up with a hack to solve this problem, but I should warn you: it's not pretty. Stop reading now if you've easily offended ...
Since there seems to be no way of making IE9 use the IDocHostUIHandler::GetOptionKeyPath() method, I used SysInternals' tools to see which IE9 DLLs accessed the relevant parts of the registry to load the IE9 settings. This revealed the only culprits as "mshtml.dll" and "iertutil.dll", both of which call RegOpenKeyExW().
The plan was then to load these DLLs before initializing the WebBrowser control, and patch them so that calls are redirected to my code, where I can lie about what registry key I've opened, using dbghelp.dll. So, to start, before initializing the WebBrowser control:
And now, the code that does the evil work of scanning the DLLs import address tables, and patching the requested function (error handling omitted to keep the code size down):
Finally, the function that I have patched the DLLs to call in my code, in place of RegOpenKeyExW():
Amazingly enough, this horrible hack actually works. But please, Microsoft, if you're listening, please fix this properly in IE10.