1

MFC 文件:winctrl4.cpp

(C:\Program Files\Microsoft Visual Studio 8\VC\atlmfc\src\mfc)

CString CRichEditCtrl::GetSelText() const
{
    ASSERT(::IsWindow(m_hWnd));
    CHARRANGE cr;
    cr.cpMin = cr.cpMax = 0;
    ::SendMessage(m_hWnd, EM_EXGETSEL, 0, (LPARAM)&cr);
    CStringA strText;
    LPSTR lpsz=strText.GetBufferSetLength((cr.cpMax - cr.cpMin + 1)*2); 
    lpsz[0] = NULL;
    ::SendMessage(m_hWnd, EM_GETSELTEXT, 0, (LPARAM)lpsz);
    strText.ReleaseBuffer();
    return CString(strText);
}

我有一个奇怪的问题,当我调用它时,它只返回所选字符串的第一个字符。cr已正确设置,但在::SendMessage(m_hWnd, EM_GETSELTEXT,...整个字符串不存在之后。

由于预期的问题(一个字节中包含零的两个字节字符) ,我在我的自定义代码中看到了类似的行为。但这是 MFC/Win32 的一部分!我的 .rc 文件是否有可能设置错误?是否有与此相关的创建风格?或者,既然我们为相关控件创建了一个 CFont,那会不会搞砸呢?WCHARCHAR

4

2 回答 2

3

这不是正确的 MFC 源代码,您编辑了吗?使用 CStringA 和 LPSTR 是非常不合适的,实际代码使用 CString 和 LPTSTR 以便正确处理 Unicode。是的,正如发布的那样,代码只会返回一个字符。


看到版本有帮助。此反馈文章中描述了该错误。 如果你不能合理地升级到 VS2008 SP1,你可以从 CRichEditCtrl 派生你自己的类并替换函数。例如:

CString CRichEditCtrlFix::GetSelText() const
{
    ASSERT(::IsWindow(m_hWnd));
    CHARRANGE cr;
    cr.cpMin = cr.cpMax = 0;
    ::SendMessage(m_hWnd, EM_EXGETSEL, 0, (LPARAM)&cr);
    CString strText;
    LPTSTR lpsz=strText.GetBufferSetLength((cr.cpMax - cr.cpMin + 1) * 2);
    lpsz[0] = NULL;
    ::SendMessage(m_hWnd, EM_GETSELTEXT, 0, (LPARAM)lpsz);
    strText.ReleaseBuffer();
    return CString(strText);
}
于 2010-02-28T14:07:43.403 回答
0

要获得宽字符字符串,您必须使用 EM_GETTEXTEX 消息。CRichEditCtrl 源不包含使用此类消息的方法。这是 GetSelText() 的正确实现,它实际上确实返回 Unicode 字符:

CString CRichEditCtrlFix::GetSelText() const
{
    ASSERT(::IsWindow(m_hWnd));
    CHARRANGE cr;
    cr.cpMin = cr.cpMax = 0;
    ::SendMessage(m_hWnd, EM_EXGETSEL, 0, (LPARAM)&cr);
    CString strText;
    int sz = (cr.cpMax - cr.cpMin + 1) * sizeof(tchar);
    LPTSTR lpsz = strText.GetBufferSetLength(sz);
    lpsz[0] = NULL;
    GETTEXTEX gte;
    memset( &gte, 0, sizeof(GETTEXTEX) );
    gte.cb = sz;
    gte.flags = GT_SELECTION;
    if( sizeof(tchar) == 2 ) gte.codepage = 1200;
    ::SendMessage(m_hWnd, EM_GETTEXTEX, (WPARAM)&gte, (LPARAM)lpsz);
    strText.ReleaseBuffer();
    return CString(strText);
}

这里的 1200表示UTF-16LE

于 2019-11-23T00:18:26.373 回答