【发布时间】:2023-04-01 13:40:01
【问题描述】:
我正在尝试使用以下 wndproc 和 winmain 处理 WM_KEYDOWN 消息,但是当我按下一个键(即 ascii 值为 24、25、26、27 的箭头键)时,它没有处理。
WndProc
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){
/*TO CHECK uMsg message*/
char buff[256];
_itoa_s(uMsg, buff, 10);
SetWindowText(hEdit, buff);
/**********************/
switch (uMsg)
case WM_CREATE:
hEdit = CreateWindowEx(WS_EX_CLIENTEDGE, "Edit", "", WS_CHILD | WS_VISIBLE |ES_AUTOVSCROLL | ES_MULTILINE | ES_WANTRETURN | WS_VSCROLL, 735, 5, 150, 100, hWnd, NULL, hInst, NULL);
HButton1 = CreateWindowEx(NULL, "BUTTON", "START", WS_CHILD | WS_VISIBLE | SS_CENTER, 2, 2, 80, 20, hWnd, (HMENU)IDC_BUTTON1, hInst, NULL);
HButton2 = CreateWindowEx(NULL, "BUTTON", "B", WS_CHILD | WS_VISIBLE | SS_CENTER, 82, 2, 80, 20, hWnd, (HMENU)IDC_BUTTON2, hInst, NULL);
HButton3 = CreateWindowEx(NULL, "BUTTON", "STOP", WS_CHILD | WS_VISIBLE | SS_CENTER, 162, 2, 80, 20, hWnd, (HMENU)IDC_BUTTON3, hInst, NULL);
Hmainbmp = CreateWindowEx(NULL, "STATIC", "", WS_CHILD | WS_VISIBLE | SS_BITMAP | WS_THICKFRAME, 1, 23, 600, 500, hWnd, NULL, hInst, NULL);
break;
case WM_KEYDOWN:
PRESSED_KEY = wParam;
break;
case WM_COMMAND:
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return(DefWindowProc(hWnd, uMsg, wParam, lParam));
return(0L);
}
WinMain
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow){
MSG msg;
WNDCLASSEX wc;
HMENU MainMenu, FileMenu;
MainMenu = CreateMenu();
FileMenu = CreatePopupMenu();
AppendMenu(FileMenu, MF_STRING, IDC_OPEN, "Open");
AppendMenu(MainMenu, MF_POPUP, (UINT_PTR)FileMenu, "FILE");
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW);
wc.lpszMenuName = lpszAppName;
wc.lpszClassName = lpszAppName;
wc.cbSize = sizeof(WNDCLASSEX);
wc.hIconSm = (HICON)LoadImage(hInstance, lpszAppName, IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
if (!RegisterClassEx(&wc)) return(FALSE);
hInst = hInstance;
hWnd = CreateWindowEx(0, lpszAppName, lpszTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 900, 600, NULL, MainMenu, hInstance, NULL);
if (!hWnd) return(FALSE);
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}
为什么下面的情况不起作用?以及如何处理 WM_KEYDOWN?
case WM_KEYDOWN:
PRESSED_KEY = wParam;
break;
更新
当我再次最小化和最大化窗口时,WM_KEYDOWN 已处理,但如果我单击任何按钮,它就不起作用。
【问题讨论】:
-
可能是因为 WM_KEYDOWN 消息会发送到您创建的编辑控件。
-
如果你想拦截进入编辑控件的键盘消息,你必须使用一种叫做window subclassing的技术。
-
另请注意,箭头键是特殊处理的,因为默认情况下它们被操作系统保留用于导航目的,因此默认情况下它们不会生成
WM_KEY...消息。您必须通过处理WM_GETDLGCODE消息来明确要求返回DLGC_WANTARROWS标志。 -
@john 实际上,我想在按键时更改全局变量(PRESSED_KEY)的值。 hEdit 只是为了看值。
-
键盘消息只进入具有焦点的窗口。用户可以通过单击一个窗口来更改哪些窗口具有焦点。因此,如果您真的想跟踪所有键盘使用情况,那么 Windows 消息并不是最好的方法。也许你应该看看SetWindowsHookExA,虽然我没有这方面的经验。