# Problem with WM_KEYDOWN in modal dialog (winapi)

This topic is 4811 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi! I have a little problem. When I create a dialog I can't get WM_KEYDOWN message for VK_UP, VK_LEFT, VK_RIGHT, VK_DOWN, VK_TAB: DialogBox(hInst, "MyDialog", hwnd, DialogProc);
// MyDialog in *.rc file:

#include <windows.h>

MyDialog DIALOG 20, 20, 120, 95
STYLE WS_POPUP | WS_DLGFRAME | WS_VISIBLE
{
}


In DialogProc I am trying to know if arrow keys are pressed:
case WM_KEYDOWN:
MessageBeep(0);
break;


There is a problem, because MessageBeep doesn't take effect when Tab or arrow keys are pressed. So I think that messages WM_KEYDOWN for these keys aren't sent to DialogProc. How can I handle them then? Please help me if you can. Thanks in advance.

##### Share on other sites
there are certain keys that DialogBox makes use of to allow the user to navigate amongst the controls on a dialog box. so its msg pump is processing those key msgs and not passing them on to your dialog msg proc.

what you can do is make the dialog box a modeless dialog box (see CreateDialog docs), and make sure not to call IsDialogMessage in your msg pump. then the key msgs should be passed on to your dialog msg proc.

- or -

you can sub-class the dialog box window's msg proc (see SetWindowLong docs) and then handle the key msgs there.

##### Share on other sites
Quote:
 Original post by only_meHi!I have a little problem. When I create a dialog I can't get WM_KEYDOWN message for VK_UP, VK_LEFT, VK_RIGHT, VK_DOWN, VK_TAB:DialogBox(hInst, "MyDialog", hwnd, DialogProc);*** Source Snippet Removed ***In DialogProc I am trying to know if arrow keys are pressed:*** Source Snippet Removed ***There is a problem, because MessageBeep doesn't take effect when Tab or arrow keys are pressed. So I think that messages WM_KEYDOWN for these keys aren't sent to DialogProc. How can I handle them then?Please help me if you can.Thanks in advance.

You can use WM_KEYDOWN hooks. Not the best solvement, but it must work.

##### Share on other sites
Quote:
 Original post by Anonymous Posterthere are certain keys that DialogBox makes use of to allow the user to navigate amongst the controls on a dialog box. so its msg pump is processing those key msgs and not passing them on to your dialog msg proc.what you can do is make the dialog box a modeless dialog box (see CreateDialog docs), and make sure not to call IsDialogMessage in your msg pump. then the key msgs should be passed on to your dialog msg proc.- or -you can sub-class the dialog box window's msg proc (see SetWindowLong docs) and then handle the key msgs there.

But I need this dialog to be modal because the main window of my application must be held up until it gets a reply from the dialog (the dialog is a typical window for making a choice).
Yes, I know that I can subclass the dialog box window's msg proc. But I don't know where I should place SetWindowLong(hDlg, GWL_WNDPROC, (LONG)MyProc); line (for example: it is very easy when we are creating buttons and other controls because we have their hwnd (hwnd=CreateWindowEx), problem is that command: hDlg=DialogBox(...) stops the program until dialog is closed). Should I use it when I get WM_INITDIALOG message?
I'd rather prefer the second solution of my problem (with sub-classing the dialog box window's msg proc).

Quote:
 Original post by cpp foreverYou can use WM_KEYDOWN hooks. Not the best solvement, but it must work.

I know nothing about WM_KEYDOWN hooks. This is really not the best solvement for me. :(
I've been facing with sub-classing buttons etc. once. But I have never used hooks.

EDIT:

I've tried to sub-class the dialog box window's msg proc. Here'e an example code:

static WNDPROC OldProc;//------------------------------------------------------------------------------LRESULT CALLBACK MyDialogProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){switch (message)    {        case WM_CREATE:            break;                case WM_KEYDOWN:            MessageBeep(0);            break;                    case WM_LBUTTONDOWN:            SendMessage(hwnd, WM_CLOSE, 0, 0);            break;                  case WM_CLOSE:            EndDialog(hwnd, 0);            break;        default:            return CallWindowProc(OldProc, hwnd, message, wParam, lParam);    }return CallWindowProc(OldProc, hwnd, message, wParam, lParam);}//------------------------------------------------------------------------------BOOL CALLBACK DialogProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){    switch(msg)    {    case WM_INITDIALOG:        OldProc=(WNDPROC)GetWindowLong(hwnd, GWL_WNDPROC);        SetWindowLong(hwnd, GWL_WNDPROC, (LONG)MyDialogProc);        return TRUE;              }    return FALSE;}

DialogBox(hInst, "MyDialog", hwnd, DialogProc);

But this all still does no effect. Unfortunately. [crying]

[Edited by - only_me on September 10, 2005 2:43:41 PM]

##### Share on other sites
huh, that used to work for me under 9x. maybe they got smart and moved the key processing code out of the proc and used an accelerator table or who knows.

but, never fear, RegisterHotKey is here to your rescue. works like a charm for tab, arrow keys, and escape, without a mod key or with one or more.

just make sure to call it before the dialog is created.

##### Share on other sites
Quote:
 Original post by Anonymous Posterhuh, that used to work for me under 9x. maybe they got smart and moved the key processing code out of the proc and used an accelerator table or who knows.but, never fear, RegisterHotKey is here to your rescue. works like a charm for tab, arrow keys, and escape, without a mod key or with one or more.just make sure to call it before the dialog is created.

Does it really work under 9x ? I am surprised. Under xp it doesn't.

##### Share on other sites
Quote:
 Original post by Anonymous Posterjust make sure to call it before the dialog is created.

But how can I do this? Until I call DialogBox function I don't have hwnd of the dialog. It works in the main window proc (for the main window proc) when I call RegisterHotKey() after WM_CREATE and UnregisterHotKey() after WM_DESTROY. But it doesn't work in the dialog proc. How could I register a hot key for the dialog in the main window proc when I haven't known the handle to the dialog yet?

EDIT

Thank you very much. It really works!!!!
But I had to place RegisterHotKey in DialogProc after WM_INITDIALOG (not in MyDialogProc after WM_CREATE).

[Edited by - only_me on September 11, 2005 2:42:47 PM]

1. 1
2. 2
Rutin
15
3. 3
4. 4
5. 5

• 9
• 9
• 14
• 12
• 10
• ### Forum Statistics

• Total Topics
633270
• Total Posts
3011155
• ### Who's Online (See full list)

There are no registered users currently online

×