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相關文檔;nChar 代碼與鍵盤中各鍵的對應關係如下:
取值(16進制) 常量符號 含義
01 VK_LBUTTON 鼠標左鍵
02 VK_RBUTTON 鼠標右鍵
03 VK_CANCEL Break中斷鍵
04 VK_MBUTTON 鼠標中鍵
05-07 -- 未定義
08 VK_BACK (BackSpace)鍵
09 VK_TAB Tab鍵
0A-0B -- 未定義
0C VK_CLEAR Clear鍵
0D VK_RETURN Enter鍵
0E-0F -- 未定義
10 VK_SHIFT Shift鍵
11 VK_CONTROL Ctrl鍵
12 VK_MENU Alt鍵
13 VK_PAUSE Pause鍵
14 VK_CAPTIAL CapsLock鍵
15-19 -- 漢字系統保留
1A -- 未定義
1B VK_ESCAPE Esc鍵
1C-1F -- 漢字系統保留
20 VK_SPACE 空格鍵
21 VK_PRIOR PageUp鍵
22 VK_NEXT PageDown鍵
23 VK_END End鍵
24 VK_HOME Home鍵
25 VK_LEFT ←(Left Arrow)鍵
26 VK_UP ↑(Up Arrow)鍵
27 VK_RIGHT →(Right Arrow)鍵
28 VK_DOWN ↓(Down Arrow)鍵
29 VK_SELECT Select鍵
2A -- OEM保留
2B VK_EXECUTE Execute鍵
2C VK_SNAPSHOT Print Screen鍵
2D VK_INSERT Insert鍵
2E VK_DELETE Delete鍵
2F VK_HELP Help鍵
30-39 VK_0-VK_9 數字鍵0-9
3A-40 -- 未定義
41-5A VK_A-VK_Z 字母鍵A-Z
5B-5F -- 未定義
60-69 VK_NUMPAD0-VK_NUMPAD9 小鍵盤數字鍵0-9
6A VK_MULTIPLY *(乘號)鍵
6B VK_ADD +(加號)鍵
6C VK_SEPAPATOR 分隔符鍵
6E VK_SUBTRACT -(減號)鍵
6F VK_DECIMAL .(小數點)鍵
70-87 VK_DIVIDE /(除號)鍵
88-8F VK_F1-VK_F24 F1-F24功能鍵
90 VK_NUMBERLOCK Number lock鍵
91 VK_SCROLL Scroll lock鍵
92-B9 -- 未定義
BA-C0 -- OEM保留
C1-DA -- 未定義
DB_E4 -- OEM保留
E5 -- 未定義
E6 -- OEM保留
E7-E8 -- 未定義
E9-F5 -- OEM保留
F6-FE -- 未定義
例子如下:
- void CTestCharDlg::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
- {
- // TODO: Add your message handler code here and/or call default
- switch(nChar)
- {
- case VK_LEFT://按下左鍵
- DealLeft();
- break;
- case VK_RIGHT://按下右鍵
- DealRight();
- break;
- case VK_UP://按下上鍵
- DealUp();
- break;
- case VK_DOWN:// 按下下鍵
- DealDown();
- break;
- default:
- break;
- }
- CDialog::OnKeyDown(nChar, nRepCnt, nFlags);
- }
在大多數時候我們只要用到OnChar、OnKeyDown、OnKeyUp這些消息處理函數就夠了,但有時候我們會發理這些函數並不會被調用(特別是對話框程序)這時我們就必需去重載PreTranslateMessage函數;些函數的使用也比較簡單但在處理組合按鍵時我們必需用到相關的輔助API,這些API有GetKeyState、GetKeyboardState等;這些輔助API的功能是獲取相應鍵的當前狀態(具體說明請參見MSDN文檔);PreTranslateMessage例子如下:
- BOOL CTestDlg::PreTranslateMessage(MSG* pMsg)
- {
- // TODO: Add your specialized code here and/or call the base class
- //判斷是否是按鍵消息
- if( pMsg->message == WM_KEYDOWN )
- {
- int nTmp;
- SHORT nVK;
- //獲取左Ctrl鍵狀態
- nVK = GetKeyState( VK_LCONTROL );
- nVK = nVK & 0xff00;
- //判斷具體鍵
- switch( pMsg->wParam )
- {
- case VK_LEFT://按下左鍵
- if ( nVK == 0 )
- {
- AdjustDestRect( -1, 0 );
- }else
- {
- AdjustLeftMid( -1 );
- }
- //消息到些結束,不要再向別的地方發送
- return TRUE;
- break;
- case VK_RIGHT://按下右鍵
- if ( nVK == 0 )
- {
- AdjustDestRect( 1, 0 );
- }else
- {
- AdjustRightMid( 1 );
- }
- break;
- case VK_UP://按下上鍵
- if ( nVK == 0 )
- {
- AdjustDestRect( 0, -1 );
- }else<, /SPAN>
- {
- AdjustTopMid( -1 );
- }
- break;
- case VK_DOWN://按下下鍵
- if ( nVK == 0 )
- {
- AdjustDestRect( 0, 1 );
- }else
- {
- ADjustButtonMid( 1 );
- }
- break;
- default:
- break;
- }
- }
- return CDialog::PreTranslateMessage(pMsg);
- }