#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;
}