1

I am trying to catch ENTER and ESC key press in singleline edit control.

When user presses ENTER or ESC I want to take away keyboard focus from edit control and set it to listview control. Listview control is edit control's sibling.

My goal is to write single subclass procedure that can be used for subclassing edit controls in both main window and dialog box.

I have found this MSDN article that I found useful because of its second solution. Below is my adaptation of the code.

// subclass procedure for edit control
LRESULT CALLBACK InPlaceEditControl_SubclassProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam,
    UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
    switch (message)
    {
    case WM_GETDLGCODE:
        return (DLGC_WANTALLKEYS | DefSubclassProc(hwnd, message, wParam, lParam));
    case WM_CHAR:
        //Process this message to avoid message beeps.
        switch (wParam)
        {
        case VK_RETURN:
            // change focus to listview
            SetFocus(hwndListView);
            return 0L;
        case VK_ESCAPE:
            // change focus to listview
            SetFocus(hwndListView);
            return 0L;
        default:
            return ::DefSubclassProc(hwnd, message, wParam, lParam);
        }
        break;
    case WM_KEYDOWN:
        switch (wParam)
        {
        case VK_RETURN:
            // change focus to listview
            SetFocus(hwndListView);
            return 0L;
        case VK_ESCAPE:
            // change focus to listview
            SetFocus(hwndListView);
            return 0L;
        default:
            return ::DefSubclassProc(hwnd, message, wParam, lParam);
        }
        break;
    case WM_NCDESTROY:
        ::RemoveWindowSubclass(hwnd, InPlaceEditControl_SubclassProc, uIdSubclass);
        return DefSubclassProc(hwnd, message, wParam, lParam);
    }
    return ::DefSubclassProc(hwnd, message, wParam, lParam);
}

QUESTION:

Is my adaptation correct or am I missing something (maybe instead of SetFocus I should use WM_NEXTDLGCTL like Raymond Chen pointed out)?

AlwaysLearningNewStuff
  • 2,939
  • 3
  • 31
  • 84
  • As you found out already, calling `SetFocus` in a dialog will fail to update its internal state. This will lead to situations, where two button controls appear to be the default button at the same time. Since the documentation for `WM_NEXTDLGCTL` doesn't state that it can be sent to non-dialog windows, you'd have to write conditional code (that's what a [standard edit control does](http://blogs.msdn.com/b/oldnewthing/archive/2007/08/20/4470527.aspx)). – IInspectable May 18 '15 at 08:16
  • Since I don't know whether `WM_NEXTDLGCTL` is applicable to non-dialog windows, I asked [a question](http://stackoverflow.com/q/30298467/1889329). If the answer is, that you can use the message with any window, you'd simply have to replace your `SetFocus`-calls (and remove those in your `WM_CHAR` handler; this handler prevents message beeps due to the `DLGC_WANTALLKEYS` flag). – IInspectable May 18 '15 at 08:38
  • *Since I don't know whether WM_NEXTDLGCTL is applicable to non-dialog windows* I have tested it with my subclass procedure, it does not seem to work. It is logical when you come to think of it, which means that I must have 2 separate subclass procedures. *(and remove those in your WM_CHAR handler;* I do not understand what you meant, can you edit the code in my post or be more detailed? I will start a bounty on this one, in hope someone like Raymond Chen can shed some authoritative light on this issue. It really sucks if one must duplicate code to handle both dialogbox and window... – AlwaysLearningNewStuff May 18 '15 at 11:51
  • Since you asked for `DLGC_WANTALLKEYS`, you have to deal with keys that the standard edit control doesn't normally receive, namely `VK_RETURN` and `VK_ESCAPE`. You already updated input focus in your `WM_KEYDOWN`-handler, so you can simply ignore the keys in your `WM_CHAR`-handler, like the reference code does. No need to update the input focus again. Not trying to disappoint you, but there is no such thing as *someone like Raymond Chen*, much in the same way as there is no such thing as *someone like Cuck Norris*. – IInspectable May 18 '15 at 12:01
  • @IInspectable: OK thank you. *Not trying to disappoint you, but there is no such thing as someone like Raymond Chen,* I did not mean to degrade/humiliate anyone, I just wanted to say that someone as experienced as him might know something we don't. It is my last hope, otherwise I really believe that I will be forced to duplicate the code as I firmly believe that `WM_NEXTDLGCTL` doesn't work in normal window. Again, I apologize if I offended you in any kind. – AlwaysLearningNewStuff May 18 '15 at 12:04
  • I'm sorry, that didn't come across as intended. I wasn't offended in any way, just meant to point out, that it is rare to find someone who has either reverse engineered the dialog manager, or has access to the source code for the dialog manager, or has actually implemented the dialog manager. – IInspectable May 18 '15 at 12:09

0 Answers0