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

发布于 2024-12-01 19:49:27 字数 1448 浏览 0 评论 0原文

我不经常使用 winapi,我几乎正在编写 .NET 代码。但此时我必须使用winapi来制作一个简单的对话框。我想在那里处理一些关键事件。因此,我观看了相应的回调消息 WM_KEYDOWN< /code> 或 WM_KEYUP在 MSDN 上并将其添加到我的回调函数中。

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_KEYUPWM_KEYDOWN 都不会被触发。然后我说寻找这个问题的解决方案。我想我的对话框可能会吃掉这些消息。所以我补充道:

    case WM_GETDLGCODE: 
        return DLGC_WANTALLKEYS;

结果是没有帮助。 我发现的其他解决方案如下:

  • 或者,按照 此处
  • 我发现了很多线程(例如这个)谈论一个名为 PreTranslateMessage 的方法。但我什至没有这个类,因为我只是使用 DialogBoxParam

所以它们都不适合我。此刻我不知道如何处理。我注意到,按下按键时似乎会出现 WM_COMMAND 消息。

问候内姆。

i don't often work with winapi, i'm writing almost .NET code. But at this time I have to use the winapi to make a simple dialog. There i want to handle some keyevents. Therefore i watched for the corresponding callback message WM_KEYDOWN or WM_KEYUP at MSDN and added it to my callback function.

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;
}

But neither WM_KEYUP nor WM_KEYDOWN ever get triggered. Then I stated looking for a solution for this problem. I thought may my dialog eats this messages. So I added:

    case WM_GETDLGCODE: 
        return DLGC_WANTALLKEYS;

With the result that it doesn't help.
Other solutions I've found were the following:

  • Alternatively using the WM_GETDLGCODE event to handle this keys as suggested on here.
  • I've found a lot of threads (like this one) talking about a method called PreTranslateMessage. But I don't even have got this class, because I simply create my dialog by using DialogBoxParam

So none of them worked for me. In the moment i have got no idea how to handle it. Something I've noticed, is that on key press a WM_COMMAND message seems to occur.

Regards Nem.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

赠意 2024-12-08 19:49:27

根据此链接,某些消息很难用对话框捕获,因为 Windows 在内部处理它们并且它们永远不会到达DialogProc。以下是我能想到的两个选项:

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

According to this link, certain messages are hard to trap with dialog boxes because Windows processes them internally and they never get to the DialogProc. Here are two of the options I can think of:

  1. Use GetAsyncKeyState on a WM_COMMAND event
  2. Create a custom dialog box, the DialogProc for which will handle WM_KEYDOWN etc. messages.
秋凉 2024-12-08 19:49:27

DialogProc 不接收 WM_KEY 事件(还有许多其他事件)。您可以:

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

DialogProc doesn't receive WM_KEY events (and many others too). You can:

  1. Subclass the dialog window (overwrite its WndProc) and process all
    messages there, sample
  2. Register hot key for the dialog window's HWND and then receive WM_HOTKEY in DlgProc (but registered key combinations will be system-wide)
  3. Create your own message loop, link
じее 2024-12-08 19:49:27

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

这对我有用。

Try handling the WM_KEYDOWN and WM_KEYUP messages in the message loop and not in the window procedure.

 //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

That worked for me.

绝影如岚 2024-12-08 19:49:27

替换此

案例 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;

Replace This

case WM_KEYUP:
MMsgBox("up"); // I never get here
return 0;

case WM_KEYDOWN:
    MMsgBox("down"); // I never get here        
    return 0;

With This

case WM_KEYUP:
MMsgBox("up"); // I never get here
break;

case WM_KEYDOWN:
    MMsgBox("down"); // I never get here        
    break;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文