RichEdit - WM_GETTEXTLENGTH and EM_SETSEL consider different new lines characters

199 Views Asked by At

RichEdit has a strange behavior. The WM_GETTEXTLENGTH message considers the new line characters as two characters \r\n, while the EM_SETSEL and EM_EXSETSEL messages consider them as one character \n.

This creates confusion and lot of bad things, for example the below function does not work well:

void CutLastFiveChars(HWND hRichEdit) {

    // Get the current text length
    int textLength = (int)SendMessage(hRichEdit, WM_GETTEXTLENGTH, 0, 0);

    // Calculate the starting position for the selection
    int startPos = textLength - 5;
    if (startPos < 0) {
        startPos = 0;  // Ensure startPos is within bounds
    }

    // Set the selection to the last 5 characters
    SendMessage(hRichEdit, EM_SETSEL, startPos, textLength);

    // Replace the selected text with an empty string
    SendMessage(hRichEdit, EM_REPLACESEL, TRUE, (LPARAM)"");
}

How can I fix this?

Or, is there a way to disable automatically converting \n characters into \r\n?

2

There are 2 best solutions below

1
273K On

Have you made any attempt to read the manual carefully?

WM_GETTEXTLENGTH is used for getting a buffer allocation size.

To obtain the exact length of the text, use the WM_GETTEXT, LB_GETTEXT, or CB_GETLBTEXT messages, or the GetWindowText function.

0
YangXiaoPo-MSFT On

As @HansPassant pointed, EM_GETTEXTLENGTHEX gets the actual length with considering the new line characters as one character \r which is the same way as the EM_SETSEL and EM_EXSETSEL messages. While WM_GETTEXTLENGTH considers the new line characters as two characters \r \n.

You just need to use the EM_SETSEL and EM_EXSETSEL messages with EM_GETTEXTLENGTHEX. Then if you want to select a number of characters strictly, you need some extra effort. For example, revise the first selection based on EM_GETTEXTEX. enter image description here