[Windows]MFC对话框会过滤掉键盘消息

来源:互联网 发布:linux 回复win7引导 编辑:程序博客网 时间:2024/04/30 09:41

建了个对话框工程,结果怎么都响应了不键盘的上下左右消息,又去查了WM_KEYDOWN和WM_SYSKEYDOWN的区别,以为是这里出问题。但WM_SYSKEYDOWN是只说按下了F10或者ALT,显然与我的问题无关。最后在论坛中见有人回答说:对话框对键盘消息已经过滤,但可以在PreTranslateMessage中处理。于是在对话框类中复写了这个方法。

然后去MSDN查这个方法的具体意思:

MSDN上说,这个是CWnd的方法,此方法由CWinApp调用,在消息传送给TranslateMessage和DispatchMessage窗口函数之前翻译他们。

http://support.microsoft.com/kb/126874此链接中有下面内容(拙劣翻译之):

当一个模态对话框已经调用(invoked)时,不会调用PreTranslatemessage函数。模态对话框有自己的消息循环,不与应用程序的主消息循环交互。这阻止了CWinApp::PumpMessage函数的调用,这个函数调用了PreTranslateMessage。

一个应用程序的开始是通过调用WinMain。MFC的WinMain实现是通过调用CWinApp::Run(),这里有应用程序的消息循环。Run中的消息循环调用PumpMessage去处理消息。PumpMessage通过windows API的GetMessage函数从应用程序的消息队列得到消息。然后PumpMessage调用CWinApp::PreTranslateMessage(),这个函数又调用适当CWnd的PreTranslateMessage()。MFC的消息路由技术细节,可以参考MFC TechNote#21和在APPCORE.cpp中的源码。在32位的MFC版本中,代码在CWinThread::PreTranslateMessage中,在THRDCORE.cpp。顺序如下:

-------------------------------------| CWinApp::PumpMessage | ------------------------------------- | | ------------------------------------- | CWinApp::PreTranslateMessage | ------------------------------------- | | ------------------------------------- | CWnd:: PreTranslateMessage | -------------------------------------

对于一个模态对话框,上面的序列就没用了。一个模态对话框用对话框管理器去从应用程序的消息队列得到消息并处理他们。换句话说,在模态对话框存在的时候,对话框管理器控制着消息处理。顺序如下:

------------------------------------- | CWinApp::PumpMessage | ------------------------------------- | | ------------------------------------- | CDialog::DoModal | ------------------------------------- | | ------------------------------------- | Dialog Manager's Message Loop | -------------------------------------

CWinApp::PumpMessage只在调用对话框时被调用一次,以后都不再调用,直到对话框管理器退出消息循环,即对话框不可见(dismissed)。

而非模态对话框用的是正常的消息循环。

PreTranslateMessage一般都会被重写以在消息被翻译和分派前添加些额外的处理。但因为模态对话框存在时并不调用PreTranslateMessage,因而无法达到前述效果。这时候就要另外的技术:

一是用非模态对话框模拟模态对话框。创建一个非模态对话框,然后使主框架窗口不可用,这样就可以调用PreTranslateMessage了。AfxGetApp()->m_pMainWnd->EnableWindow(FALSE)。当非模态对话框消失时,记得要将框架窗口可用,AfxGetApp()->m_pMainWnd->EnableWindow(TRUE)。

二是如果一个模态对话框很必要,那么可以重写CWinApp::ProcessMessageFilter以执行额外的消息处理。