6、键盘

键盘基础

1、焦点

键盘被正在运行的所有程序共享,键盘消息会被当前拥有焦点的窗口接收,窗口获取焦点时窗口过程会收到WM_SETFOCUS消息,而失去焦点时会接收到WM_KILLFOCUS消息。

2、同步

键盘消息产生后,首先被暂时存储在系统消息队列中,只有当窗口过程处理完上一条键盘消息后,才会从系统消息队列取出下一条键盘消息放入程序消息队列中。
这一机制是为了避免键盘消息被发送到错误的窗口过程。假如没有系统消息队列:一个特殊的键盘消息可能导致焦点的转移,则其后面的键盘消息应该发送给另一个窗口。但如果用户输入速度比窗口过程处理消息速度快,那么在焦点切换到另一个窗口前,其后键盘消息都被发送到了当前窗口过程。

3、击键消息

按下一个键时,会产生WM_KEYDOWN或WM_SYSKEYDOWN消息;释放键时,会产生WM_KEYUP或WM_SYSKEYUP消息。如果按住键不放,会一直产生WM_KEYDOWN或WM_SYSKEYDOWN消息。

WM_SYSKEYDOWN和WM_SYSKEYUP消息是系统击键,一般由alt组合键产生,应用程序通常忽略系统击键消息,将它们交给DefWindowProc处理。

击键消息的wParam参数是虚拟击键码,<winuser.h>中定义了一系列VK_开头的虚拟键宏。

lParam包含击键消息的其他数据,32位被分成6个字段:

  • 16位重复计数[0,15]
    如果按住一个键不放,并且窗口过程来不及处理产生的击键消息,windows就把这些击键消息合并成一条,并增加其重复计数。KEYUP消息的重复计数总是1。

  • 8位OEM扫描码[16, 23]
    OEM扫描码是键盘硬件产生的代码,windows程序可以忽略。

  • 1位扩展键标记[24]
    windows程序可以忽略。

  • 1位内容代码[29]

  • 1位先前状态[30]
    0:键先前处于释放状态。1:键先前处于按下状态。

  • 1位转换状态[31]
    KEYDOWN消息为0,KEYUP消息为1。

4、GetKeyState
  • 判断按键是否被按下
    处理击键消息时,可能需要检查Shitf、Ctrll或Alt键是否按下来实现组合键功能,GetKeyState返回值的最高位表示按键的按下状态。如果按键按下,返回值高位置1,否则置0。
  • 判断按键开关状态
    键盘个别按键具有开关状态,比如CapsLock、NumLock、Scroll Lock等。GetKeyState返回值的最地位表示这些按键的开关状态。低位置1表示状态打开,否则关闭。

需要注意,GetKeyState不是实时的键盘状态,它反映的是窗口过程处理到当前消息为止的键盘状态(消息队列中可能还有待处理的键盘消息)。如果希望获取键盘的实时状态,可以使用GetAsyncKeyState函数。

字符消息

消息循环代码段中,通常都会调用TranslateMessage函数。TranslateMessage负责把WM_KEYDOWN或WM_SYSKEYDOWN消息转换为字符消息。如果WM_KEYDOWN或WM_SYSKEYDOWN消息产生了一个字符,TranslateMessage就会把字符消息放入应用程序消息队列中。

1、四种字符消息
  • WM_CHAR
  • WM_DEADCHAR
  • WM_SYSCHAR
  • WM_SYSDEADCHAR

通常,windows程序只需要处理WM_CAHR消息。
字符消息的lParam参数和击键消息的一样。wParam是字符的ANSI码或Unicode码。
wParam的编码依赖于注册窗口类时使用的函数。如果使用RegisterClassA,则wParam的编码是ANSI;如果使用RegisterClassW,则wParam的编码是Unicode。此外,还可以使用IsWindowUnicode来判断窗口使用的字符集。

插入符号

通常,进行文本输入的地方都会有一个闪烁的符号,称为“插入符号”。windows提供了几个处理插入符号的函数:

  • CreateCaret
  • SetCaretPos
  • ShowCaret
  • HideCaret
  • DestroyCaret
  • GetCaretPos
  • GetCaretBlinkTime
  • SetCaretBlinkTime

一个消息队列中只能有一个插入符号。窗口通常在获取到焦点时才显示插入符号,所以使用插入符号的一般方法是,在WM_SETFOCUS消息处理中CreateCaret,在WM_KILLFOCUS消息处理中DestroyCaret。

此外,还需要注意:

  • CreateCaret后,必须ShowCaret才会显示插入符号
  • 在非WM_PAINT消息中进行绘制时,必须先HideCaret隐藏插入符号
  • HideCaret的效果会叠加,需要调用相同次数ShowCaret才能显示插入符号。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值