Raw Input
Raw Input — это механизм операционной системы Microsoft Windows для прямого доступа к данным с устройств ввода (клавиатура, мышь, джойстик, сенсорная панель и другие HID-совместимые устройства) без промежуточной обработки и фильтрации стандартными очередями сообщений (Windows message queue). В отличие от традиционных методов работы с вводом через сообщения WM_KEYDOWN, WM_MOUSEMOVE или WM_INPUT, Raw Input позволяет приложению получать необработанные данные непосредственно от драйвера устройства, что обеспечивает более низкую задержку, точность и возможность обработки данных, недоступных в обычном потоке.
История
Механизм Raw Input был впервые представлен в операционной системе Microsoft Windows XP с выходом Service Pack 1 (2002 год) и стал частью DirectInput API в составе DirectX 8.1. До появления Raw Input разработчики игр и специализированных приложений (например, симуляторов, профессиональных графических редакторов) сталкивались с ограничениями стандартной модели ввода: сообщения мыши и клавиатуры подвергались фильтрации (например, сглаживание движения мыши через параметр ускорения, заданный в настройках системы), а доступ к данным с джойстиков и других HID-устройств требовал использования DirectInput или API коммуникационных портов (COM-порт, LPT).
С выходом Windows Vista (2006) и Windows 7 (2009) поддержка Raw Input была расширена: появилась возможность регистрации устройств с различной топологией (например, нескольких мышей или клавиатур одновременно), а улучшенная документация MSDN и примеры кода на C++ упростили внедрение. Начиная с Windows 8 (2012) механизм стал основным способом работы с вводом для приложений, требующих высокой отзывчивости (в первую очередь — видеоигр). В Windows 10 и 11 Raw Input остаётся обратно совместимым с более ранними версиями и поддерживается для всех HID-классов.
Принцип работы
Отличие от стандартного ввода
Стандартный ввод в Windows работает через оконную очередь сообщений: каждое нажатие клавиши или движение мыши генерирует сообщение (например, WM_KEYDOWN), которое помещается в очередь потока, создавшего окно. При этом Windows может модифицировать данные: округлять координаты мыши, накладывать системное ускорение, удалять повторяющиеся нажатия (ключевой режим повтора) или преобразовывать скан-коды в виртуальные ключи с учётом раскладки. Эти модификации могут приводить к потере информации и дополнительной задержке.
Raw Input регистрирует устройство напрямую через API. Приложение получает данные в виде сырого пакета (структура RAWINPUT) через сообщение WM_INPUT. Обработка пакета происходит в произвольном порядке, вне очереди оконных сообщений, что снижает задержку до минимально возможной. При этом данные не фильтруются: приложение получает, например, абсолютное положение курсора или сырой скан-код клавиши (без раскладки).
Основные функции API
Windows предоставляет следующие функции для работы с Raw Input:
- RegisterRawInputDevices — регистрация устройства для получения сырых данных. Приложение указывает HID-тип (RIM_TYPEHID, RIM_TYPEKEYBOARD, RIM_TYPEMOUSE), идентификатор устройства (через VID/PID или топологию) и флаги. Регистрация может быть глобальной (все устройства) или специфичной (конкретная модель).
- GetRawInputData — извлекает необработанные данные из переданного сообщения WM_INPUT. Принимает дескриптор сообщения (содержащий указатель на пакет) и возвращает структуру RAWINPUT.
- GetRawInputDeviceInfo — получает информацию о зарегистрированном устройстве (имя, производитель, HID-дескриптор). Позволяет отличить одну мышь от другой или определить тип джойстика.
- GetRegisteredRawInputDevices — перечисляет все зарегистрированные для текущего потока устройства.
Структура RAWINPUT
Структура RAINPUT содержит заголовок (RAWINPUTHEADER) с идентификатором устройства, типом (мышь, клавиатура или HID) и полем размера пакета. Далее следуют структуры в зависимости от типа:
- Для мыши (RAWMOUSE): координаты перемещения (ulRawButtons, usFlags), абсолютное положение (lLastX, lLastY), информация о колёсике (usButtonFlags) и кнопках.
- Для клавиатуры (RAWKEYBOARD): скан-код (MakeCode), флаги (например, нажатие или отпускание), виртуальный код (VKey) и сообщение (WM_KEYDOWN / WM_KEYUP).
- Для HID-устройств: массив сырых байт (bRawData), который приложение интерпретирует в соответствии с HID-дескриптором.
Классификация
По типу устройств
- Мыши — Raw Input позволяет получить необработанное перемещение без ускорения и сглаживания, а также данные с колёсика и дополнительных кнопок (например, боковые). Часто используется в игровых жанрах, требующих точного прицеливания (шутеры от первого лица, стратегии в реальном времени).
- Клавиатуры — даёт сырые скан-коды, позволяя игнорировать раскладку и обрабатывать многоклавишные сочетания (например, в симуляторах полёта). Также передаёт информацию о нажатии/отпускании без задержки повтора.
- HID-устройства — джойстики, рули, педали, сенсорные панели, считыватели штрих-кодов. Приложение принимает сырой поток байт, структура которого задана в HID-дескрипторе устройства. Это даёт полный доступ к всем возможностям, включая силы обратной связи (force feedback) через дополнительные API.
По способу регистрации
- Глобальная регистрация (флаги RIDEV_INPUTSINK и RIDEV_NOLEGACY) — приложение получает данные от всех устройств данного типа, даже если окно неактивно или свернуто. Используется в фоновых утилитах (например, для макросов или мониторинга ввода).
- Целевая регистрация — приложение регистрирует одно конкретное устройство, указав его VID/PID. Позволяет различать две мыши или клавиатуры, подключенные одновременно.
Применение
Видеоигры
Raw Input является стандартом де-факто для современных игр, особенно шутеров от первого лица (например, Counter-Strike: Global Offensive, Quake Champions, Overwatch). Отсутствие системного ускорения мыши обеспечивает предсказуемость и точность, что критично для соревновательной игры. Многие игровые движки (Unreal Engine, Unity, id Tech) имеют встроенную поддержку Raw Input.
Симуляторы и профессиональные приложения
- Авиасимуляторы (Microsoft Flight Simulator, X-Plane) используют Raw Input для обработки джойстиков, рулей и педалей, получая полные данные об осях (например, 16-битный диапазон вместо стандартных 8).
- Программы 3D-моделирования (Autodesk Maya, Blender, ZBrush) — для точного управления кистями и инструментами через планшет (HID-перо) без дополнительного сглаживания.
- Медицинские и научные приложения — для обработки данных с устройств ввода высокой точности (задающих координаты в микро- или нанометровом диапазоне).
Специализированные системы
- Утилиты автоматизации (AutoHotkey, Pulover’s Macro Creator) используют Raw Input для захвата данных с нескольких клавиатур одновременно.
- Программы тестирования и диагностики (например, HID Logger) анализируют сырой поток HID-пакетов для отладки оборудования.
- Системы безопасности — для захвата нажатий клавиш из режима ядра (например, в криптографических библиотеках), что снижает риск перехвата через шпионское ПО.
Ограничения и недостатки
- Сложность реализации — по сравнению с обработкой стандартных сообщений Windows (WM_KEYDOWN) код работы с Raw Input более объёмный: требуется регистрация устройств, обработка WM_INPUT, извлечение данных через GetRawInputData и интерпретация сырых байт для HID-устройств. Это может быть избыточно для простых приложений (например, текстового редактора).
- Не полностью обходит системные модификации — хотя мышиный ввод освобождается от ускорения, клавиатурный ввод всё равно может подвергаться преобразованию раскладки через функцию MapVirtualKey, если приложение не обрабатывает скан-коды напрямую.
- Совместимость — механизм доступен только в операционной системе Windows. Кроссплатформенные игры и приложения, работающие также под Linux и macOS, используют другие API (например, EVDEV, IOKit), что требует отдельной реализации.
- Потребление ресурсов — если приложение регистрирует глобальный захват (RIDEV_INPUTSINK), оно может потреблять дополнительное время процессора для обработки каждого пакета, что при высокой частоте опроса (1000 Гц и выше) влияет на производительность системы в целом.
Пример использования
На практике разработчик игры на C++ обычно выполняет следующие шаги:
- Ввод структуры RAWINPUTDEVICE и вызов RegisterRawInputDevices с указанием типа устройства (например, RIM_TYPEMOUSE).
- В оконной процедуре (WndProc) обработка сообщения WM_INPUT.
- Вызов GetRawInputData для получения данных в структуру RAINPUT.
- Для мыши: чтение lLastX и lLastY как сырое перемещение (разница позиций между кадрами). Для клавиатуры: чтение MakeCode и определение нажатия/отпускания.
Источники
- Microsoft Docs. «Raw Input». Documentation for Windows App Development.
- Microsoft Docs. «About Raw Input». Remarks and examples.
- Charles Petzold. «Programming Windows» (5th Edition), глава 12 — Raw Input.
- DirectInput documentation for Windows (MSDN), разделы RegisterRawInputDevices и GetRawInputData.
- «Game Input Programming in Windows 10» — статья на GameDev.net (авторы: Michael D., 2021).
- Rusty Wagner. «Understanding Raw Input in Windows» — вики BYOND (2018).
BFOmetr — база данных и аналитика по компаниям России.
На главную BFOmetr →