鍵盤消息被攔截而得不到正常響應,其中的關鍵就是Run函數對消息的預處理。在Run函數中,調用了函數CWinThread::PumpMessage,就是利用這一函數,MFC實現了對消息的分流,使得消息沿着MFC對各種消息規定的路線流動,直到被正確響應。
函數PumpMessage調用了函數CWinThread::PreTranslateMessage對消息進行處理,如果該函數不對消息進行處理,則調用API函數TranslateMessage函數將虛擬鍵消息轉換爲字符消息並調用DispatchMessage分發消息給窗口處理程序。在對話框中,程序用CWinThread::PreTranslateMessage函數處理了鍵盤消息,所以對話框程序是否要響應鍵盤消息,將完全由CWinThread::PreTranslateMessage函數來決定了。
在CWnd及其派生類的成員函數PreTranslateMessage函數是一個虛函數,可以通過重載來改變其處理過程。在默認情況下,沒有重載這一函數。
例子如下,在VC6的Class view中找到相應的對話框類單擊右鍵,在右鍵菜單中選擇Add Virtual Fuction...項,然後找到PreTranslateMessage虛函數進行加載。
BOOL CKeyinTstDlg::PreTranslateMessage(MSG* pMsg) //CKeyinTstDlg我爲自己創建的對話框類
{
// TODO: Add your specialized code here and/or call the base class
if(pMsg->message == WM_KEYDOWN)
{
MessageBox(L"有鍵被按下");
}
return CDialog::PreTranslateMessage(pMsg);
}
BOOL CKeyinTstDlg::PreTranslateMessage(MSG* pMsg) //CKeyinTstDlg我爲自己創建的對話框類
{
// TODO: Add your specialized code here and/or call the base class
方式是使用PreTranslateMessage消息,進行處理,將焦點設置到主窗口上。具體代碼如下:
if ( pMsg->message == WM_CHAR)
{
pMsg->hwnd = m_hWnd;
return FALSE;
}
return CDialog::PreTranslateMessage(pMsg);
}
void Ctest4Dlg::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)//nChar 爲對應按鍵的asc碼值
{
if (nChar==0xD)
{
dd="";
aa.SetWindowText(dd);
}
CString ss;
ss.Format(L"%c",nChar);
dd=dd+ss;
aa.SetWindowText(dd);
CDialog::OnChar(nChar, nRepCnt, nFlags);
}