【问题标题】:Mfc Font binding and Rich Edit Control RICHEDIT50W does not display Unicode ProperlyMfc 字体绑定和 Rich Edit 控件 RICHEDIT50W 无法正确显示 Unicode
【发布时间】:2016-09-12 18:30:50
【问题描述】:

最新更新:

嗯,我发现了某种原因。我将控件从50W 更改为RichEdit20W,它现在显示韩文(韩文)。除了初始化,我不需要更改任何其他代码,添加了 AfxInitRichEdit2(),并注释掉了 LoadLibrary(L"MsftEdit.dll")。 AfxInitRichEdit5() 不适用于 VS2010。一切都是平等的,Rich Edit 4.1 从 VS2005 开始就可以使用,它应该可以工作的。我现在无法升级到 VS2015,所以我被卡住了。不过,我将为任何可以使 Hangul 与 50W 和 VS2010 一起工作的人提供赏金。


我有一个似乎无法解决的难题。

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

我的问题:

我为 CEditCRichEditCtrl 使用相同的字体 Courier New

作为测试,我使用了一些韩文符号来查看两者的输出
控制。

CEdit 输出ᄀᄁᄂᄃᄄᄅᄆᄇᄈ

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

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

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

有人能解开这个谜吗?

提前致谢!

请注意,其他一些字符集也会发生这种情况,而不仅仅是韩文


更新

我查看了 VS2010 WordPad 示例,它使用 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("ᄃᄄᄅᄆᄇᄈᄉᄊᄋᄌᄍᄎ"));

更新 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( ... );
}

【问题讨论】:

  • 在 Wordpad.exe 中工作得很好,它也使用该控件。你必须向我们展示。
  • 好的,我有延迟,一会儿要显示源..
  • 我们可以看到您创建字体并将字体分配给任一控件的代码吗?
  • 好的,添加了一些代码。
  • 我希望这不是我必须 test 为该字符的 lcid 插入的每个字符并设置适合插入的 CHARFORMAT2 的情况在具有相同 lcid 的每个系列上。我希望这可以通过像文档暗示的字体绑定自动完成。

标签: visual-studio-2010 unicode fonts mfc richedit


【解决方案1】:

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

BOOL CMyApp::InitInstance()
{
    CWinApp::InitInstance();
    LoadLibrary(L"MsftEdit.dll");
    ...
}

BOOL CMyDialog::OnInitDialog()
{
    CDialog::OnInitDialog();

    static CRichEditCtrl redit;
    CWnd *wnd = &redit;
    wnd->Create(MSFTEDIT_CLASS, L"ᄃᄄᄅᄆᄇᄈᄉᄊᄋᄌᄍᄎ",
            WS_CHILD | WS_VISIBLE, CRect(0,0,300,300), this, 1001, 0);
    ...
    //redit is not to be mixed up with controls created in dialog editor.
}

编辑----------------

NONCLIENTMETRICS info = { sizeof(info) };
SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(info), &info, 0);
LOGFONT logfont = info.lfMessageFont;

//CClientDC has automatic cleanup, use it instead of GetDC
CClientDC dc(this);
logfont.lfHeight = -MulDiv(abs(logfont.lfHeight), dc.GetDeviceCaps(LOGPIXELSY), 76);

CFont font;
font.CreateFontIndirect(&logfont);
m_RichEdit.SetFont(&font);

m_RichEdit.SetWindowText(L"ᄃᄄᄅᄆᄇᄈᄉᄊᄋᄌᄍᄎ");

m_RichEdit.SetSel(1, 1);

CString test = L"(Test, ελληνικά)";

//Test to make sure we can see Unicode text
AfxMessageBox(test);
m_RichEdit.ReplaceSel(test);

//optional:
//get default CHARFORMAT
CHARFORMAT2 charFormat;
//m_RichEdit.GetSelectionCharFormat(charFormat);
m_RichEdit.GetDefaultCharFormat(charFormat);

【讨论】:

  • 我想我找到了一些东西。如果我从记事本或 CEdit 复制 (ctrl-c) 韩文文本并粘贴到 Rich ctrl 中,我会得到框。如果我从 MS Word(即另一个 Rich ctrl)复制并粘贴,我会得到韩文。 ??呜呜呜???您认为这与多字节或剪贴板 Unicode 文本类型有关吗?此外,我主要以编程方式填充SetWindowText or SetSel( -1,-1 );ReplaceSel( str );,其中 str 是 LPCTSTR(即宽字符)。此外,当我将粘贴的 box 文本从富控件复制到控件中的另一个位置时,它会出现 Hangul..
  • 我认为你的项目不是 Unicode。所以有时有效,有时无效。如果可能,您应该将项目更改为 Unicode。如果这不是一个选项,您可以在 ANSI 项目中强制使用 Unicode 控件(请参阅编辑)。请注意,在 ANSI 项目中,MFC 函数将始终默认为 ANSI。所以你必须使用 WinAPI 来访问 Unicode 函数。您不能使用CRichEdit::ReplaceSel 在 ANSI 项目中发送 Unicode 文本。相反,你必须使用SendMessageW(hedit, EM_REPLACESEL...) 它变得复杂......
  • 这是一个 Unicode 项目/D "_UNICODE",我认为 ReplaceSel 只是将 EM_REPLACESEL 发送到控件。无论如何,我会尝试一下,看看会发生什么。在写字板和记事本和 MSWord 之间剪切和粘贴 Unicode 也有类似的奇怪效果。
  • 不要介意EM_REPLACESEL,因为如果你有Unicode项目应该没问题。也许这是一个问题,或者源文本不是 Unicode。在将文本插入 RichEdit 之前,用消息框显示它以确保它是 Unicode 文本。请参阅第二次编辑。
  • 好吧,我找到了某种罪魁祸首。我将控件从50W 更改为RichEdit20W,它现在显示韩文(韩文)。除了初始化,我不需要更改任何其他代码,添加了 AfxInitRichEdit2(),并注释掉了 LoadLibrary(L"MsftEdit.dll")。 AfxInitRichEdit5() 不适用于 VS2010。一切都是平等的,Rich Edit 4.1 从 VS2005 开始就可以使用,它应该可以工作的。我现在无法升级到 VS2015,所以我被卡住了。不过,我将为任何可以使 Hangul 与 50W 和 VS2010 一起工作的人提供赏金。
猜你喜欢
  • 1970-01-01
  • 2013-06-05
  • 1970-01-01
  • 1970-01-01
  • 2013-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-14
相关资源
最近更新 更多