Custom navigation in dialog boxes, redux


SuperBK asks, "What's the proper way to add keyboard support to a dialog box?"

There are many options available to you. The most traditional way is to pick them off in the dialog loop, either hard-coding the keys in code or putting them into resources by moving them to an accelerator resource. Moving them to an accelerator resource is a good idea if the keys are subject to translation (for example, if they are mnemonic). On the other hand, picking them off in code is your only choice if the action you want to take cannot be mapped to a WM_COMMAND message (or if you simply don't feel like creating such a mapping).

SuperBK appears to be using MFC, a framework I have only cursory familiarity with, so I'll accept that the MFC way of customizing the dialog loop is to use PreTranslateMessage.

One issue that was raised was the case where a keyboard accelerator is active only when a certain window has keyboard focus. But if that's your design, then you don't need to mess with the dialog loop at all. For example, the space bar pushes a button, but only if focus is on the button. There is no special code in the dialog loop to accomplish this; it's just part of the button control's WM_KEYDOWN message handler.

This is one of those cases where you discovered a hammer and start seeing everything as a nail. When the user presses a key, the keyboard message is posted to the window that has keyboard focus. You don't have to do any special work to pick it off, because it'll get to that window anyway if you just leave it alone.

In SuperBK's specific example, the list box should behave a certain way if it has focus and the user hits VK_RETURN. Okay, well, VK_RETURN is a special keyboard navigation key for dialog boxes, so you need to tell the dialog manager, "No, I want this key to go to me." Just have the control return DLGC_WANTMESSAGE in response to WM_GETDLGCODE if the message is a press of the VK_RETURN key. The dialog manager will let the message go through to the window, and then the window can perform its custom VK_RETURN action.

Comments (2)
  1. Goran says:

    As one of those people who only have a hammer :-( … It looks like MFC just told us off with this?

    WM_GETDLGCODE has meaningfull wParam and lParam, but CWnd::OnGetDlgCode has none of that.

    Anyone used OnGetDlgCode? Help?

    [Perhaps CWnd::GetCurrentMessage will help? (I don’t know; I don’t use MFC. I just browsed the methods and that one looked promising.) -Raymond]
  2. ChrisR says:

    @Goran:  I’ve wondered how to do this for so long and never even thought about GetCurrentMessage, but I just updated some code to use this and it does indeed work.

    @Raymond:  Thank you.

Comments are closed.