字符消息的产生
在消息循环中
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
当右WM_KEYDOWN或WM_SYSKEYDOWN消息产生并处理时,
消息循环中,TranslateMessage会将按键消息翻译转化称字符消息WM_CHAR。
如果消息为WM_KEYDOWN或者WM_SYSKEYDOWN,并且按键与位移状态相组合产生一个字符,
则TranslateMessage把字符消息放入消息队列中。此字符消息将是GetMessage从消息队列中得到的按键消息之后的下一个消息。
字符消息分为4类
字符 | 死字符 | |
非系统字符 | WM_CHAR | WM_DEADCHAR |
系统字符 | WM_SYSCHAR | WM_SYSDEADCHAR |
WM_CHAR和WM_DEADCHAR消息是从WM_KEYDOWN得到的;而WM_SYSCHAR和WM_SYSDEADCHAR消息是从WM_SYSKEYDOWN消息得到的
如何处理:
在大多数情况下,Windows程序会忽略除WM_CHAR之外的任何消息
字符消息的lParam参数含义与按键消息的lparam一致
但是,参数wParam不是虚拟键码,实际上,它是ANSI或Unicode字符代码。
窗口消息处理程序是如何知道该字符是8位的ANSI字符还是16位的Unicode宽字符呢?
很简单:任何与您用RegisterClassA(RegisterClass的ANSI版)注册的窗口类别相联系的窗口消息处理程序,都会获得含有ANSI字符代码的消息。
如果窗口消息处理程序用RegisterClassW(RegisterClass的宽字符版)注册,那么传递给窗口消息处理程序的消息就带有Unicode字符代码
按键消息与字符消息产生的顺序
因为TranslateMessage函数从WM_KEYDOWN和WM_SYSKEYDOWN消息产生了字符消息,
所以字符消息是夹在按键消息之间传递给窗口消息处理程序的。
例如,如果Caps Lock未打开,而使用者按下再释放A键,则窗口消息处理程序将接收到如表6-10所示的三个消息:
WM_KEYDOWN -> WM_CHAR(a) -> WM_KEYUP
如果按下Shift键,再按下A键,然后释放A键,再释放Shift键,就会输入大写的A,而窗口消息处理程序会接收到五个消息
WM_KEYDOWN(shift)-> WM_KEYDOWN(A) -> WM_CHAR(A) ->WM_KEYUP(A) ->WM_KEYUP(shift)
息 | 按键或者代码 |
WM_KEYDOWN | 虚拟键码VK_SHIFT (0x10) |
WM_KEYDOWN | 「A」的虚拟键码(0x41) |
WM_CHAR | 「A」的字符代码(0x41) |
WM_KEYUP | 「A」的虚拟键码(0x41) |
WM_KEYUP | 虚拟键码VK_SHIFT(0x10) |
处理字符消息:
case WM_CHAR:
switch (wParam)
{
case '\b': // backspace
//其它行程序
break ;
case '\t': // tab
//其它行程序
break ;
case '\n': // linefeed
//其它行程序
break ;
case '\r': // carriage return
//其它行程序
break ;
default: // character codes
//其它行程序
break ;
}
return 0 ;