VC处理键盘消息
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 代码与键盘中各键的对应关系如下:
VK_0 到 VK_9 表示键盘上数字“ 0 ”到“ 9 ”键 (ASCII 码为 0x30 - 0x39) ;
VK_A 到 VK_Z 表示键盘上字母“ A ”到“ Z ”键 (ASCII 码为 0x41 - 0x5a) ;
VK_ADD 表示数字键盘上的“ + ”键。
VK_ALT 表示键盘上 “ ALT ”键。
VK_BACK_QUOTE 表示键盘上 “ ` ”键。
VK_BACK_SLASH 表示键盘上 “ / ”键。
VK_BACK_SPACE 表示键盘上 “ BACKSPACE “键。
VK_CAPS_LOCK 表示键盘上 “ CAPS LOCK ”键。
VK_CLOSE_BRACKET表示键盘上 “ ] ”键。
VK_COMMAN 表示键盘上 “ , ”键。
VK_CONTROL 表示键盘上 “ CTRL ”键。
VK_DECIMAL 表示数字键盘上 “ . ”键。
VK_DELETE 表示键盘上 “ DELETE ”键。
VK_DIVIDE 表示键盘上 “ / ”键。
VK_DOWN 表示键盘上 “向下箭头”键。
VK_END 表示键盘上 “ END ”键。
VK_ENTER 表示键盘上 “ ENTER ”键。
VK_EQUALS 表示键盘上 “=”键。
VK_ESCAPE 表示键盘上 “ ESC ”键。
VK_F1 到 VK_F12 表示键盘上 “ F1 ”到“ F12 ”键。
VK_HOME 表示键盘上 “ HOME ”键。
VK_INSERT 表示键盘上 “ INSTERT ”键。
VK_LEFT 表示键盘上 “向左箭头”键。
VK_MULTIPLY 表示键盘上 “ * ”键。
VK_NUMPAD0 到 VK_NUMPAD9 表示数字键盘上 “ 0 ”到“ 9 ”键。
VK_OPEN_BRACKET 表示键盘上 “ [ ”键。
VK_PAGE_DOWN 表示键盘上 “ PAGE DOWN ”键。
VK_PAGE_UP 表示键盘上 “ PAGE UP ”键。
VK_PAUSE 表示键盘上 “ PAUSE ”键。
VK_PRINTSCREEN 表示键盘上 “ PRINT SCREEN ”键。
VK_RIGHT 表示键盘上 “向右箭头”键。
VK_SCROLL_LOCK 表示键盘上 “ SCROLL LOCK ”键。
VK_SEMICOLON 表示键盘上 “;”键。
VK_SHIFT 表示键盘上 “ SHIFT ”键。
VK_SPACE 表示键盘上 “ SPACEBAR ”键。
VK_SUBTRACT 表示键盘上 “-”键。
VK_TAB 表示键盘上 “ TAB ”键。
VK_UP 表示键盘上 “向上箭头”键。
例子如下:
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);
}