MFC中CWintThread的PumpMessage函数的定义:
1 BOOL CWinThread::PumpMessage() 2 { 3 _AFX_THREAD_STATE *pState = AfxGetThreadState(); 4 5 ::GetMessage(&(pState->m_msgCur), NULL, NULL, NULL)) 6 7 if (!AfxPreTranslateMessage(&(pState->m_msgCur)))//当PreTranslateMessage返回FALSE时才继续传递消息 8 { 9 ::TranslateMessage(&(pState->m_msgCur)); 10 ::DispatchMessage(&(pState->m_msgCur)); 11 } 12 return TRUE; 13 }
由此可见,PreTranslateMessage函数在TranslateMessage之前调用,而且必须PreTranslateMessage返回TRUE时消息才能继续传递。
但是,只有进入消息队列的消息才受PreTranslateMessage影响。
钩子函数也是在TranslateMessage之前拦截消息,而且他是在PreTranslateMessage之前获取到消息的控制权,为此做如下测试:
1.为对话框添加PreTranslateMessage函数
//头文件中 virtual BOOL PreTranslateMessage(MSG* pMsg); //CPP文件中 BOOL CMFC_TabCtrlDlg::PreTranslateMessage(MSG* pMsg) { if(pMsg->wParam == 'A') { AfxMessageBox(_T("PreTranslateMessage")); } return FALSE; }
2.钩子
1 HHOOK g_HookKeyBord; 2 3 4 g_HookKeyBord = SetWindowsHookEx(WH_KEYBOARD, WindowHookProc, NULL, GetCurrentThreadId());//; 5 6 7 LRESULT CALLBACK WindowHookProc(int nCode,WPARAM wParam, LPARAM lParam) 8 { 9 if ((wParam == 'A'))//按下。否则 10 AfxMessageBox(_T("Hook")); 11 return CallNextHookEx(g_HookKeyBord,nCode,wParam,lParam);//其他键不拦截。也可以返回0.。不建议 12 }
经过测试,当按下键盘A字母时,先弹出Hook,再弹出PreTranslateMessage,由此可见,还是钩子牛B。。。。。