Структура RAWINPUT¶
RAWINPUT — это структура данных в операционной системе Microsoft Windows, предназначенная для хранения информации о необработанных (raw) входных данных от устройств ввода, таких как клавиатура, мышь и джойстик. Она используется в рамках механизма Raw Input API, который позволяет приложениям получать данные напрямую от устройства, минуя стандартную обработку очереди сообщений Windows (Windows Message Queue). Структура определена в заголовочном файле Winuser.h и является частью Win32 API.
¶История и назначение
До появления Windows XP (2001 год) приложения для получения данных от мыши и клавиатуры использовали стандартные сообщения Windows, такие как WM_MOUSEMOVE, WM_KEYDOWN и WM_INPUT. Однако этот подход имел ограничения: он не обеспечивал доступа к данным с высокой частотой опроса, не поддерживал множественные устройства одного типа (например, две мыши) и не позволял получать информацию от специализированных устройств, таких как графические планшеты или игровые контроллеры, без дополнительных драйверов.
С выходом Windows XP компания Microsoft представила Raw Input API, который предоставил разработчикам прямой доступ к входным данным на уровне драйвера устройства. Центральным элементом этого API является структура RAWINPUT, которая инкапсулирует все полученные данные. Основное преимущество использования Raw Input — снижение задержки (лагентности) и возможность обрабатывать данные от устройств, которые не генерируют стандартные сообщения Windows.
¶Структура и поля
Структура RAWINPUT определена следующим образом (на языке C/C++):
``c typedef struct tagRAWINPUT { RAWINPUTHEADER header; union { RAWMOUSE mouse; RAWKEYBOARD keyboard; RAWHID hid; } data; } RAWINPUT; ``
¶Поле header
Поле header имеет тип RAWINPUTHEADER и содержит метаданные о полученном пакете данных:
- dwType — тип устройства. Может принимать одно из трёх значений:
RIM_TYPEMOUSE(0) — данные от мыши.RIM_TYPEKEYBOARD(1) — данные от клавиатуры.RIM_TYPEHID(2) — данные от HID-устройства (Human Interface Device), например, джойстика, графического планшета или педали.- dwSize — общий размер структуры
RAWINPUTв байтах. - hDevice — дескриптор устройства, с которого получены данные. Этот дескриптор можно использовать для вызова функций
GetRawInputDeviceInfoдля получения дополнительной информации об устройстве. - wParam — дополнительный параметр, обычно равен нулю, но может содержать флаги, например,
RIM_INPUT(0) илиRIM_INPUTSINK(1).
¶Поле data
Поле data является объединением (union) трёх структур, каждая из которых соответствует типу устройства:
¶RAWMOUSE
Используется, когда header.dwType равен RIM_TYPEMOUSE. Содержит следующие поля:
- usFlags — флаги состояния мыши, такие как
MOUSE_MOVE_RELATIVE(относительное движение) илиMOUSE_MOVE_ABSOLUTE(абсолютное движение, например, для планшетов). - ulButtons — битовая маска, указывающая, какие кнопки мыши были нажаты или отпущены.
- usButtonFlags — флаги, описывающие конкретные события кнопок (например,
RI_MOUSE_BUTTON_1_DOWN). - ulRawButtons — необработанное состояние кнопок (если поддерживается устройством).
- lLastX и lLastY — координаты мыши (относительные или абсолютные).
- ulExtraInformation — дополнительные данные, зависящие от устройства.
¶RAWKEYBOARD
Используется, когда header.dwType равен RIM_TYPEKEYBOARD. Содержит:
- MakeCode — скан-код клавиши (аппаратный код, генерируемый клавиатурой).
- Flags — флаги, например,
RI_KEY_MAKE(нажатие) илиRI_KEY_BREAK(отпускание). - Reserved — зарезервировано, обычно равно нулю.
- VKey — виртуальный код клавиши (Windows-совместимый код).
- Message — сообщение Windows, соответствующее событию (например,
WM_KEYDOWN). - ExtraInformation — дополнительные данные.
¶RAWHID
Используется, когда header.dwType равен RIM_TYPEHID. Эта структура является универсальной для всех HID-устройств и содержит:
- dwSizeHid — размер одного HID-отчёта в байтах.
- dwCount — количество HID-отчётов в буфере.
- bRawData — массив байтов, содержащий необработанные данные от устройства. Формат данных зависит от конкретного устройства и его HID-дескриптора.
¶Применение
Структура RAWINPUT используется в следующих сценариях:
- Игровая разработка: для получения данных от мыши с высокой частотой опроса (например, 1000 Гц) и минимизации задержки, что критично для шутеров от первого лица.
- Профессиональные приложения: для поддержки многокнопочных мышей, графических планшетов и 3D-контроллеров (например, SpaceMouse).
- Системное программирование: для мониторинга и логирования всех входных событий в системе (например, кейлоггеры или программы для автоматизации).
- Поддержка нестандартных устройств: для работы с HID-устройствами, которые не генерируют стандартные сообщения Windows (например, педали для симуляторов или джойстики с обратной связью).
¶Пример использования
Для получения данных через RAWINPUT приложение должно:
- Зарегистрировать устройство с помощью функции
RegisterRawInputDevices, указав тип устройства и флаги. - В цикле обработки сообщений Windows обрабатывать сообщение
WM_INPUT, которое содержит указатель на структуруRAWINPUT. - Извлечь структуру с помощью функции
GetRawInputData, передавRID_INPUTв качестве параметра. - Проанализировать поля
header.dwTypeи соответствующую часть объединенияdata.
Пример кода на C++:
``cpp case WM_INPUT: { UINT dwSize; GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &dwSize, sizeof(RAWINPUTHEADER)); RAWINPUT raw = (RAWINPUT)malloc(dwSize); GetRawInputData((HRAWINPUT)lParam, RID_INPUT, raw, &dwSize, sizeof(RAWINPUTHEADER)); if (raw->header.dwType == RIM_TYPEMOUSE) { // Обработка данных мыши } free(raw); break; } ``
¶Ограничения и особенности
- Производительность: использование Raw Input может увеличить нагрузку на процессор, так как данные обрабатываются на уровне приложения, а не через стандартную очередь сообщений.
- Безопасность: в некоторых версиях Windows (например, Windows Vista и выше) для получения данных от всех устройств (в том числе в фоновом режиме) требуется флаг
RIDEV_INPUTSINK, который может быть ограничен правами администратора. - Совместимость: не все устройства поддерживают Raw Input; старые драйверы могут не генерировать соответствующие HID-отчёты.
- Многопоточность: структура
RAWINPUTне является потокобезопасной; при обработке в нескольких потоках необходимо использовать синхронизацию.
¶Источники
- Microsoft Docs: «RAWINPUT structure» (Windows Dev Center)
- Microsoft Docs: «Using Raw Input» (Windows Dev Center)
- Charles Petzold, «Programming Windows», 5th edition, Chapter 14: «Raw Input»
- MSDN Magazine, «Raw Input in Windows XP» (2002)
BFOmetr — база данных и аналитика по компаниям России.
На главную BFOmetr →


