我不经常使用 winapi,我几乎正在编写 .NET 代码。但此时我必须使用winapi来制作一个简单的对话框。我想在那里处理一些关键事件。因此我在MSDN上查看了相应的回调消息
WM_KEYDOWN
或WM_KEYUP
并将其添加到我的回调函数中。
INT_PTR CALLBACK cbfunc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
switch(message) {
// ...
case WM_KEYUP:
MMsgBox("up"); // I never get here
return 0;
case WM_KEYDOWN:
MMsgBox("down"); // I never get here
return 0;
// ...
}
return 0;
}
但是
WM_KEYUP
和 WM_KEYDOWN
都不会被触发。然后我说寻找这个问题的解决方案。我想我的对话框可能会吃掉这些消息。所以我补充道:
case WM_GETDLGCODE:
return DLGC_WANTALLKEYS;
结果却无济于事。 我发现的其他解决方案如下:
WM_GETDLGCODE
事件来处理此键,如 here 上的建议。PreTranslateMessage
的方法。但我什至没有这个类,因为我只是使用 DialogBoxParam
所以他们都不适合我。此刻我不知道如何处理。我注意到,按下按键时似乎会出现
WM_COMMAND
消息。
问候内姆。
根据此链接,某些消息很难用对话框捕获,因为Windows在内部处理它们并且它们永远不会到达
DialogProc
。这是我能想到的两个选项:
GetAsyncKeyState
事件上使用
WM_COMMAND
DialogProc
,其中will处理WM_KEYDOWN
等消息。尝试在消息循环中而不是在窗口过程中处理 WM_KEYDOWN 和 WM_KEYUP 消息。
//Process window messages.
while(TTRUE){
//Wait for a message to enter the
//queue.
ret = GetMessage(&tmpmsg, \
NULL, \
0, \
0);
if(ret > 0){
//Check if the user pressed the Shift key.
if(tmpmsg.message == WM_KEYDOWN){
//Get the key state of the Shift key.
tmpn = GetKeyState(VK_SHIFT);
} //End WM_KEYDOWN
//Check if the user lifted the Shift key.
if(tmpmsg.message == WM_KEYUP){
//Get the key state of the Shift key.
tmpn = GetKeyState(VK_SHIFT);
} //End WM_KEYUP
} //EndIf
这对我有用。
替换这个
案例WM_KEYUP: MMsgBox("向上"); // 我从来没有到过这里 返回0;
case WM_KEYDOWN:
MMsgBox("down"); // I never get here
return 0;
有了这个
案例WM_KEYUP: MMsgBox("向上"); // 我从来没有到过这里 打破;
case WM_KEYDOWN:
MMsgBox("down"); // I never get here
break;