EssGeEich has already identified the problem.
When the Edit control has focus, it is the window which is sent the key stroke messages.
If you need WM_KEYDOWN to arrive in your app's main WndProc, you will have to either:
(a) subclass the Edit control
(b) intercept the message in the message loop (only really accepable if you have so many controls that subclassing would be a right pain.)
Andy
Subclassing the Edit control involves:
1 - adding an include, if you don't already have it (you also need to link to comctl32.lib)
#include <commctrl.h>
2 - defining a custom (user) message (and control ID, if you don't already have one)
1 2
|
#define WM_USER_KEYDOWN (WM_USER + 1000)
#define ID_EDIT_ONE 200
|
3 - foward declaring the subclass proceedure
LRESULT CALLBACK EscapeWndProc(HWND, UINT, WPARAM, LPARAM, UINT_PTR, DWORD_PTR);
4 - subclassing in WM_CREATE, along these lines (where s_hwndEdit is declared as a static HWND in the main WndProc.)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
case WM_CREATE:
{
s_hwndEdit = CreateWindow( TEXT("EDIT"),
NULL,
WS_CHILD | WS_VISIBLE | ES_LEFT,
20, 50,
150, 30,
hWnd,
(HMENU)ID_EDIT_ONE,
g_hInst,
NULL );
SetWindowSubclass(s_hwndEdit, EscapeWndProc, ID_EDIT_ONE, 0);
}
break;
|
5 - unsubclassing in WM_DESTROY
1 2 3 4 5 6 7
|
case WM_DESTROY:
{
RemoveWindowSubclass(s_hwndEdit, EscapeWndProc, ID_EDIT_ONE);
PostQuitMessage(0);
}
break;
|
6- providing the implentation of the subclass proceedure
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
LRESULT CALLBACK EscapeWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
// Usually you use a switch statement and return appropriate value
// to indicate that you've handled a message. But here we're just
// letting our parent know what's going on.
if((uMsg == WM_KEYDOWN) && (wParam == VK_ESCAPE))
{
HWND hWndParent = GetParent(hWnd);
PostMessage(hWndParent, WM_USER_KEYDOWN, wParam, lParam);
}
return DefSubclassProc(hWnd, uMsg, wParam, lParam);
}
|
7 - and handling the custom message as well as WM_KEYDOWN
1 2 3 4 5 6 7 8 9
|
case WM_KEYDOWN:
case WM_USER_KEYDOWN:
{
if (wParam == VK_ESCAPE)
{
DestroyWindow(hWnd);
}
}
break;
|
Notes:
- I am deliberately using a custom message so I can tell the difference between the normal and re-posted messages.
- The ID used to subclass a control does not need to be the same as the control ID, but it's easier to keep track of things if you keep them in step.
- I am using the "new style" subclassing mechanism (SetWindowSubclass, RemoveWindowSubclass, ...), introduced in Windows XP back in 2001, rather than the older (ancient) approach using SetWindowLongPtr with GWLP_WNDPROC (or the even older SetWindowLong with GWL_WNDPROC) which is still referred to all over the place.