Как преобразовать структуру RawInput RAWKEYBOARD в константу DirectInput DIK_?

Я конвертирую приложение, которое в настоящее время использует DirectInput, для использования RawInput. (DirectInput — это в значительной степени устаревший API.)

К сожалению, несмотря на то, что RawInput является рекомендуемым преемником DirectInput, похоже, что он не предоставляет данные клавиатуры таким же образом, как DirectInput.

DirectInput использует константы DIK_*. (например, DIK_A, DIK_RETURN и т. д.), чтобы определить конкретные физические клавиши на клавиатуре. Эти клавиши одинаковы для всех клавиатур, но не меняются в зависимости от раскладки клавиатуры. (Например, DIK_Q относится к любой клавише, которая находится в том же физическом месте, что и клавиша Q на стандартной американо-английской клавиатуре QWERTY.) В моем случае это желаемое поведение.

Структура RawInput RAWKEYBOARD обеспечивает как MakeCode, так и VKey. Я не могу использовать VKey, потому что это зависит от раскладки клавиатуры.

Но MakeCode не соответствует 1:1 константам DIK_*. В частности, он не различает левую и правую клавиши Ctrl и Alt, а также большинство клавиш цифровой клавиатуры от других клавиш.

Итак, мой вопрос: можно ли использовать содержимое структуры RAWKEYBOARD для определения эквивалентной константы DIK_*? И если предположить, что MakeCode является частью выяснения этого, могу ли я полагаться на то, что MakeCode будет постоянным для всех клавиатур, так же, как константы DIK_*?


person Walt D    schedule 11.05.2016    source источник
comment
Лучший способ получить данные клавиатуры для настольного приложения Windows — просто использовать сообщения Windows. Ввод RAW полезен для относительного движения мыши, но это все. Примеры этого см. в разделах Keyboard и Мышь в Наборе инструментов DirectX   -  person Chuck Walbourn    schedule 12.05.2016
comment
@ChuckWalbourn Поправьте меня, если я ошибаюсь, но, похоже, используются те же виртуальные ключи, что и RawInput?   -  person Walt D    schedule 12.05.2016
comment
Я использую виртуальные ключи для реализации Keyboard, что и сделала XNA Game Studio. Да, раскладки меняются, но, вообще говоря, единственным решением для международных клавиатур является предоставление нескольких различных параметров раскладки и/или меню конфигурации переназначения (я отмечаю это на wiki).   -  person Chuck Walbourn    schedule 12.05.2016
comment
Обратите внимание, что вы можете использовать GetKeyNameText, чтобы получить имя данного ключа.   -  person Chuck Walbourn    schedule 12.05.2016
comment
Вы можете использовать RAWKEYBOARD.VKey, номера виртуальных клавиш не зависят от раскладки клавиатуры. Поэтому они виртуальные. Значения VK_xxxx являются однозначным сопоставлением со значениями DIK, вам просто нужна таблица поиска.   -  person Hans Passant    schedule 12.05.2016
comment
@HansPassant Только что протестировано, и значения VK_ меняются, когда я меняю раскладку клавиатуры в Windows, а DIK_ — нет. В моем конкретном случае мне нужно поведение DIK_. VK_ полезен, когда важна буква, напечатанная на клавише (например, ярлыки), тогда как DIK_ полезен, когда положение клавиши наиболее важно (например, движение WASD в играх).   -  person Walt D    schedule 12.05.2016
comment
Я позвоню этому, это просто невозможно. Все, на что вы смотрите, не является ценностями ВКонтакте. Раскладка клавиатуры используется только в ToUnicodeEx() для преобразования значений VK в символы. Обычно используемая Windows для преобразования сообщения WM_KEYDOWN в сообщение WM_CHAR, функция winapi TranslateMessage делает это.   -  person Hans Passant    schedule 12.05.2016
comment
@HansPassant Нет, значения DIK определенно не могут быть сопоставлены 1: 1 со значениями VK. Я так понимаю, в этом весь смысл моего вопроса? Мне просто кажется странным, что устаревший API, такой как DirectInput, предоставляет важную функцию, которую не поддерживает его предполагаемый преемник?   -  person Walt D    schedule 12.05.2016
comment
@HansPassant Почему ты говоришь, что я делаю это неправильно? Я использую хорошо понятное поведение DirectInput, которое я хотел бы воспроизвести с помощью RawInput. Я чувствую, что у нас просто какое-то недопонимание о том, что именно я пытаюсь сделать? В любом случае, я мог бы найти решение, которое я опубликовал в качестве ответа ниже.   -  person Walt D    schedule 12.05.2016


Ответы (1)


Я не уверен на 100%, что это надежно на всех аппаратных средствах клавиатуры, но кажется, что я могу использовать поля MakeCode и Flags (в частности, флаги RI_KEY_E0 и RI_KEY_E1) RAWKEYBOARD, чтобы определить фактическую физическую клавишу, которая была нажата или отпущена, и сопоставьте это с константой DIK_. Я использовал эту таблицу, чтобы определить большинство коды создания/сканирования для отдельных ключей, а затем эксперименты, чтобы выяснить коды сканирования/изготовления и флаги для остальных ключей.

Я протестировал это на четырех разных клавиатурах, и все они производят одинаковые коды / флаги: 2 USB-клавиатуры, клавиатура PS/2 и встроенная клавиатура на Macbook с запущенным bootcamp.

Мне бы хотелось получить документальное подтверждение того, что я могу полагаться на то, что код make и флаги будут согласованы на всех клавиатурах, но пока это работает нормально.

person Walt D    schedule 12.05.2016