如何在 MFC 对话框与单文档(SDI)工程中获得与处理键盘消
息
http://www.blogbus.com/jingtianzi-logs/159024434.html
VC 中键盘事件处理主要是通过对相应的消息的响应,这些事件有如:
WM_CHAR、WM_KEYDOWN、WM_KEYUP 等他们分别对应
OnChar、OnKeyDown、OnKeyUp 消息处理函数;当然在有些时候我们也可能需要用到对
PreTranslateMessage 函数的重载。
从这些事件的名称我们可以看出 WM_CHAR 表示字符事件,WM_KEYDOWN 表示键盘的
键被按下时事件,而 WM_KEYUP 则表示键盘的键被放开时的事件;我们在键盘上按下某
个键时系统先调用 OnKeyDown 函数接着调用 OnChar 函数最后调用 OnKeyUp 函数;这些
消息函数的原形如下:
afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags);
nChar 代表虚拟键,nRepCnt 代表重复次数;而对于 nFlags 则有点麻烦但大多数时候我们不
管这个参数,nFlags 的具体意义请参考 MSDN 相关文档。
在大多数时候我们只要用到 OnChar、OnKeyDown、OnKeyUp 这些消息处理函数就
够了,但有时候我们会发理这些函数并不会被调用(特别是对话框程序)这时我们就必需
去重载 PreTranslateMessage 函数;些函数的使用也比较简单但在处理组合按键时我们必需
用到相关的辅助 API,这些 API 有 GetKeyState、GetKeyboardState 等;这些辅助 API 的功
能是获取相应键的当前状态(具体说明请参见 MSDN 文档)。
用 VC6 创建一个基于对话框的程序,结果发现对于不能直接响应键盘按键的消息。原来,
在 MFC 中,对话框程序在完成程序的初始化后,就在程序主线程中,调用
CWinThread::Run 函数。在该函数中,首先调用 API 函数 PeekMessage,而函数
PeekMessage 检查线程消息队列,如果消息存在,就将该消息放于指定的 MSG 结构中,以
后的消息处理都将针对这一 MSG 结构对象。捕获消息后,该函数将捕获的消息进行预处
理,然后再将消息传递给相应的窗口处理函数。
键盘消息被拦截而得不到正常响应,其中的关键就是 Run 函数对消息的预处理。在 Run 函
数中,调用了函数 CWinThread::PumpMessage,就是利用这一函数,MFC 实现了对消息的
分流,使得消息沿着 MFC 对各种消息规定的路线流动,直到被正确响应。
函数 PumpMessage 调用了函数 CWinThread::PreTranslateMessage 对消息进行处理,如果该
评论0