您的位置:首页 > 其它

【MFC】基于对话框的键盘响应

2017-07-02 14:08 525 查看
先看下从网上找到的一篇文章(别急着用):

键盘消息作者:孙文华 时间: 2011-1-6

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相关文档。

在大多数时候我们只要用到OnChar、OnKeyDown、OnKeyUp这些消息处理函数就够

了,但有时候我们会发理这些函数并不会被调用(特别是对话框程序)这时我们就必需去重

载PreTranslateMessage函数;些函数的使用也比较简单但在处理组合按键时我们必需用到相

键盘消息被拦截而得不到正常响应,其中的关键就是Run函数对消息的预处理。在Run

函数中,调用了函数CWinThread::PumpMessage,就是利用这一函数,MFC实现了对消息

的分流,使得消息沿着MFC对各种消息规定的路线流动,直到被正确响应。函数PumpMessage调用了函数CWinThread::PreTranslateMessage对消息进行处理,如

果该函数不对消息进行处理,则调用API函数TranslateMessage函数将虚拟键消息转换为字

符消息并调用DispatchMessage分发消息给窗口处理程序。在对话框中,程序用

CWinThread::PreTranslateMessage函数处理了键盘消息,所以对话框程序是否要响应键盘消

息,将完全由CWinThread::PreTranslateMessage函数来决定了。

在CWnd及其派生类的成员函数PreTranslateMessage函数是一个虚函数,可以通过重

载来改变其处理过程。在默认情况下,没有重载这一函数。

例子1:

在VC6中创建基于对话框的工程,在Class view中找到相应的对话框类单击右键,在右键

菜单中选择Add Virtual Fuction...项,然后找到PreTranslateMessage虚函数进行加载。相应的

代码中如下:
BOOL CTestDlg::PreTranslateMessage(MSG* pMsg)

{

// TODO: Add your specialized code here and/or call the base class

//判断是否是按键消息

if( pMsg->message == WM_KEYDOWN )

{

MessageBox("有键被按下");

//判断具体键

switch( pMsg->wParam )

{

case VK_LEFT://按下左键

MessageBox(_T("左"));

return TRUE;

break;

case VK_RIGHT://按下右键

MessageBox(_T("右"));

return TRUE;

break;
case VK_UP://按下上键

MessageBox(_T("上"));

return TRUE;

break;

case VK_DOWN://按下下键

MessageBox(_T("下"));

return TRUE;

break;

default:

return TRUE;

break;

}

return CDialog::PreTranslateMessage(pMsg);

}

}


///////////////////////////////////////////////////////////////////////////////////////////////

将return CDialog::PreTranslateMessage(pMsg);放在if里将导致程序无法正常关闭!

最起码应该放到if的外面去。

下面是一个用WASD这几个按键控制滑块的代码:(用→这样的按钮控制时老是出问题)

其中m_X,和m_Y为滑块的控制变量
BOOL CTestDlg::PreTranslateMessage(MSG *pMsg)
{
if (pMsg->wParam == 'W')
{
Y = m_Y.GetPos();
Y++;
m_Y.SetPos(Y);
}
else if (pMsg->wParam == 'S')
{
Y = m_Y.GetPos();
Y--;
m_Y.SetPos(Y);
}
else if (pMsg->wParam == 'A')
{
X = m_X.GetPos();
X--;
m_X.SetPos(X);
}
else if (pMsg->wParam == 'D')
{
X = m_X.GetPos();
X++;
m_X.SetPos(X);
}
return CDialog::PreTranslateMessage(pMsg);
}
当然也可以分开写:
1.先添加PreTranslateMessage(pMsg);里面只加入:
return CDialog::PreTranslateMessage(pMsg);
即:
BOOL CKEYDlg::PreTranslateMessage(MSG *pMsg)
{
// TODO: Add your specialized code here and/or call the base class
return CDialog::PreTranslateMessage(pMsg);
}
2.然后添加单独添加WM_KEYDOWN等消息:
void CKEYDlg::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: Add your message handler code here and/or call default
if (nChar == VK_SPACE)
{
MessageBox("空格键被按下","提示!");
}
CDialog::OnKeyDown(nChar, nRepCnt, nFlags);
}


另附上 虚拟码:

后面括号的是对应的ASCII码

ESC键 VK_ESCAPE (27)

回车键: VK_RETURN (13)

TAB键: VK_TAB (9)

Caps Lock键: VK_CAPITAL (20)

Shift键: VK_SHIFT ($10)

Ctrl键: VK_CONTROL (17)

Alt键: VK_MENU (18)

空格键: VK_SPACE ($20/32)

退格键: VK_BACK (8)

左徽标键: VK_LWIN (91)

右徽标键: VK_LWIN (92)

鼠标右键快捷键:VK_APPS (93)

Insert键: VK_INSERT (45)

Home键: VK_HOME (36)

Page Up: VK_PRIOR (33)

PageDown: VK_NEXT (34)

End键: VK_END (35)

Delete键: VK_DELETE (46)

方向键(←): VK_LEFT (37)

方向键(↑): VK_UP (38)

方向键(→): VK_RIGHT (39)

方向键(↓): VK_DOWN (40)

F1键: VK_F1 (112)

F2键: VK_F2 (113)

F3键: VK_F3 (114)

F4键: VK_F4 (115)

F5键: VK_F5 (116)

F6键: VK_F6 (117)

F7键: VK_F7 (118)

F8键: VK_F8 (119)

F9键: VK_F9 (120)

F10键: VK_F10 (121)

F11键: VK_F11 (122)

F12键: VK_F12 (123)

Num Lock键: VK_NUMLOCK (144)

小键盘0: VK_NUMPAD0 (96)

小键盘1: VK_NUMPAD0 (97)

小键盘2: VK_NUMPAD0 (98)

小键盘3: VK_NUMPAD0 (99)

小键盘4: VK_NUMPAD0 (100)

小键盘5: VK_NUMPAD0 (101)

小键盘6: VK_NUMPAD0 (102)

小键盘7: VK_NUMPAD0 (103)

小键盘8: VK_NUMPAD0 (104)

小键盘9: VK_NUMPAD0 (105)

小键盘.: VK_DECIMAL (110)

小键盘*: VK_MULTIPLY (106)

小键盘+: VK_MULTIPLY (107)

小键盘-: VK_SUBTRACT (109)

小键盘/: VK_DIVIDE (111)

Pause Break键: VK_PAUSE (19)

Scroll Lock键: VK_SCROLL (145)

字母的虚拟码直接使用ASCII码即可

另外需要注意:

VK_?? 定义在 winuser.h 中,而对于字母123...,ABC..却没有VK_A,VK_B...

MFC中恰恰没有VK_0 -- VK_9,VK_A --VK_Z ,倒是有VK_NUMPAD0 --VK_NUMPAD9

在delphi,BCB,JAVA中都有。

当然,你可以直接定义,但是打开winuser.h会找到:

所以直接用'A'就行了!

转载来源:http://blog.sina.com.cn/s/blog_7590da790101285a.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  mfc