文章出处:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/userinput/rawinput/aboutrawinput.asp
关于原始输入
除了传统的键盘和鼠标以外还有很多其他的输入设备。例如:用户输入可以来自游戏杆设备,触摸屏,麦克风以及其他可以提供用户输入的设备。这些设备被统称为HID(人体工程学)设备。Raw Input的API为应用程序提供了稳定健壮的读取原始数据数据的方式,包括键盘和鼠标。
这篇文章主要包括3个部分:
· 原始输入模型
· 注册原始输入
· 读取原始输入
以前鼠标和键盘数据处理模式是这样的,鼠标和键盘产生输入数据,系统中断去处理这些与设备信息相关的数据,让这些数据变得与设备无关。例如:键盘产生与键盘设备相关的ScanCode但是系统提供给应用程序虚拟键码。除了隐藏原始输入的细节,Windows管理器还不支持所有新的HID设备。为了要从HID设备里面得到信息,一个应用程序必须处理以下步骤:打开设备,管理共享模式,周期性读取设备或者设置IO完成端口,或者更多操作。原始输入模型及其相关的API允许比较容易的从输入设备中获取原始输入,包括键盘和鼠标。
那么原始输入模型和微软原来的鼠标键盘输入模型有什么差别呢?在原来的输入模型,一个应用程序通过发送到他窗口的消息获取与设备无关的消息,例如WM_CHAR,WM_MOUSEMOVE和WM_APPCOMMAND。与之原来模式不同的是:一个应用程序想获取原始数据的必须注册他想要获取原始输入的那些设备,应用程序会收到WM_INPUT消息。
原始输入模型有很多优点:
l 应用程序不需要查找和打开输入设备。
l 应用程序直接从设备获取数据并根据他们的需要获取数据。
l 应用程序能够甄别来自两个不同设备的输入,尽管他们有可能是同一个类型的设备。例如:两个鼠标设备。
l 应用程序能够管理数据流,可以从一类设备或者某种制定类型设备获取输入数据。
l 当HID设备在市场上可以买到时候,能够立即被使用,而不需要等待操作系统更新新的消息定义或者操作系统更新WM_APPCOMMAND消息。
需要注意的是:WM_APPCOMMAND确实是为一些HID设备提供的。然而WM_APPCOMMAND是一个高层的非设备相关的输入事件,而WM_INPUT消息发送原始的底层的设备相关的消息。
默认情况下,没有应用程序会接受WM_INPUT消息。为了接受从一个设备发送原始输入,你必须注册这个设备。
为了注册这个设备,一个应用程序首先必须创建一个指明他所希望接受设备类别的(top level collection――
TLC)RAWINPUTDEVICE结构。TLC被定义成为UsagePage(设备类)和Usage(设备类内的具体设备)。例如为了从键盘获取原始输入,设置UsagePage = 1 and Usage = 6,应用程序调用RegisterRawInputDevice去注册这个设备。
注意:应用程序可以注册系统当前没有的设备。当设备可用之后,Windows管理器会自动将原始输入数据发送到应用程序。应用程序可以调用GetRawInputDeviceList来获取系统中原始输入设备的列表。用GetRawInputDeviceList获取的hDevice,应用程序调用GetRawInputDeviceInfo获取设备信息。
通过RAWINPUTDEVICE中的dwFlag,应用程序可以选择是否监听还是忽略来自某个指定设备的信息。例如:一个应用程序能够监听所有的电话设备除了答录机。
注意:鼠标和键盘也是HID设备,所以能够从Hid设备的WM_INPUT消息或者从传统的消息中获取信息。应用程序能够通过指定RAWINPUTDEVICE中的标志位选择任意一个。
可以调用GetRegisteredRawInputDevice来得到应用程序的该设备的注册状态。
读取原始输入
应用程序会收到符合所注册的TLC的HID设备的原始输入消息。当一个应用程序收到了原始输入,应用程序的消息队列就会得到一个WM_INPUT消息,系统状态被置成QS_RAWINPUT(QS_INPUT)同样包含这个标志。不管应用程序在前台和后台都能够收到消息。
有两种方法去读取原始数据:标准(没有缓冲的)方法和缓冲方法。前者获取原始输入时,每次获取一个RAWINPUT数据,而且对于大多数HID设备都是可以用这种方式读取的。应用程序调用CallMessage得到WM_INPUT消息,然后应用程序通过WM_INPUT消息,调用GetRawInputData来获取RAWINPUT句柄。
相对应的,缓存方式每次得到一系列的RAWINPUT结构。这是给那些能够构产生很大数据量的原始输入。用这种方法去获取数据,首先调用GetRawInputBuffer去获取一系列的RAWINPUT结构。注意NEXTTRAWINPUTBLOCK宏是用来获取下一个RAWINPUT结构的。
为了获取原始输入HID设备的详细信息。应用程序可以用GetRawInputdeviceInfo来查询相对应的句柄。这个句柄可以是从WM_INPUT消息或者RAWINPUTHRADER.hDevice获取。
附录:
部分词汇中英文对照表:
HID――人体工程学设备
SCANCODE――扫描码