About Raw Input
There are many user-input devices beside the traditional keyboard and mouse. For example, user input can come from a joystick, a touch screen, a microphone, or other devices that allow great flexibility in user input. These devices are collectively known as Human Interface Devices (HIDs). The raw input API provides a stable and robust way for applications to accept raw input from any HID, including the keyboard and mouse.
This section covers the following topics:
Previously, the keyboard and mouse typically generated input data. The system interpreted the data coming from these devices in a way that eliminated the device-specific details of the raw information. For example, the keyboard generates the device-specific scan code but the system provides an application with the virtual key code. Besides hiding the details of the raw input, the window manager did not support all the new HIDs. To get input from the unsupported HIDs, an application had to do many things: open the device, manage the shared mode, periodically read the device or set up the I/O completion port, and so forth. The raw input model and the associated APIs were developed to allow simple access to raw input from all input devices, including the keyboard and mouse.
The raw input model is different from the original Windows input model for the keyboard and mouse. In the original input model, an application receives device-independent input in the form of messages that are sent or posted to its windows, such as WM_CHAR, WM_MOUSEMOVE, and WM_APPCOMMAND. In contrast, for raw input an application must register the devices it wants to get data from. Also, the application gets the raw input through the WM_INPUT message.
There are several advantages to the raw input model:
- An application does not have to detect or open the input device.
- An application gets the data directly from the device, and processes the data for its needs.
- An application can distinguish the source of the input even if it is from the same type of device. For example, two mouse devices.
- An application manages the data traffic by specifying data from a collection of devices or only specific device types.
- HID devices can be used as they become available in the marketplace, without waiting for new message types or an updated OS to have new commands in WM_APPCOMMAND.
Note that WM_APPCOMMAND does provide for some HID devices. However, WM_APPCOMMAND is a higher level device-independent input event, while WM_INPUT sends raw, low level data that is specific to a device.
By default, no application receives raw input. To receive raw input from a device, an application must register the device.
To register devices, an application first creates an array of RAWINPUTDEVICE structures that specify the top level collection (TLC) for the devices it wants. The TLC is defined by a Usage Page (the class of the device) and a Usage (the device within the class). For example, to get the keyboard TLC, set UsagePage = 1 and Usage = 6. The application calls RegisterRawInputDevices to register the devices.
Note that an application can register a device that is not currently attached to the system. When this device is attached, the Windows Manager will automatically send the raw input to the application. To get the list of raw input devices on the system, an application calls GetRawInputDeviceList. Using the hDevice from this call, an application calls GetRawInputDeviceInfo to get the device information.
Through the dwFlags member of RAWINPUTDEVICE, an application can select the devices to listen to and also those it wants to ignore. For example, an application can ask for input from all telephony devices except for answering machines. For sample code, see Registering for Raw Input.
Note that the mouse and the keyboard are also HIDs, so data from them can come through both the HID message WM_INPUT and from traditional messages. An application can select either method by the proper selection of flags in RAWINPUTDEVICE.
To get an application's registration status, call GetRegisteredRawInputDevices at any time.
An application receives raw input from any HID whose top level collection (TLC) matches a TLC from the registration. When an application receives raw input, its message queue gets a WM_INPUT message and the queue status flag QS_RAWINPUT is set (QS_INPUT also includes this flag). An application can receive data when it is in the foreground and when it is in the background.
There are two ways to read the raw data: the unbuffered (or standard) method and the buffered method. The unbuffered method gets the raw data one RAWINPUT structure at a time and is adequate for many HIDs. Here, the application calls GetMessage to get the WM_INPUT message. Then the application calls GetRawInputData using the RAWINPUT handle contained in WM_INPUT. For an example, see Doing a Standard Read of Raw Input.
In contrast, the buffered method gets an array of RAWINPUT structures at a time. This is provided for devices that can produce large amounts of raw input. In this method, the application calls GetRawInputBuffer to get an array of RAWINPUT structures. Note that the NEXTRAWINPUTBLOCK macro is used to traverse an array of RAWINPUT structures. For an example, see Doing a Buffered Read of Raw Input.
To interpret the raw input, detailed information about the HIDs is required. An application gets the device information by calling GetRawInputDeviceInfo with the device handle. This handle can come either from WM_INPUT or from the hDevice member of RAWINPUTHEADER.