Проблема с поиском символов GetRawInputData при настройке другого языка

#c# #.net #keyboard-events #raw-input

#c# #.net #клавиатура-события #необработанный ввод

Вопрос:

Я использую GetRawInputData для поиска данных считывателя штрих-кодов. https://github.com/mfakane/rawinput-sharp

Когда я считываю штрих-код со своего сканера штрих-кодов, он обычно получает правильные символы как на rawinput, так и на экране ПК. На рисунке ниже показан правильный сценарий.

Режим настройки языка США

Моя проблема в том, что если я изменю языковые настройки сканера штрих-кодов на Turkey, rawinput получит дополнительные символы, как показано на рисунке ниже.

Режим настройки языка индейки

Если кто-то раньше использовал библиотеку RawInput, пожалуйста, помогите мне объяснить, почему это происходит, и мне нужна идея о том, как анализировать данные точно так же, как ПК получает изображения.

Ответ №1:

Я меняю языковые настройки сканера штрих-кодов на турецкие

Я не совсем понимаю, что вы подразумеваете под этим. Также я не знаю, какой именно тип устройства HID реализует ваш сканер штрих-кода.

Если мы говорим о RIM_TYPEKEYBOARD данных (СКРЫТАЯ страница использования 0x01, идентификатор использования 0x06) — необработанный ввод Windows API сам по себе не предоставляет никаких символов.

WM_INPUT дает вам PS / 2 scancode ключа (в RAWKEYBOARD.MakeCode , он фактически преобразуется с помощью KBDHID.sys в соответствии с этой таблицей) и VK_* код ключа (в RAWKEYBOARD.VKey поле).

Эти нажатия могут быть сопоставлены с символами с помощью вызова ToUnicode API. В качестве входных данных требуется код сканирования, код vk и состояние клавиатуры (которое содержит, например, состояние CAPSLOCK и SHIFT). Он будет преобразован на основе активной раскладки клавиатуры потока вызывающих абонентов. Если вам нужна другая раскладка клавиатуры, вы можете использовать ToUnicodeEx с дополнительным параметром HKL dwhkl .

Правильное использование ToUnicode / ToUnicodeEx сложно, потому что оно может выдавать несколько символов при одном нажатии клавиши. Также там могут быть мертвые ключи…

Но для простого случая это может быть что-то вроде этого:

 wchar_t VkToChar(uint16_t vk, bool isShift = false)
{
    uint16_t sc = MapVirtualKeyW(vk, MAPVK_VK_TO_VSC);
    const uint32_t flags = 1 << 2; // Do not change keyboard state of this thread

    static uint8_t state[256] = { 0 };
    state[VK_SHIFT] = isShift << 7; // Modifiers set the high-order bit when pressed

    wchar_t unicodeChar;
    if (ToUnicode(vk, sc, state, amp;unicodeChar, 1, flags) != 1)
        return L'';

    if (!std::iswprint(unicodeChar))
        return L'';

    return unicodeChar;
}