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
Why doesn't OnKeyDown catch key events in a dialog-based MFC project?
提问by Moh
I just create a dialog-based project in MFC (VS2008) and add OnKeyDown
event 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_KEYDOWN
message is sent to the control with focus so your CgDlg::OnKeyDown
is never called. Override the dialog's PreTranslateMessage
function if you want dialog to handle the WM_KEYDOWN
message:
当对话框上有控件时,对话框本身永远不会获得焦点。它被孩子控件偷走了。当您按下按钮时,一条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()。