代码之家  ›  专栏  ›  技术社区  ›  Mr.C64

在单字符行上调用时,CRichEditCtrl::GetLine()添加了伪“\r”?

  •  2
  • Mr.C64  · 技术社区  · 7 年前

    我试过使用 CRichEditCtrl::GetLine() 在以Unicode模式使用VS2015构建并在Windows 10上运行的MFC应用程序中检索rich edit控件的给定行的文本。

    我编写了这个助手函数:

    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;
    }
    

    除了 仅适用于包含 CRICHEDITCRL::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;
    }
    


    附笔: 这个 CRICHEDITCRL::GetLine()

    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

    这个 MSDN doc for EM_GETLINE “返回值是 TCHAR (就我而言 wchar_t -返回值为的字符行 ,而不是预期的。因此,听起来富编辑控件实际上是返回单个字符,后跟一个伪字符 \r

    对于包含多个字符的行,返回值是预期的实际字符数(我尝试使用简单的英文/ASCII字符,以避免Unicode代理对和其他东西的复杂性)。

    2 回复  |  直到 7 年前
        1
  •  2
  •   zett42    7 年前

    CRichEditCtrl::GetLine() :

    *(int*) buffer = lineLength;
    lineLength = richEdit.GetLine(lineNum, buffer);
    

    的参考 EM_GETLINE 说你必须写下 缓冲区的大小 进入缓冲区,而这实际上是 .

    Edit_GetLine() 哪个发送 EM_GETLINE公司

    cchMax要复制到缓冲区的最大字符数。

    cchMax 调用前将参数添加到缓冲区 SendMessage() 这与我上面的代码完全相同。

    CRICHEDITCRL::GetLine() 如果请求少于2个字符,则会导致异常,这是不正确的。

        2
  •  -2
  •   Baxter    7 年前

    (0)如果行无效。

    函数参考指出,缓冲区的长度应至少为4字节,因为一个字在传递到之前会写入缓冲区 发送消息 .

    CRichEditCtrl::GetLine

    CRICHEDITCRL::GetLineCount有一些代码。