VC++ 對話框程序響應鍵盤消息的處理方法的說明(很是重要)

基於MFC對話框的應用程序在響應按鍵消息和熱鍵方面都力不從心,CDialog類的消息循環中去掉了TranslateAccelerator函數,所以不能響應熱鍵;同時因爲對話框上可能有不少控件,且默認狀況下這些子窗口已經截獲了焦點,所以鍵盤消息已經被控件捕獲了;同時爲了實現控件焦點切換和對話框默認行爲,  VK_TAB、VK_LEFT、VK_RIGHT、VK_UP、VK_DOWN、 VK_RETURN、VK_ESCAPE 等鍵已經被截獲處理,所以對話框沒有控件時仍然不能徹底響應按鍵消息。app

    關於熱鍵的響應請參考這篇文章:Keyboard messages/accelerators handling in MFC dialog based applications
 
    那麼咱們怎麼讓對話框程序響應按鍵消息呢?答案就是重載PreTranslateMessage,在其中截獲鍵盤消息進行處理。
    與按鍵相關的消息大概有4個:WM_KEYDOWN、WM_KEYUP、WM_SYSKEYDOWN、WM_SYSKEYUP,須要說明的包括如下幾點:
    一、KEY與SYSKEY消息的區別在於:若是某個按鍵動做的同時,ALT鍵或F10鍵被按下,則發送SYSKEY消息,不然發送KEY消息;
    二、某個按鍵動做依次產生WM_KEYDOWN和WM_KEYUP消息;
    三、一個按鍵一直按着不放,會按必定間隔時間不斷髮送WM_KEYDOWN消息;
    四、單鍵動做最好響應WM_KEYUP,組合鍵動做響應WM_KEYDOWN或WM_SYSKEYDOWN;
    關於幾個按鍵消息的具體解釋,請參考MSDN。
 
    如下是一個響應單鍵消息的示例代碼:
BOOL CMyDlg::PreTranslateMessage(MSG* pMsg)   

{

if(pMsg->message == WM_KEYUP) 

{

// 響應keyup消息

if(pMsg->wParam == VK_RETURN)

{

// 回車

}

}

return CDialog::PreTranslateMessage(pMsg); 

}

 

 
    那麼怎樣判斷組合鍵呢?使用GetKeyState函數。示例代碼以下:
BOOL CMyDlg::PreTranslateMessage(MSG* pMsg)   

{

if(pMsg->message == WM_KEYDOWN)

{

// 組合鍵響應keydown消息

if( pMsg->wParam == VK_SPACE&& (GetKeyState(VK_SHIFT)& 0x8000))

{

// 空格 + Shift

}

}

else if(pMsg->message == WM_SYSKEYDOWN)

{

// Alt組合鍵響應syskeydown消息

if( pMsg->wParam == 'A'&& (HIWORD(pMsg->lParam) & KF_ALTDOWN))

{

// A + Alt

}

}

 

return CDialog::PreTranslateMessage(pMsg); 

}

 

 
    另外,還有GetAsyncKeyState和GetKeyboardState等相似函數,涉及到邏輯按鍵和物理按鍵值等問題,你們能夠參考MSDN的說明。
相關文章
相關標籤/搜索