如何在winapi标准对话框中处理键盘事件?

问题描述 投票:0回答:4

我不经常使用 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
消息。

问候内姆。

c++ winforms winapi keyboard callback
4个回答
6
投票

根据此链接,某些消息很难用对话框捕获,因为Windows在内部处理它们并且它们永远不会到达

DialogProc
。这是我能想到的两个选项:

  1. GetAsyncKeyState
     事件上使用 
    WM_COMMAND
  2. 创建自定义对话框,
    DialogProc
    ,其中will处理
    WM_KEYDOWN
    等消息。

2
投票

DialogProc 不接收 WM_KEY 事件(以及许多其他事件)。你可以:

  1. 对对话框窗口进行子类化(覆盖其 WndProc)并处理所有 那里有消息,样本
  2. 为对话框窗口的HWND注册热键,然后在DlgProc中接收WM_HOTKEY(但注册的组合键将是系统范围的)
  3. 创建您自己的消息循环,link

0
投票

尝试在消息循环中而不是在窗口过程中处理 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

这对我有用。


-1
投票

替换这个

案例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;
© www.soinside.com 2019 - 2024. All rights reserved.