字符消息

前面讨论了利用位移状态信息把按键消息翻译为字符消息的方法,并且提到,仅利用转换状态信息还不够,因为还需要知道与国家/地区有关的键盘配置。由于这个原因,您不应该试图把按键消息翻译为字符代码。Windows会为您完成这一工作,在前面我们曾看到过以下的程序代码:

while       (GetMessage (&msg, NULL, 0, 0))
        
{
        
    TranslateMessage (&msg) ;
        
    DispatchMessage (&msg) ;
        
}
        

这是WinMain中典型的消息循环。GetMessage函数用队列中的下一个消息填入msg结构的字段。DispatchMessage以此消息为参数呼叫适当的窗口消息处理程序。

在这两个函数之间是TranslateMessage函数,它将按键消息转换为字符消息。如果消息为WM_KEYDOWN或者WM_SYSKEYDOWN,并且按键与位移状态相组合产生一个字符,则TranslateMessage把字符消息放入消息队列中。此字符消息将是GetMessage从消息队列中得到的按键消息之后的下一个消息。

 

消息顺序

因为TranslateMessage函数从WM_KEYDOWN和WM_SYSKEYDOWN消息产生了字符消息,所以字符消息是夹在按键消息之间传递给窗口消息处理程序的。例如,如果Caps Lock未打开,而使用者按下再释放A键,则窗口消息处理程序将接收到如表6-10所示的三个消息:

表6-10

消息

按键或者代码

WM_KEYDOWN

「A」的虚拟键码(0x41)

WM_CHAR

「a」的字符代码(0x61)

WM_KEYUP

「A」的虚拟键码(0x41)

如果您按下Shift键,再按下A键,然后释放A键,再释放Shift键,就会输入大写的A,而窗口消息处理程序会接收到五个消息,如表6-11所示:

表6-11

消息

按键或者代码

WM_KEYDOWN

虚拟键码VK_SHIFT (0x10)

WM_KEYDOWN

「A」的虚拟键码(0x41)

WM_CHAR

「A」的字符代码(0x41)

WM_KEYUP

「A」的虚拟键码(0x41)

WM_KEYUP

虚拟键码VK_SHIFT(0x10)

Shift键本身不产生字符消息。

如果使用者按住A键,以使自动重复产生一系列的按键,那么对每条WM_KEYDOWN消息,都会得到一条字符消息,如表6-12所示:

表6-12

消息

按键或者代码

WM_KEYDOWN

「A」的虚拟键码(0x41)

WM_CHAR

「a」的字符代码(0x61)

WM_KEYDOWN

「A」的虚拟键码(0x41)

WM_CHAR

「a」的字符代码(0x61)

WM_KEYDOWN

「A」的虚拟键码(0x41)

WM_CHAR

「a」的字符代码(0x61)

WM_KEYDOWN

「A」的虚拟键码(0x41)

WM_CHAR

「a」的字符代码(0x61)

WM_KEYUP

「A」的虚拟键码(0x41)

如果某些WM_KEYDOWN消息的重复计数大于1,那么相应的WM_CHAR消息将具有同样的重复计数。

组合使用Ctrl键与字母键会产生从0x01(Ctrl-A)到0x1A(Ctrl-Z)的ASCII控制代码,其中的某些控制代码也可以由表6-13列出的键产生:

表6-13

按键

字符代码

产生方法

ANSI C控制字符

Backspace

0x08

Ctrl-H

/b

Tab

0x09

Ctrl-I

/t

Ctrl-Enter

0x0A

Ctrl-J

/n

Enter

0x0D

Ctrl-M

/r

Esc

0x1B

Ctrl-[

最右列给出了在ANSI C中定义的控制字符,它们用于描述这些键的字符代码。

有时Windows程序将Ctrl与字母键的组合用作菜单快捷键此时,不会将字母键转换成字符消息。

经过10年的考虑(回顾这些年来我写过的Windows程序代码),我更喜欢将Tab、Enter、Backspace和Escape键处理成控制字符,而不是虚拟键。我通常这样处理WM_CHAR:

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 ;
        
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值