比较WM_KEYDOWN、WM_KEYUP、WM_SYSKEYDOWN、WM_SYSKEYUP与WM_CHAR

【转】比较WM_KEYDOWN、WM_KEYUP、WM_SYSKEYDOWN、WM_SYSKEYUP与WM_CHAR
       前一阵子写程序的时候,发现了WM_KEYDOWN使用虚拟键码,完全可以知道响应的是什么字母键。当按下字母键“A”的时候,我们知道WM_KEYDOWN的wParam消息参数就可以知道是什么虚拟键码,这里wParam是“0x41”.如果想输入大写字母A, 我们完全可以使用GetKeyState(VK_SHIFT)和GetKeyState(VK_CAPITAL)来判断时候输入的是否是大写字母,然后通过ASCII中大小写之间相差0x16来进行转换。
       但是Windwos消息响应中为什么还要添加WM_CHAR呢?这不在一定范围内重复了么。一般我们用WM_KEYDOWN种处理具有非打印键的消息, 而使用WM_CHAR中处理可打印字符消息。但是KEYDOWN完全可以替代WM_CHAR,只是处理起来相对复杂一些而已,不过我们完全可以写一套自己的库来处理相关的情况,而放弃WM_CHAR。
       上网查了一下,很多程序员认为WM_CHAR和WM_KEYDOWN的差别在于:如果分别按下“q”和“shift+q”,发出的WM_KEYDOWN消息都是代表q键,而发出的WM_CHAR消息分别是“q”和“Q” 。但是二者区别用意真正在于当你遇到国际键盘之间的差异的话,WM_CHAR和WM_KEYDOWN所产生的结果就不一样了。如果您得到wParam等于0x33的WM_KEYDOWN消息,您就可以知道使用者按下了键3,到此为止一切正常。这时,如果用GetKeyState发现Shift键被按下,您就可能会认为使用者输入了#号,这可不一定。比如英国使用者就是在输入£。(注:TranslateMessage函数就是将按键消息转换为字符消息。如果消息为WM_KEYDOWN或者WM_SYSKEYDOWN,并且按键与位移状态相组合产生一个字符,则TranslateMessage把字符消息放入消息伫列中。)
不同键盘之间的差别,Windows给我们做了很好的解决方案了,我们为什么还要根据不同的键盘来确定WM_KEYDOWN结果呢。
        至于WM_KEYDOWN和WM_KEYUP之间的区别就很容易区别了,一个是键的按下,一个是键的释放。而WM_SYSKEYDOWN与WM_KEYDOWN的区别在于WM_SYSKEYDOWN和WM_SYSKEYUP消息经常由与Alt相组合的按键产生,这些按键启动程序菜单或者系统菜单上的选项,或者用于切换活动窗口等系统功能(Alt-Tab或者Alt-Esc),也可以用作系统菜单加速键(Alt键与一个功能键相结合,例如Alt-F4用于关闭应用程序)。程序通常忽略WM_SYSKEYUP和WM_SYSKEYDOWN消息,并将它们传送到DefWindowProc。由于Windows要处理所有Alt键的功能,所以您无需拦截这些消息。您的窗口消息处理程序将最后收到关于这些按键结果(如菜单选择)的其它消息。如果您想在自己的窗口消息处理程序中加上拦截系统按键的程序码,那么在处理这些消息之后再传送到DefWindowProc,Windows就仍然可以将它们用于通常的目的。当然我们完全可以在响应WM_KEYDOWN和WM_KEYUP消息的lParam参数时,判断第29位来判断Alt键是否按下,如果在按键的时候同时按下ALT键,那么该位为1, 否则为0;或者通过GetKeyState(VK_MENU)来判断ALT也是可以的哦。

转自: http://hanwei0143.blog.163.com/blog/static/51926993200711412630918/

你可能感兴趣的:(比较WM_KEYDOWN、WM_KEYUP、WM_SYSKEYDOWN、WM_SYSKEYUP与WM_CHAR)