C++ 为什么 OnKeyDown 不捕获基于对话框的 MFC 项目中的关键事件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4699148/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 16:10:17  来源:igfitidea点击:

Why doesn't OnKeyDown catch key events in a dialog-based MFC project?

c++visual-c++mfckeydowndialogbasedapp

提问by Moh

I just create a dialog-based project in MFC (VS2008) and add OnKeyDownevent to the dialog. When I run the project and press the keys on the keyboard, nothing happens. But, if I remove all the controls from the dialog and rerun the project it works. What should I do to get key events even when I have controls on the dialog?

我只是在 MFC (VS2008) 中创建了一个基于对话框的项目并将OnKeyDown事件添加到对话框中。当我运行项目并按下键盘上的键时,没有任何反应。但是,如果我从对话框中删除所有控件并重新运行该项目,它就会起作用。即使我在对话框上有控件,我应该怎么做才能获取关键事件?

Here's a piece of code:

这是一段代码:

void CgDlg::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
    // TODO: Add your message handler code here and/or call default
    AfxMessageBox(L"Key down!");
    CDialog::OnKeyDown(nChar, nRepCnt, nFlags);
}

回答by Bojan Komazec

When a dialog has controls on it, the dialog itself never gets the focus. It's stolen by the child controls. When you press a button, a WM_KEYDOWNmessage is sent to the control with focus so your CgDlg::OnKeyDownis never called. Override the dialog's PreTranslateMessagefunction if you want dialog to handle the WM_KEYDOWNmessage:

当对话框上有控件时,对话框本身永远不会获得焦点。它被孩子控件偷走了。当您按下按钮时,一条WM_KEYDOWN消息会发送到具有焦点的控件,因此您CgDlg::OnKeyDown永远不会被调用。PreTranslateMessage如果您希望对话框处理WM_KEYDOWN消息,请覆盖对话框的功能:

BOOL CgDlg::PreTranslateMessage(MSG* pMsg)
{
   if(pMsg->message == WM_KEYDOWN   )  
   {
      if(pMsg->wParam == VK_DOWN)
      {
         ...
      }
      else if(pMsg->wParam == ...)
      {
         ...                      
      }
      ...
      else
      {
         ...                   
      }
   }

   return CDialog::PreTranslateMessage(pMsg);  
}

Also see this article on CodeProject: http://www.codeproject.com/KB/dialog/pretransdialog01.aspx

另请参阅 CodeProject 上的这篇文章:http: //www.codeproject.com/KB/dialog/pretransdialog01.aspx

回答by Gary Davies

Many of my CDialog apps use OnKeyDown(). As long you only want to receive key presses and draw on the screen (as in make a game), delete the default buttons and static text (the CDialog must be empty) and OnKeyDown() will start working. Once controls are placed on the CDialog, OnKeyDown() will no longer be called.

我的许多 CDialog 应用程序都使用 OnKeyDown()。只要您只想接收按键操作并在屏幕上绘图(如制作游戏),删除默认按钮和静态文本(CDialog 必须为空),OnKeyDown() 将开始工作。一旦将控件放置在 CDialog 上,将不再调用 OnKeyDown()。