1

I would like to hide a caret from a RichEdit(50W) with ES_READONLY style specified. It's pretty confusing for the user, when the caret is blinking and the user can't type.
I tried to hide the caret using HideCaret() function,
however it doesn't work for me with following code:

LRESULT CALLBACK ChatMessaegsSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) // Subclassed control
{
    LRESULT ret = CallWindowProc(WndProc_ChatMessages, hwnd, msg, wParam, lParam);
    switch(msg)
    {
    //Also tried with EN_SETFOCUS
    case WM_SETFOCUS:
    {
        ret = CallWindowProc(WndProc_ChatMessages, hwnd, msg, wParam, lParam);
        HideCaret(ChatMessages); //Returns 5 (Access denied.)
        break;
    }

    //According the documentation:
    //If your application calls HideCaret five times in a row, 
    //it must also call ShowCaret five times before the caret is displayed.
    case WM_KILLFOCUS: //The message is called when the RichEdit get focus, however nothing happens.
    {
        ret = CallWindowProc(WndProc_ChatMessages, hwnd, msg, wParam, lParam);
        ShowCaret(ChatMessages);
        break;
    }
    }
    return ret;
}
David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
ProXicT
  • 1,903
  • 3
  • 22
  • 46
  • 2
    Your solution is on the right track, but it won't help if the control gets focus via the keyboard (e.g. Tab key). Is hiding the caret really a good idea? I question how "confusing" it is - it's a standard behavior of the control, and lets the user know they can still copy text out of it even if they can't type into it. – Jonathan Potter Oct 01 '15 at 21:42
  • @JonathanPotter You're right with the keyboard focus. I want to display messages like in skype in this RichEdit. It seems confusing for users when they see a caret which actually tells them: "Hey, you can type here!" and they cannot because of the 'ES_READONLY' style. – ProXicT Oct 01 '15 at 22:12
  • An *Access denied* error is rather unlikely. It is generally set, when a securable kernel object cannot be used with the supplied access token. User objects aren't securable in the same way, and error code 5 is usually not set. Please show the code you are using to retrieve the error code. – IInspectable Oct 02 '15 at 07:58
  • `CallWindowProc` is called twice. You should remove the one before `switch` statement. Then add default processing after `switch` is finished. – Barmak Shemirani Oct 02 '15 at 15:58
  • @IInspectable [Here](http://pastebin.com/13yJBdrX) is the code I'm using to retrieve the error code. Sorry for the late response, I somehow missed that comment. – ProXicT Oct 03 '15 at 02:04

1 Answers1

0

Here is the solution:

LRESULT CALLBACK ChatMessaegsSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    LRESULT ret = CallWindowProc(WndProc_ChatMessages, hwnd, msg, wParam, lParam);
    switch(msg)
    {
    case WM_LBUTTONDOWN:
    {
        HideCaret(ChatMessages);
        break;
    }
    case WM_KILLFOCUS:
    {
        ShowCaret(ChatMessages);
        break;
    }
    }
    return ret;
}

NOTE this only works when user induces the focus with mouse. Therefore if anyone knows how to deal with it correctly, feel free to answer, I'll be glad.

ProXicT
  • 1,903
  • 3
  • 22
  • 46
  • This looks fine as is and Keyboard focus shouldn't activate the caret! Except `SetWindowSubclass` would be better. – Barmak Shemirani Oct 02 '15 at 06:29
  • @BarmakShemirani Keyboard focus does not hide the caret. It's obvious when I'm handling LMB-down case only. Why is `SetWindowSubclass` better than `SetWindowLong`? – ProXicT Oct 02 '15 at 12:40
  • `SetWindowSubclass` is recommended for common control 6 and higher https://msdn.microsoft.com/en-us/library/windows/desktop/bb773183%28v=vs.85%29.aspx --- You can turn `WS_TAB` off for edit control, or turn in on/off --- There must be another way to handle tab key in WinApi, but I don't know how. – Barmak Shemirani Oct 02 '15 at 16:10
  • Actually I don't think you need to handle `WM_KILLFOCUS` – Barmak Shemirani Oct 02 '15 at 16:11
  • Thanks for clearing out the `SetWindowSubclass`. Using tab key is not the only way to turn a control in focus. Proper way would be to handle `WM_SETFOCUS`, but `HideCaret` returns me 5 (Access is denied). Handeling `WM_KILLFOCUS` is needed according [the documentation](https://msdn.microsoft.com/en-us/library/windows/desktop/ms648403(v=vs.85).aspx) of `HideCaret` function. – ProXicT Oct 02 '15 at 19:15