关于原始输入
其实,除了传统的键盘与鼠标外还有很多输入设备,例如游戏杆、触摸屏、麦克风或其他更灵活的输入设备。 这些设备统称为人类接口设备(Human Interface Devices)简称HID。原始输入(raw input)API提供了对任意HID原始输入的稳定及健壮支持,其中就包括键盘和鼠标。
本节涵盖以下内容:
- 原始输入模型
- 登记原始输入设备
- 获取原始输入数据
原始输入模型
以前,通常用键盘及鼠标作为输入设备,系统是通过去除原始信息中的设备特定描述来解释这些设备数据的。例如,键盘产生设备特定的扫描码,但系统提供给应用程序的却是虚键码(virtual key code)。除了支持隐藏原始输入细节的设备外,窗口管理器不支持所有的新HID。要从不支持的HID中获取输入的话,应用程序不得不做许多事情:打开一个设备、管理共享模式、周期性的读取设备或者建立I/O completion port等等。原始输入模型及API简化了这些操作,使得我们可以很简单的访问所有原始输入设备的原始输入数据,其中就包含键盘及鼠标。
原始输入模型同原来的键盘、鼠标的Microsoft® Windows®输入模型不同,原来的模型中,应用程序以发送或提交到窗体的消息的形式接收设备无关输入,如 WM_CHAR 、WM_MOUSEMOVE及 WM_APPCOMMAND。 与之对应,原始输入的应用程序必须登记需要获取数据的设备。然后,应用程序就可以通过WM_INPUT消息接收原始输入了。
下面是一些原始输入模型的优点:
- 应用程序没有必要非得检测或打开一个输入设备了;
- 应用程序直接从设备获取数据,并可以仅处理它需要的数据;
- 即便有同种类型的设备,应用程序也可以识别源输入。例如有两个鼠标的话。
- 应用程序可以指定一组特定的设备或者仅指定设备类型来进行数据通信。
- 只要市场有货,HID设备就可以使用,而不必等待系统支持新的消息类型或更新OS以在WM_APPCOMMAND中包含新的命令。
注意:WM_APPCOMMAND的确提供对某些HID设备的支持,然而,WM_APPCOMMAND是一个更高级的设备无关的输入事件,而WM_INPUT发送低级的原始数据。
登记原始输入设备
默认情况下,应用程序不会接收原始输入,要接收原始数据的话,就必须首先登记输入设备。
要登记设备的话,首先要创建一个RAWINPUTDEVICE结构的数组,其中包含设备的顶级集合(top level collection)(TLC)。TLC是通过一个Usage Page(设备类)及一个Usage(类内部设备)定义的。例如,要得到键盘TLC的话,需要设置UsagePage = 1并且Usage = 6,然后调用RegisterRawInputDevices来完成登记设备。
注意:应用程序可以登记一个当前并未连到系统的设备。一旦设备连接,窗口管理器就会自动发送原始输入到应用程序。要得到系统中原始输入设备列表的话,可以调用GetRawInputDeviceList。使用调用中的hDevice,然后调用GetRawInputDeviceInfo就可以得到设备信息。
通过RAWINPUTDEVICE的成员dwFlags,应用程序可以选择需要的设备或者不需要哪些设备。例如,应用程序可以请求所有电话的输入,但不包括应答机的。关于示例代码,请参见“登记原始输入设备”。
注意:鼠标、键盘同样也是HID,所以他们的数据可以通过HID消息WM_INPUT得到,也可以通过传统的消息得到。应用程序可以通过设置RAWINPUTDEVICE中的选项标志选定使用不同的方法。
要获取一个应用程序的设备登记情况,可以随时通过GetRegisteredRawInputDevices调用得到。
获取原始输入数据
应用程序会接收哪些顶级集合已经登记的HID的原始输入,到收到原始输入时,消息队列中就会得到一个WM_INPUT消息,并且队列状态标志QS_RAWINPUT被设置(QS_INPUT也包含该标志)。应用程序无论在前台或后台都回收到数据。
获取原始数据有两种方法:不缓存(标准)的方法及缓存的方法。不缓存的方法依次读取一个RAWINPUT结构的数据,并且该方法对许多HID都适合。这里,应用程序通过调用GetMessage来得到WM_INPUT消息,然后用WM_INPU中的RAWINPUT句柄调用GetRawInputData。示例请见“标准方式获取原始输入”。
相对而言,缓存的方法一次得到一个RAWINPUT结构的数组。这比较适合那些可能产生大量原始输入的设备。在该方法中,应用程序通过调用GetRawInputBuffer得到RAWINPUT结构数组。注意NEXTRAWINUPTBLOCK宏是为了遍历RAWINPUT结构数组。示例请参照“缓存方式读取原始输入”。
要解释原始输入,就需要HID的详细信息,可以通过GetRawInputDeviceInfo得到设备信息,其所需的设备句柄可以通过WM_INPUT或者RAWINPUTHEADER.hDevice获得。
翻译:Room3rd@hotmail.com,2004-11-25止