我尝试使用CRichEditCtrl::GetLine()
检索MFC应用程序中以Unicode模式构建并运行在Windows 10上的丰富编辑控件的给定行的文本。
我编写了这个助手函数:
CString GetLine(CRichEditCtrl& richEdit, const int lineNum)
{
int lineLength = richEdit.LineLength(richEdit.LineIndex(lineNum));
if (lineLength == 0)
{
// Empty line
return CString();
}
const int kMinBufferLength = sizeof(int) / sizeof(wchar_t);
const int bufferLength = max(kMinBufferLength, lineLength);
CString line;
wchar_t* buffer = line.GetBuffer(bufferLength);
lineLength = richEdit.GetLine(lineNum, buffer, bufferLength);
line.ReleaseBuffer(lineLength);
return line;
}
此代码工作正常,但只包含一个字符的行除外。在这种情况下,CRichEditCtrl::GetLine()
返回2(而不是预期的1),输出缓冲区包含正确的字符,后面跟着一个\r
。
为什么会这样呢?为什么只为单字符行而不是包含更多字符的行添加\r
?
我能够修复添加这样一个特例if
:
// Code inserted after the richEdit.GetLine() call, before the line.ReleaseBuffer() call:
// *** Special Case ***
// It seems that when there's only one character (e.g. 'C') in the line,
// CRichEditCtrl::GetLine() returns 2, and appends a '\r' after
// the read character in the output buffer.
if ((lineLength == 2) && (buffer[1] == L'\r'))
{
// Chop off the spurious '\r'
lineLength = 1;
}
然而,我不清楚为什么会有这种特殊的行为。
P.S:调用的CRichEditCtrl::GetLine()
MFC代码是:
int CRichEditCtrl::GetLine(_In_ int nIndex, _Out_writes_to_(nMaxLength, return) LPTSTR lpszBuffer, _In_ int nMaxLength) const
{
ASSERT(::IsWindow(m_hWnd));
ENSURE(sizeof(nMaxLength)<=nMaxLength*sizeof(TCHAR)&&nMaxLength>0);
*(LPINT)lpszBuffer = nMaxLength;
return (int)::SendMessage(m_hWnd, EM_GETLINE, nIndex, (LPARAM)lpszBuffer);
}
因此,这似乎只是EM_GETLINE
消息的一个小包装器。
EM_GETLINE
声明“返回值是复制的TCHAR
__s的数量”(在我的例子中,是wchar_t
s)。对于一个字符行,返回值为2,而不是预期的。因此,听起来富编辑控件实际上是返回单个字符,在这种特殊情况下,后面是一个伪\r
。
对于包含多个字符的行,返回的值是实际字符数,如预期的那样(我尝试使用简单的English/ASCII字符,以避免Unicode代理项对等复杂问题)。
发布于 2017-09-23 04:03:18
如果该行无效,则返回值为零(0)。
如果行为空,则在缓冲区中返回1和'\r‘是有意义的。这意味着在行号有效时总是返回'\r‘。
函数引用指出,缓冲区应该至少有4个字节长,因为在传递给SendMessage之前,会向缓冲区写入一个单词。
nMaxLength是int或WORD的大小。
CRichEditCtrl::GetLineCount有一些代码。
https://stackoverflow.com/questions/46371932
复制相似问题