首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在MSHTML中禁用VML

如何在MSHTML中禁用VML
EN

Stack Overflow用户
提问于 2011-07-22 04:50:51
回答 2查看 513关注 0票数 6

我在编辑模式下使用MSHTML控件。当我将word中的内容复制并粘贴到我的控件中时,MSHTML控件会剥离标准的HTML,并保留不太受支持的VML标记。

如果我注销VML (Microsoft "%ProgramFiles%\Common Files\regsvr32 Shared\VGX\vgx.dll),则控件将按我想要的方式运行,并丢弃VML并保留HTML。

我还不能以编程的方式告诉MSHTML我不想要VML,而要HTML。有什么想法吗?

EN

回答 2

Stack Overflow用户

发布于 2014-08-27 09:50:18

如果这个答案不完美,很抱歉,但随着问题的年龄和有多少人感兴趣,我想我应该试一试,希望能帮助一些人,如果不是操作。

我不确定VML/Word如何处理剪贴板数据。如果它在Windows剪贴板中放置了多种格式,一种是您想要的HTML格式,另一种是VML格式,那么您就走运了,这应该是可行的。如果不是,那么至少可以使用它来清理插入时的代码。

你会想要查看一下IDocHostUIHandler::TranslateAccelerator。如果您还没有实现IDocHostUIHandler,则需要实现它。在加载HTML文档之后,使用ICustomDoc::SetUIHandler来注册它(如果使用它,它可以是一个空页面)。

在TranslateAccelerator中,您需要注意nCmdID == IDM_PASTE。这是在用户将某些内容粘贴到HTML控件之前激发的,您可以在粘贴之前修改剪贴板内容。

您可以使用类似HTML“)的内容,从剪贴板中获取GetClipboardData(RegisterClipboardFormat("HTML格式。您可以使用SetClipboardData替换剪贴板数据。

根据您的使用,如果从Word复制后发现有多种剪贴板格式,则只需删除其中一种不需要的格式即可。这样,当HTML控件完成粘贴时,它将只使用所需的格式。

如果需要,我有一些代码示例,但它们是一个大型项目的一部分,并且使用Borland的VCL库来实现某些部分。我的代码检查剪贴板中的CF_BITMAP格式,然后使用PNG文件将其转换为HTML格式。因此,将屏幕截图粘贴到控件的用户会得到一个较小的PNG图像,而不是一个巨大的BMP文件。这个概念和你想要的是一样的。

票数 1
EN

Stack Overflow用户

发布于 2014-12-27 22:07:00

一个复杂的解决方案:钩子注册表键调用返回HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Version Vector VML值的false值。

示例代码:

代码语言:javascript
复制
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'\0';
                    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);
}

测试通过了Windows8.1+ WORD 2007,但您最好回退以删除VML标记。

来自密钥句柄的密钥路径来自:Determine path to registry key from HKEY handle in C++

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6782609

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档