Открыть сервис

Структура 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 приложение должно:

  1. Зарегистрировать устройство с помощью функции RegisterRawInputDevices, указав тип устройства и флаги.
  2. В цикле обработки сообщений Windows обрабатывать сообщение WM_INPUT, которое содержит указатель на структуру RAWINPUT.
  3. Извлечь структуру с помощью функции GetRawInputData, передав RID_INPUT в качестве параметра.
  4. Проанализировать поля 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 →