在网上经常有人提出CDialog中响应键盘消息的OnKeyDown函数没反应。结论是CDialog不响应OnKeyDown,相应的解决方法是:
一个简单的办法就是重载CWnd::PreTranslateMessage
BOOL CTestDlg::PreTranslateMessage(MSG* pMsg)
{
// TODO: Add your specialized code here and/or call the base class
if(pMsg->message == WM_KEYDOWN)
{
switch (pMsg->wParam)
{
case VK_LEFT:
break;
case VK_RIGHT:
break;
case VK_UP:
break;
case VK_DOWN:
break;
}
}
return CDialog::PreTranslateMessage(pMsg);
}
经过仔细研究发现CDialog是相应对应消息的OnKeyDown函数的,只是这个消息在到达窗体之前,已经被它的子控件捕获了,如果将窗体中的所有控件都删除,窗体就会捕获到这个消息,但要注意的是,MFC为了实现在窗体上切换子控件的焦点,已经将 VK_TAB,VK_LEFT,VK_RIGHT,VK_UP,VK_DOWN进行了处理,同时VK_RETURN也被系统捕获用来处理相应的确定事件,所以即使窗体中没控件,这几个键还是无法捕获,暂时只能用PreTranslateMessage解决。
一个窗体仅在它没有可视和有效的控件时。响应OnKeyDown。
以下的代码实现了在对话框中显示虚拟键值(virtual-key code)
BOOL CTestDlg::PreTranslateMessage(MSG* pMsg)
{
if(pMsg->message == WM_KEYDOWN)
{
///或者直接调用OnKeyDown
CString strwParam;
strwParam.Format("%d ",pMsg->wParam);
CDC* pDC = GetDC();
pDC->TextOut(10,10,strwParam);
ReleaseDC(pDC);
}
return CDialog::PreTranslateMessage(pMsg);
}
阅读(1226) | 评论(0) | 转发(1) |