如何在MSHTML中禁用VML
How to disable VML in MSHTML
我在编辑模式下使用MSHTML控件。当我从word复制和粘贴内容到我的控件时,MSHTML控件剥离标准HTML并保留不太受支持的VML标记。
如果我注销VML Dll (regsvr32 -u "%ProgramFiles%Common FilesMicrosoft SharedVGX VGX . Dll),那么控件的行为方式是我想要的,并丢弃VML并保留HTML。
我还没有能够编程的方式告诉MSHTML,我不想要VML,而是HTML。什么好主意吗?
抱歉,如果这个答案不完美,但随着问题的年龄和有多少人感兴趣,我想我应该试一试,希望能帮助那些没有op的人。
我不确定VML/Word如何处理剪贴板数据。如果它在Windows剪贴板中放置了多种格式,一种是你想要的HTML格式,另一种是VML格式,那么你很幸运,这应该可以工作。如果没有,那么也许您可以使用它至少清理insert上的代码。
你会想看看IDocHostUIHandler::TranslateAccelerator。你需要实现IDocHostUIHandler,如果你还没有。你使用ICustomDoc::SetUIHandler来注册它,在HTML文档加载之后(如果你使用它,可以是一个空页面)。
在TranslateAccelerator中,您需要注意nCmdID == IDM_PASTE
。这是在用户将内容粘贴到HTML控件之前触发的,您可以在粘贴发生之前修改剪贴板内容。
你可以使用类似GetClipboardData(RegisterClipboardFormat("HTML格式"))的东西,从剪贴板获取HTML格式。你可以使用SetClipboardData来替换剪贴板数据。
对于您的使用,如果您看到从Word复制后有多种剪贴板格式,您可以简单地删除其中一种格式,即您不想要的格式。这样,当HTML控件完成粘贴时,它将只使用您想要的格式。
如果需要的话,我有代码示例,但它们是大型项目的一部分,并且在某些部分使用Borland的VCL库。我的代码检查剪贴板中的CF_BITMAP格式,并使用PNG文件转换为HTML格式。因此,将屏幕截图粘贴到控件的用户将得到一个较小的PNG图像,而不是一个巨大的BMP文件。这个概念和你想要的是一样的一个复杂的解决方案:钩子寄存器键调用HKEY_LOCAL_MACHINESOFTWAREMicrosoftInternet ExplorerVersion Vector
返回false值VML
值
示例代码:
typedef DWORD(__stdcall *NtQueryKeyType)(
HANDLE KeyHandle,
int KeyInformationClass,
PVOID KeyInformation,
ULONG Length,
PULONG ResultLength);
NtQueryKeyType sNtQueryKeyPtr = NULL;
std::wstring GetKeyPathFromKKEY(HKEY key)
{
std::wstring keyPath;
if (sNtQueryKeyPtr != NULL) {
DWORD size = 0;
DWORD result = 0;
result = sNtQueryKeyPtr(key, 3, 0, 0, &size);
if (result == STATUS_BUFFER_TOO_SMALL) {
size = size + 2;
wchar_t* buffer = new (std::nothrow) wchar_t[size / sizeof(wchar_t)]; // size is in bytes
if (buffer != NULL)
{
result = sNtQueryKeyPtr(key, 3, buffer, size, &size);
if (result == STATUS_SUCCESS)
{
buffer[size / sizeof(wchar_t)] = L' ';
keyPath = std::wstring(buffer + 2);
}
delete[] buffer;
}
}
}
return keyPath;
}
DWORD __stdcall VWMLNtQueryKey(
HANDLE KeyHandle,
int KeyInformationClass,
PVOID KeyInformation,
ULONG Length,
PULONG ResultLength) {
auto str = GetKeyPathFromKKEY((HKEY)KeyHandle);
if (!str.empty() && base::StringProcess::endsWith(str, L"Internet Explorer\Version Vector"))
return STATUS_INVALID_PARAMETER;
return sNtQueryKeyPtr(KeyHandle, KeyInformationClass, KeyInformation, Length, ResultLength);
}
base::WindowsDllInterceptor ntHook;
ntHook.Init("ntdll.dll");
if (!ntHook.AddHook("NtQueryKey", reinterpret_cast<intptr_t>(&VWMLNtQueryKey),
(void**)&sNtQueryKeyPtr)) {
removeVMLTags(&html);
}
测试通过Windows 8.1 + WORD 2007,但你最好后退到删除VML标签。
键句柄的键路径from:从c++中的HKEY句柄确定注册表键的路径