Search code examples
c++mfccricheditctrlcrichedit

Replace character after key press in CRichEditCtrl MFC


I want to redirect Space key press action to display another char (whitespace char '·').

What handler or windows message can I use to do that?


Solution

  • One method is to intercept the key in PreTranslateMessage

    BOOL CMyDialog::PreTranslateMessage(MSG* msg)
    {
        if (msg->hwnd == m_RichEdit.m_hWnd)
        {
            if (msg->message == WM_CHAR)
            {
                if (msg->wParam == ' ')
                {
                    msg->wParam = '.';
                    return TRUE;
                }
            }
        }
    
       return CDialog::PreTranslateMessage(msg);
    }
    

    Edit: To insert unicode characters with Alt key:

    Declare member data:

    int m_key_value;
    

    Initialize m_key_value = 0;

    To check if Alt key is pressed down:

    BOOL IsKeyDown(int vkCode)
    {
        return GetAsyncKeyState(vkCode) & 0x8000;
    }
    

    We want to see if number keys are pressed while Alt key is down. We check WM_SYSKEYUP (don't check WM_SYSKEYDOW because it results in repeat characters)

    BOOL CMyDialog::PreTranslateMessage(MSG* msg)
    {
        if (msg->hwnd == m_RichEdit.m_hWnd)
        {
            if (msg->message == WM_SYSKEYUP && IsKeyDown(VK_MENU))
            {
                int i = msg->wParam;
                if (i >= '0' && i <= '9')
                    i -= '0';
                else if (i >= VK_NUMPAD0 && i <= VK_NUMPAD9)
                    i -= VK_NUMPAD0;
                if (i >= 0 && i <= 9)
                {
                    m_key_value *= 10;
                    m_key_value += i;
                    TRACE("m_key_value = %d\n", m_key_value);
                    return TRUE;
                }
            }
    
            if (msg->message == WM_KEYUP && msg->wParam == VK_MENU && m_key_value)
            {
                TRACE("WM_KEYUP RESULT %d\n", m_key_value);
                if (m_key_value == 160) m_key_value = '.';
                m_RichEdit.PostMessage(WM_CHAR, m_key_value, 0);
                m_key_value = 0;
                return TRUE;
            }
    
        }
        return CDialog::PreTranslateMessage(msg);
    }