找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 731|回复: 0

[分享] WM_CHAR、WM_KEYDOWN和WM_SYSKEYDOWN消息

[复制链接]

已领礼包: 13个

财富等级: 恭喜发财

发表于 2018-1-3 14:40:09 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×

       WM_KEYDOWN和WM_CHAR都是键盘消息。TranslateMessage函数已经将按键消息转换成字符消息了,那么WndProc函数中需要对事件进行选择。如:键入“D”键,就应该选择WM_CHAR,因为WM_CHAR 只是字母,不包含特殊字符如Ctrl等。

如果键盘键入的是“Ctrl+D”,则应该选择WM_KEYDOWN,因为WM_KEYDOWN既包含字母也包含特殊字符。

       WM_CHAR是由WM_KEYDOWN消息Translate()之后产生的,然后再发送给窗口过程。例如按下“D”键,产生WM_KEYDOWN消息,此消息经过Translate()处理后变成了WM_KEYDOW、WM_CHAR两个消息传递给窗口过程。

        而WM_SYSKEYDOWN是接受快捷键或系统命令按键的,像Alt键就是。所以捕获Alt键时,在WM_KEYDOWN下是无效的,要在WM_SYSKEYDOWN中。Ctrl和shift不属于WM_SYSKEYDOWN。键盘消息的处理从PreProcessMessage方法开始,按下表所述的逻辑顺序进行。(了解这个过程或许有助于对上面三个消息的理解) 方法 说明 结果 ProcessCmdKey 此方法检查按键是否为命令键,例如快捷键或菜单快捷键

如果方法返回true,则将不调度键消息,而且将不发生键事件

如果方法返回false,则将调用IsInputKey检查该键是否为常规输入键

IsInputKey 此方法检查按键是否为常规输入键 如果方法返回true,则表示该键为常规字符,将调用ProcessKeyMessage进行消息处理
如果方法返回false,则将调用ProcessDialogKey
ProcessDialogKey 此方法检查按键是否为导航键,例如Esc、Tab、回车键或箭头键。

如果该控件不处理该键,则将调用基控件或父控件的ProcessDialogKey,直至层次结构中的最顶端控件。 如果此方法返回true,则完成消息预处理,而且将不生成键事件

如果此方法返回false,则将调用ProcessKeyMessage进行消息处理

ProcessKeyMessage 此方法处理由控件的WndProc方法接收的所有键盘消息 如果控件有父级,则调用父级的ProcessKeyPreview
如果控件没有父级或父级的ProcessKeyPreview不处理该消息,则调用ProcessKeyEventArgs

ProcessKeyPreview 此方法将键盘消息发送到控件的父控件 如果此方法返回true,则将不发生键事件

如果此方法返回false,则将调用ProcessKeyEventArgs

ProcessKeyEventArgs 此方法引发KeyDown事件

BOOL CHBPlayerApp::PreTranslateMessage(MSG* pMsg)
{
// TODO: Add your specialized code here and/or call the base class
if (pMsg->message == WM_KEYDOWN)
{
  switch (pMsg->wParam)
  {
  //屏蔽Esc消息
  case VK_ESCAPE:
   return true;
   break;
  //屏蔽回车键消息
  case VK_RETURN:
   return true;
   break;
  //组合键Ctrl+C
  case 'C':
   if(::GetKeyState(VK_CONTROL) < 0)
   {
   }
   break;
   //组合键Ctrl+Shift+S
  case 'S':
     if((::GetKeyState(VK_CONTROL) < 0) && (::GetKeyState(VK_SHIFT) < 0))
   {
   }
    return CWinApp::PreTranslateMessage(pMsg);
}

在对话框中添加键盘响应事件

1. ClassView中Add Windows Message Handle 添加WM-KEYDOWN和WM-KEYUP,Add Virtural Functions添加PreTranslateMessage

2.         BOOL **Dlg::PreTranslateMessage(MSG* pMsg)中添加
{
       if (pMsg-> message == WM_KEYDOWN)
              {
                     if(pMsg-> wParam== VK_RETURN)//直接用虚码代替就可以响应所指键
                     SetInfo(WDK_OK);      //回车对应ok
              }
       if (pMsg-> message == WM_KEYDOWN)
              {
                     if(pMsg-> wParam== VK_BACK)//直接用虚码代替就可以响应所指键
                     SetInfo(WDK_C);         //backspace对应删除
              }
       return CDialog::PreTranslateMessage(pMsg);
}
3. 组合键的用法:(本例响应Ctrl+X键)

BOOL CMydilog::PreTranslateMessage(MSG* pMsg)
{
if (pMsg-> message == WM_KEYDOWN)
{
switch (pMsg-> wParam)
{
case VK_ESCAPE:
SetFocus ();
return TRUE;
case 'X':
if(::GetKeyState(VK_CONTROL) < 0
MessageBox(" hello" );
return TRUE;
}
}
return CDialog::PreTranslateMessage(pMsg);
}

F10 and ALT arent picked up by WM_KEYDOWN, you need WM_SYSKEYDOWN.
You need to add: case WM_SYSKEYDOWN:
if(pMsg->wParam == VK_F10)
TRACE("F10/n");
break ;

评分

参与人数 1D豆 +5 收起 理由
ScmTools + 5

查看全部评分

论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2024-11-12 14:01 , Processed in 0.308179 second(s), 32 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表