CRichEditCtrl :: GetSelText()无法正常工作

时间:2010-02-25 11:47:51

标签: mfc winapi cricheditctrl

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,...之后整个字符串都不存在。

我在我的自定义代码中看到了类似的行为,因为WCHAR问题(一个字节中包含零字节的双字节字符)在预期CHAR时。但这是MFC / Win32的一部分!是不是我的.rc文件设置错了?有没有与此相关的创作风格?或者,因为我们为相关控件创建了一个CFont,可以 搞砸了吗?

2 个答案:

答案 0 :(得分:2)

这不是正确的MFC源代码,你编辑过吗?使用CStringA和LPSTR是不合适的,真正的代码使用CString和LPTSTR以便正确处理Unicode。是的,发布时代码只会返回一个字符。


看到版本有帮助。此错误在此feedback article.中描述如果您无法合理地升级到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);
}

答案 1 :(得分: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此处means UTF-16LE