windows – 使用IE9嵌入WebBrowser控件时覆盖IE设置
我有一个应用程序(用C语言编写MFC,但我不认为那是特别相关的)嵌入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 page,有类似线路的一些投诉,但没有解决方案.有没有人找到一种干净的方法来说服WebBrowser控件恢复到实际调用GetOptionKeyPath的IE9之前的行为?
我想出一个黑客来解决这个问题,但我应该警告你:它不漂亮.如果你容易被冒犯,现在就停止阅读……
由于似乎无法使IE9使用IDocHostUIHandler :: GetOptionKeyPath()方法,因此我使用SysInternals的工具查看哪些IE9 DLL访问了注册表的相关部分以加载IE9设置.这揭示了唯一的罪魁祸首是“mshtml.dll”和“iertutil.dll”,两者都称为RegOpenKeyExW(). 然后计划在初始化WebBrowser控件之前加载这些DLL,然后对它们进行修补,以便将调用重定向到我的代码,在那里我可以使用dbghelp.dll来解释我打开的注册表项.因此,在初始化WebBrowser控件之前,首先要: if (theApp.GetIEVersion() >= 9.0) { HMODULE advadi = ::LoadLibrary("advapi32.dll"); HMODULE mshtml = ::LoadLibrary("mshtml.dll"); HookApiFunction(mshtml,advadi,"advapi32.dll","RegOpenKeyExW",(PROC)HookRegOpenKeyExW); HMODULE iertutil = ::LoadLibrary("iertutil.dll"); HookApiFunction(iertutil,(PROC)HookRegOpenKeyExW); } 现在,执行扫描DLL的邪恶工作的代码导入地址表,并修补所请求的函数(省略错误处理以保持代码大小): void HookApiFunction(HMODULE callingDll,HMODULE calledDll,const char* calledDllName,const char* functionName,PROC newFunction) { // Get the pointer to the 'real' function PROC realFunction = ::GetProcAddress(calledDll,functionName); // Get the import section of the DLL,using dbghelp.dll's ImageDirectoryEntryToData() ULONG sz; PIMAGE_IMPORT_DESCRIPTOR import = (PIMAGE_IMPORT_DESCRIPTOR) ImageDirectoryEntryToData(callingDll,TRUE,IMAGE_DIRECTORY_ENTRY_IMPORT,&sz); // Find the import section matching the named DLL while (import->Name) { PSTR dllName = (PSTR)((PBYTE)callingDll + import->Name); { if (stricmp(dllName,calledDllName) == 0) break; } import++; } if (import->Name == NULL) return; // Scan the IAT for this DLL PIMAGE_THUNK_DATA thunk = (PIMAGE_THUNK_DATA)((PBYTE)callingDll + import->FirstThunk); while (thunk->u1.Function) { PROC* function = (PROC*)&(thunk->u1.Function); if (*function == realFunction) { // Make the function pointer writable and hook the function MEMORY_BASIC_INFORMATION mbi; ::VirtualQuery(function,&mbi,sizeof mbi); if (::VirtualProtect(mbi.BaseAddress,mbi.RegionSize,PAGE_READWRITE,&mbi.Protect)) { *function = newFunction; DWORD protect; ::VirtualProtect(mbi.BaseAddress,mbi.Protect,&protect); return; } } thunk++; } 最后,我修补了DLL在我的代码中调用的函数,而不是RegOpenKeyExW(): LONG WINAPI HookRegOpenKeyExW(HKEY hKey,LPCWSTR lpSubKey,DWORD ulOptions,REGSAM samDesired,PHKEY phkResult) { static const wchar_t* ieKey = L"SoftwareMicrosoftInternet Explorer"; // Never redirect any of the FeatureControl settings if (wcsstr(lpSubKey,L"FeatureControl") != NULL) return ::RegOpenKeyExW(hKey,lpSubKey,ulOptions,samDesired,phkResult); if (wcsnicmp(lpSubKey,ieKey,wcslen(ieKey)) == 0) { // Redirect the IE settings to our registry key CStringW newSubKey(m_registryPath); newSubKey.Append(lpSubKey+wcslen(ieKey)); return ::RegOpenKeyExW(hKey,newSubKey,phkResult); } else return ::RegOpenKeyExW(hKey,phkResult); } 令人惊讶的是,这个可怕的黑客确实有效.但请微软,如果你正在听,请在IE10中正确解决这个问题. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- win10专业版最新激活码以及激活方法
- windows-phone-7 – Windows Phone应用程序栏的图标颜色
- windows-server-2008 – 如何将Windows Server 2008事件日志
- 第一周1 2
- 【全网首发】使用vs2017+qt5.12.4编译64位debug和release的
- Windows+R快捷键
- hp-proliant – HP DL320e Gen8,3TB驱动器,Windows Server
- 丰富且广泛使用的Windows GUI框架?
- wpf – 如何将System.Windows.Media.Color对象序列化到sRGB
- windows-server-2008 – 在Server 2008 SP2上读取慢速SSD
- 如何在Windows XP上将eclipse的内部浏览器从IE更
- windows-runtime – 如何显示UIElement但没有UI交
- windows – 确保在任何给定时间只有1个PowerShel
- 解决win10激活错误代码0xc004c003
- windows – cmd中的Computername变量
- .net – UISpy.exe和Inspect.exe有什么区别? (来
- windows-server-2008 – 查找可执行文件将数据包
- windows – 为什么2002 :: IPv6地址无效?
- Microsoft HTTPAPI / 2.0使用端口80 – 无法启动
- windows 下python 环境安装