我如何使用 CHtmlEditCtrl::SetDocumentHTML
正确显示 Unicode(UTF-16 或 UTF-8 输入)
程序以 Unicode 编译。
例如,给定以下带有 charset=utf-8
元标记的输入:
CString u16 = LR"(<!DOCTYPE><html>
<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/></head>
<body>ελληνικά 华语 😃</body></html>)";
m_htmledit.SetDocumentHTML(u16)
没有正确显示字符。
相反,我必须调用 m_htmledit.SetDocumentHTML(CA2W(CW2A(u16, CP_UTF8), CP_ACP));
我不明白为什么它会这样工作,或者它是否在所有系统上都工作。
最小示例:
#include "afxhtml.h"
...
CHtmlEditCtrl m_htmledit;
...
BOOL CMyDialog::OnInitDialog()
{
CDialogEx::OnInitDialog();
m_htmledit.Create(0, 0, CRect(10, 10, 300, 300), this, 0, 0);
//wait for the control, this is not directly related to the question
CComPtr<IHTMLDocument2> document;
if(m_htmledit.GetDHtmlDocument(&document))
{
CComBSTR ready;
while(document->get_readyState(&ready) == S_OK)
if(wcscmp(ready, L"complete") == 0 || !AfxPumpMessage())
break;
}
//send html data:
CString utf16 = LR"(<!DOCTYPE><html>
<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/></head>
<body>ελληνικά 华语 😃</body></html>)";
//m_htmledit.SetDocumentHTML(utf16); <- outputs garbage characters
m_htmledit.SetDocumentHTML(CA2W(CW2A(utf16, CP_UTF8), CP_ACP)); //<- correct output
return TRUE;
}
UTF-8 输入也有类似的问题。
m_htmledit_ctrl.SetDocumentHTML(CA2W(utf8, CP_UTF8));
没有正确显示字符。
m_htmledit_ctrl.SetDocumentHTML(CA2W(utf8, CP_ACP));
确实有效。但是在这里使用 CP_ACP
很奇怪。
例子:
CStringA utf8 = u8R"(<!DOCTYPE><html>
<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/></head>
<body>ελληνικά 华语 😃</body></html>)";
m_htmledit.SetDocumentHTML(CA2W(utf8, CP_ACP)); //<= correct output
最佳答案
CHtmlEditCtrl::SetDocumentHTML
使用名为 CStreamOnCString
的类。
CStreamOnCString
在某些时候调用
m_strAnsi = m_strStream;
其中m_strAnsi
是一个存储缓冲区,m_strStream
是CStringW
源。我认为这是一个错误,因为它不会将源代码复制到缓冲区。而是使用 CW2A(m_strStream, CP_ACP)
可以在发送数据之前通过另一个 CP_ACP
转换来纠正此错误。
或者我们可以如下编写自己的函数:
class CMyHtmlEditCtrl : public CHtmlEditCtrl
{
public:
template <class Type>
HRESULT SetDocumentHTML_unicode(CStringT<Type, StrTraitMFC<Type>> html)
{
HRESULT hr = E_NOINTERFACE;
CComPtr<IHTMLDocument2> document;
if(!GetDHtmlDocument(&document))
return hr;
IStream *istream = SHCreateMemStream(
reinterpret_cast<const BYTE*>(html.GetBuffer()), sizeof(Type)*html.GetLength());
if(istream)
{
CComQIPtr<IPersistStreamInit> psi = document;
if(psi)
hr = psi->Load(istream);
istream->Release();
}
html.ReleaseBuffer();
return hr;
}
};
现在我们可以调用 SetDocumentHTML_unicode(utf8_string)
或 SetDocumentHTML_unicode(utf16_string)
关于c++ - 在 CHtmlEditCtrl::SetDocumentHTML 中使用 Unicode,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59360395/