应用程序应该像接收鼠标输入一样可以接收键盘输入,Windows中的应用程序是以窗体消息的形式来获取键盘输入。
本节包括以下内容:
键盘输入模型
键盘聚焦及激活
按键消息
字符消息
键状态
按键及字符转换
热键支持
浏览及其他功能键
模拟输入
语言、场所及键盘布局
键盘输入模型
系统通过安装当前键盘的设备驱动来实现与应用程序的设备无关性,也可以通过用户或应用程序的键盘布局设置来实现语言无关性。键盘设备驱动接收键盘的“扫描码”,然后把“扫描码”发送给键盘布局,通过键盘布局被转换为消息并发送到应用程序的相应窗口。
键盘上每一个键都有一个唯一值,这个唯一值就称为“扫描码”(scan code),对于键盘上每个键来说,“扫描码”是设备相关的。当用户按键时会产生两次扫描码,一次是按下键时,一次是放开时。
然后,键盘驱动把扫描码解释并转换(映射)为“虚键码”(virtual-key code),这个码是设备无关的,其值被系统所定义并用来标识每一个键。转换扫描码后,键盘布局会创建一个包含扫描码、虚键码以及其他按键信息的消息,并把这个消息放入系统消息队列。接着,系统从系统消息队列中删除该消息,再投递到相应线程的消息队列中。最后,线程的消息循环移除该消息并传递到相应窗口过程以进行处理。下图即键盘输入模型:

键盘聚焦及激活
系统投递键盘消息到前台线程的消息队列中,这个前台线程应该是创建当前获得焦点的窗口的线程。键盘聚焦(Keyboard focus)是一个窗体的临时属性。系统通过键盘聚焦来向所有的显示窗体共享键盘,从用户的角度讲,键盘聚焦也就意味着,从一个窗口转到另外一个。获取焦点的窗口接收(从创建它的线程的消息队列中)接收所有的键盘消息,直到焦点转移到另外的窗体上。
线程可以通过调用GetFocus函数来确定那个窗口为当前窗口(已经键盘聚焦),也可以通过SetFocus来使哪个窗口获取焦点。当键盘聚焦从一个窗口换到另外一个时,系统会发送WM_KILLFOCUS到失去焦点的窗口,然后发送WM_SETFOCUS消息到获得焦点的窗口。
键盘聚焦与活动窗口有一定关系,活动窗口(active window)是最上层用户正在操作的窗口。键盘聚焦的窗体或者是活动窗体,或者是活动窗体的子窗体。为了帮助用户辨别活动窗体,系统把它置于Z-order的最上层,并高亮它的标题栏及边框。
用户可以通过点击来激活一个顶级窗体,也可以用ALT+TAB(ALT+ESC)组合键或者通过任务列表来选择一个窗体。线程可以通过SetActiveWindow函数来激活一个顶级窗体,也可以通过GetActiveWindow函数来确定它创建的顶级窗体是否已被激活。
当一个窗体的活动状态变更时,系统会发送WM_ACTIVATE消息。wParam参数的低字(译者注:wParam在Win32中是一个32位的整数,从高到低依次编码的话应该是31、30、29、……、2、1、0,低字指的是15到0)部分 如果为0表示窗体未激活,否则表示激活。默认的窗口处理过程收到WM_ACTIVATE消息时,会设置键盘聚焦到活动窗口。
要阻止应用程序接收键盘及鼠标事件的话,可以使用BlockInput。需要注意的是,BlockInput函数不会影响异步的键盘输入状态表,也就是说,当输入被阻塞时,调用SendInput函数会改变异步键盘输入状态表。(译者注:原文直译可能让人更加摸不着北,应该是说,BlockInput函数不会影响异步的键盘输入,这个时候,调用SendInput的话,还是会改变异步的键盘输入状态信息)。
按键消息
按下键会产生WM_KEYDOWN或WM_SYSKEYDOWN消息,然后会被放置在当前键盘聚焦的窗口所在线程的消息队列中。同样释放按键也会产生消息,这个消息将会是WM_KEYUP或者WM_SYSKEYUP。
Key-up与Key-down消息通常应该成对出现,但如果用户按下键后呆足够长时间的话,键盘会自动重复描述这一情况,系统会对应产生一系列的WM_KEYDOWN或WM_SYSKEYDOWN事件,但不管怎样,用户释放按键时,只会产生一个WM_KEYUP或WM_SYSKEYUP消息。
本节包括以下内容:
系统及非系统按键
虚拟码描述
按键消息标志
系统及非系统按键
系统中系统按键与非系统按键是截然不同的,系统按键产生系统按键消息:WM_SYSKEYDOWN、WM_SYSKEYUP,而非系统按键产生非系统按键消息:WM_KEYDOWN与WM_KEYUP。
如果你的窗口处理过程确实有必要处理系统按键消息的话,一定要确认在处理完毕后,该过程把消息传递给了DefWindowProc函数。否则,所有的系统操作,包括ALT键都会失效,即便窗口的确获得了焦点。也就是说,用户将不能访问窗口菜单或者系统菜单,又或者使用ALT+ESC(ALT+TAB)组合键激活其他窗口了。
系统按键消息主要是系统使用的,系统用这些消息提供菜单的内置键盘接口,以及允许用户控制激活不同的窗口。系统按键消息通常是用户按下ALT及某个键的组合键时产生的,又或者在用户按下但没有窗体拥有键盘焦点(比如,激活的应用程序最小化)时产生。如果消息产生的话,就会发送到激活窗体的消息队列中。
非系统按键消息是需要应用程序窗体处理的,DefWindowProc函数不会对这些消息作任何处理,窗体的处理过程可以忽略任意的不需要的非系统按键消息。
虚键码描述
按键消息的wParam参数包含了按键的虚键码,窗口处理过程根据这个虚键码来处理或者忽略一个按键消息。
[1] [2] [3] [4] [5] 下一页
|