Mfc字体绑定和Rich Edit控件RICHEDIT50W无法正确显示Unicode

6 unicode fonts mfc richedit visual-studio-2010

最近更新:

好吧,我找到了某种罪魁祸首.我改变了控制,RichEdit20W50W它的朝鲜语(韩语)现在显示.我没有必要更改除init之外的任何其他代码,添加了AfxInitRichEdit2(),并注释掉了LoadLibrary(L"MsftEdit.dll").AfxInitRichEdit5()不适用于VS2010.所有事情都是平等的,Rich Edit 4.1自VS2005开始就已经可以使用了.我现在无法升级到VS2015所以我卡住了.我会为任何可以使韩文工作50W和VS2010的人提供赏金.


我有一个似乎无法解决的困境.

我有一个使用CEdit和CRicheditCtrl的mfc Unicode应用程序.
Rich Edit是50W,从MsftEdit.dllSpy ++ 加载并验证
类名为RICHEDIT50W.

我的问题:

Courier NewCEditCRichEditCtrl使用相同的Font .

作为测试,我使用了一些韩文符号来查看两个
控件的输出.

CEdit输出, ?????????

CRichEditCtrl box为每个字符输出a ,就像没有字形一样.

如果他们使用相同的字体,我不应该看到相同的输出字符?

我认为字体绑定不是问题,两者都有相同的默认字体.

任何人都可以解决这个谜语吗?

提前致谢!

请注意,这也适用于其他一些字符集,而不仅仅是韩文


更新

我查看了VS2010写字板示例,它使用CRichEditView,但它
提供了访问嵌入式CRichEditCtrl的包装器.

我以为我可以收集一些信息,但我看不出他们是如何进行
Rich Edit控制调用的.

这就是我为两个控件生成字体的方式.
但是,我正在专门展示Rich Edit部分.

文档说明Font绑定应该处理从默认
字体切换到当前插入点的字体.

我主要是在最后使用插入
ctrl.SetSel(-1,-1);
ctrl.ReplaceSel( str );

并且,根据文档,
如果不是默认字体,这应该根据需要更改为正确的字体.

在写字板示例中,如果我粘贴韩文文本,则字体会切换到
Gulim.

这是我的代码:

LOGFONT lf;
int pitch = 10;
memset(&lf, 0, sizeof(LOGFONT));

HDC hdc = ::GetDC(NULL);
lf.lfHeight = -MulDiv( pitch, GetDeviceCaps(hdc, LOGPIXELSY), 72);
lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
lstrcpy(lf.lfFaceName, _T("Courier New") );
lf.lfWeight = FW_NORMAL;
lf.lfCharSet = ANSI_CHARSET;  // English, but use DEFAULT_CHARSET if not
lf.lfQuality = DEFAULT_QUALITY;


if ( !m_Font.CreateFontIndirect(&lf) )
{   // Ours didn't work, create a system default fixed font
    // ( Ignore, example for post only. Never gets called though )
    //memset(&lf, 0, sizeof(LOGFONT));
    //::GetObject(GetStockObject(ANSI_FIXED_FONT), sizeof(LOGFONT), &lf);
    //m_Font.CreateFontIndirect(&lf);
}


// Save the generated Font LOGFONT 
m_lf = lf;

// Set the default Font CHARFORMAT2
memset( &m_cfDefaultFont, 0, sizeof(m_cfDefaultFont) );
m_cfDefaultFont.cbSize = sizeof(m_cfDefaultFont);
m_cfDefaultFont.dwMask = CFM_CHARSET | CFM_FACE | CFM_WEIGHT ;
m_cfDefaultFont.bCharSet = m_lf.lfCharSet;
lstrcpy( m_cfDefaultFont.szFaceName, m_lf.lfFaceName );
m_cfDefaultFont.wWeight = m_lf.lfWeight;

// Finally set the font in the controls
m_RichEdit.SetFont( &m_Font );

// Same effect as m_RichEdit.SetFont()
//m_RichEdit.SendMessage(EM_SETCHARFORMAT, SCF_ALL, &m_cfDefaultFont);

// This displays nothing but 'box' glyphs
m_RichEdit.SetWindowTextW(_T("????????????"));
Run Code Online (Sandbox Code Playgroud)

更新2

这是我在应用中初始化Rich Edit的方法.
并在对话框控件中显示50W的使用情况.

-- winapp.cpp
BOOL CMyApp::InitInstance()
{
    // ...... //

    CString strRichEdit = _T("Msftedit.dll");
    m_hMsfteditDll = AfxLoadLibrary( strRichEdit );
    if ( m_hMsfteditDll == NULL )
    {
        CString str;
        str.Format(_T("Error: Cannot find Rich Edit component %s"), strRichEdit );
        AfxMessageBox(str);
        return FALSE;
    }
    return TRUE;
}
int CRegexFormatApp::ExitInstance() 
{
    if ( m_hMsfteditDll != NULL )
        AfxFreeLibrary( m_hMsfteditDll );
    return CWinAppEx::ExitInstance();
}

// =========================

-- .rc 
CONTROL         "",IDC_RICH_EDIT,"RICHEDIT50W",WS_VSCROLL | WS_HSCROLL,40,15,148,28

-- Dlg.h
CRichEditCtrl m_RichEdit;

-- Dlg.cpp
void Dlg::DoDataExchange(CDataExchange* pDX)
{
    CDialogEx::DoDataExchange(pDX);
    DDX_Control(pDX, IDC_RICH_EDIT, m_RichEdit); // Use .rc setting to Create/Attach
}

BOOL Dlg::OnInitDialog()
{
    CDialogEx::OnInitDialog();
    CreateAndSetRichFont();  // Code shown above
    m_RichEdit.SetWindowTextW( ... );
}
Run Code Online (Sandbox Code Playgroud)

Bar*_*ani 3

此代码应该在 Unicode 项目中工作:

\n\n
BOOL CMyApp::InitInstance()\n{\n    CWinApp::InitInstance();\n    LoadLibrary(L"MsftEdit.dll");\n    ...\n}\n\nBOOL CMyDialog::OnInitDialog()\n{\n    CDialog::OnInitDialog();\n\n    static CRichEditCtrl redit;\n    CWnd *wnd = &redit;\n    wnd->Create(MSFTEDIT_CLASS, L"\xe1\x84\x83\xe1\x84\x84\xe1\x84\x85\xe1\x84\x86\xe1\x84\x87\xe1\x84\x88\xe1\x84\x89\xe1\x84\x8a\xe1\x84\x8b\xe1\x84\x8c\xe1\x84\x8d\xe1\x84\x8e",\n            WS_CHILD | WS_VISIBLE, CRect(0,0,300,300), this, 1001, 0);\n    ...\n    //redit is not to be mixed up with controls created in dialog editor.\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

编辑 - - - - - - - -

\n\n
NONCLIENTMETRICS info = { sizeof(info) };\nSystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(info), &info, 0);\nLOGFONT logfont = info.lfMessageFont;\n\n//CClientDC has automatic cleanup, use it instead of GetDC\nCClientDC dc(this);\nlogfont.lfHeight = -MulDiv(abs(logfont.lfHeight), dc.GetDeviceCaps(LOGPIXELSY), 76);\n\nCFont font;\nfont.CreateFontIndirect(&logfont);\nm_RichEdit.SetFont(&font);\n\nm_RichEdit.SetWindowText(L"\xe1\x84\x83\xe1\x84\x84\xe1\x84\x85\xe1\x84\x86\xe1\x84\x87\xe1\x84\x88\xe1\x84\x89\xe1\x84\x8a\xe1\x84\x8b\xe1\x84\x8c\xe1\x84\x8d\xe1\x84\x8e");\n\nm_RichEdit.SetSel(1, 1);\n\nCString test = L"(Test, \xce\xb5\xce\xbb\xce\xbb\xce\xb7\xce\xbd\xce\xb9\xce\xba\xce\xac)";\n\n//Test to make sure we can see Unicode text\nAfxMessageBox(test);\nm_RichEdit.ReplaceSel(test);\n\n//optional:\n//get default CHARFORMAT\nCHARFORMAT2 charFormat;\n//m_RichEdit.GetSelectionCharFormat(charFormat);\nm_RichEdit.GetDefaultCharFormat(charFormat);\n
Run Code Online (Sandbox Code Playgroud)\n