CRICHEDITCRL::GetSelText()工作不正常 MFC文件:winctrl4.cpp (C:\Program Files\Microsoft Visual Studio 8\VC\atlmfc\src\mfc)

CRICHEDITCRL::GetSelText()工作不正常 MFC文件:winctrl4.cpp (C:\Program Files\Microsoft Visual Studio 8\VC\atlmfc\src\mfc),mfc,winapi,cricheditctrl,Mfc,Winapi,Cricheditctrl,我遇到了一个奇怪的问题,当我调用它时,它只返回所选字符串的第一个字符cr设置正确,但在之后::SendMessage(m_hWnd,EM_GETSELTEXT,…整个字符串不存在 由于WCHAR问题(一个字节中包含零的两字节字符),我在自定义代码中看到了类似的行为当需要CHAR时。但这是MFC/Win32的一部分!是否可能我的.rc文件设置了错误?是否存在与此相关的创建样式?或者因为我们为所讨论的控件创建了一个CFont,这会不会把它搞砸?这不是正确的MFC源代码,您编辑过吗?使用CString

我遇到了一个奇怪的问题,当我调用它时,它只返回所选字符串的第一个字符<代码>cr设置正确,但在
之后::SendMessage(m_hWnd,EM_GETSELTEXT,…
整个字符串不存在


由于
WCHAR
问题(一个字节中包含零的两字节字符),我在自定义代码中看到了类似的行为当需要CHAR时。但这是MFC/Win32的一部分!是否可能我的.rc文件设置了错误?是否存在与此相关的创建样式?或者因为我们为所讨论的控件创建了一个CFont,这会不会把它搞砸?

这不是正确的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);
}

要获得宽字符字符串,必须使用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

这是我们SDK目录中的代码,它没有被编辑。然而,这个项目从90年代就开始了,完全有可能我们使用的是非常旧的MFC版本。你不知道你使用的是什么MFC版本,但你知道它在过去15年中没有被编辑过吗?因为它安装在我的PC上几个月前,我想是的。我更新了我的帖子,显示了文件的完整路径,并确认我可以调试到那个特定的版本。另外,我自己肯定从来没有构建过MFC,所以无论是什么DLL都是安装在我的电脑上的。你怎么知道每个版本的MFC的源代码是什么样的,以确定它是错的?哦,非常感谢。我是否也可以单独下载更新版本的MFC/platform SDK以在VS2005中使用?这是最好避免的。您将面临部署和清单方面的重大难题。
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);
}