Search code examples
c++winapiunicodesendmessagerichedit

How do I get Unicode to show up in C++ RICHEDIT_CLASS?


I have been trying and researching all day non-stop and have tried everything I found, but nothing seems to work for me.

I am pretty sure it is a problem somewhere in here:

void edit_append (const char *text)
{
    CHARRANGE range = {-1, -1};
    SendMessage(win_log, EM_EXSETSEL, 0, (LPARAM)&range);
    SendMessage(win_log, EM_REPLACESEL, FALSE, (LPARAM)text);
}

If you need any other of my code I would be happy to paste it here, I have been fighting with it all day. When I SendMessage() Unicode I just get weird symbols and one time I even got a bunch of question marks.


Solution

  • You are passing a char* to EM_REPLACESEL. That will only work if your RichEdit control is using an Ansi HWND via CreateWindow(Ex)A(RICHEDIT_CLASSA). If it is using a Unicode HWND via CreateWindow(Ex)W(RICHEDIT_CLASSW), you need to pass a wchar_t* instead:

    void edit_append (const wchar_t *text)
    {
        CHARRANGE range = {-1, -1};
        SendMessage(win_log, EM_EXSETSEL, 0, (LPARAM)&range);
        SendMessage(win_log, EM_REPLACESEL, FALSE, (LPARAM)text);
    }
    
    void edit_clear (void)
    {
        CHARRANGE range = {0, -1};
        SendMessage(win_log, EM_EXSETSEL, 0, (LPARAM)&range);
        SendMessage(win_log, EM_REPLACESEL, FALSE, (LPARAM)L"");
    }
    

    If you cannot change the data type for text for whatever reason, then you will have to use MultiByteToWideChar() (or equivilent) to convert the data to UTF-16 before giving it to SendMessage():

    void edit_append (const char *text)
    {
        int len = strlen(text);
        int wlen = MultiByteToWideChar(CP_ACP, 0, text, len, NULL, 0);
    
        wchar_t *wtext = new wchar_t[wlen+1];
        MultiByteToWideChar(CP_ACP, 0, text, len, wtext, wlen);
        wtext[wlen] = 0;
    
        CHARRANGE range = {-1, -1};
        SendMessage(win_log, EM_EXSETSEL, 0, (LPARAM)&range);
        SendMessage(win_log, EM_REPLACESEL, FALSE, (LPARAM)wtext);
    
        delete[] wtext;
    }