How to disable VML in MSHTML

I am using the MSHTML control in edit mode. When I copy and paste material from a word into my control, MSHTML controls share standard HTML and retain VML markup, which is not well supported there.

If I unregister the VML Dll (regsvr32 -u "% ProgramFiles% \ Common Files \ Microsoft Shared \ VGX \ vgx.dll), then the control behaves the way I want and discards the VML and stores the HTML.

I could not programmatically tell MSHTML that I do not want VML, but HTML. Any ideas?

+6
source share
2 answers

Sorry if this answer is not perfect, but with the age of the question and how many people are interested in it, I thought I would take a picture and hope to help someone, if not OP.

I'm not sure how VML / Word handles clipboard data. If it puts several formats on the Windows clipboard, one with the right HTML and one with the VML format, then you're in luck and that should work. If not, then perhaps you can use this to at least clear the code in the insert.

You want to see IDocHostUIHandler :: TranslateAccelerator . You need to implement IDocHostUIHandler if you have not already done so. You use ICustomDoc :: SetUIHandler to register after loading the HTML document (it may be a blank page if you use this).

Inside TranslateAccelerator you need to look at nCmdID == IDM_PASTE . This starts before the user pastes something into the HTML control, and you can change the contents of the clipboard before the paste occurs.

You can use something like GetClipboardData (RegisterClipboardFormat ("HTML Format")) to get the HTML format from the clipboard. You can use SetClipboardData to replace clipboard data.

For your use, if you see that after copying from Word there are several clipboard formats, you can simply delete one of the formats that you do not need. That way, when the HTML control finishes pasting, it will only use the format you want.

I have code examples if necessary, but they are part of a large project and use the Borland VCL library for some parts. My code checks the CF_BITMAP format on the clipboard and converts it to HTML instead of a PNG file. So that users who embed the screen capture in the control get a smaller PNG image instead of a huge BMP file. The concept is about the same as you want.

+1
source

Complex solution: Hook reigster key call returns a false value for the value HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Version Vector VML .

Code example:

 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); } 

Take the Windows 8.1 + WORD 2007 test, but it’s better to cancel the removal of VML tags.

The key path from the key descriptor from: Define the path to the registry key from the HKEY descriptor in C ++

0
source

Source: https://habr.com/ru/post/893313/


All Articles