Alexander Chef
Alexander Chef

Reputation: 388

GetRawInputData sniffing character problem on different language setting

I'm using GetRawInputData for sniffing barcode reader data. https://github.com/mfakane/rawinput-sharp

When I read a barcode from my barcode scanner normally it gets the right characters both rawinput and pc screen. Below image shows right scenario.

USA Language Setting Mode

My problem is, if I change the language settings of the barcode scanner to Turkey, rawinput gets additional characters like below image.

Turkey Language Setting Mode

If somebody used RawInput library before, please help me about why this is happening and I need an idea about how to sniff the data exactly like pc gets like the images.

Upvotes: 0

Views: 232

Answers (1)

DJm00n
DJm00n

Reputation: 1441

I change the language settings of the barcode scanner to Turkey

I don't quite understand what do you mean by this. Also I don't know which exactly HID device type your barcode scanner is implementing.

If we talk about RIM_TYPEKEYBOARD data (HID Usage Page 0x01, Usage Id 0x06) - Raw Input Windows API doesn't provide any characters by itself.

WM_INPUT gives you PS/2 scancode of the key (in RAWKEYBOARD.MakeCode, it is actually converted by KBDHID.sys driver from HID Usages according to this table) and VK_* code of the key (in RAWKEYBOARD.VKey field).

These presses could be mapped to characters by the call to ToUnicode API. It needs as input - scan code, vk code and keyboard state (which contains for example CAPSLOCK and SHIFT state). It will convert based on active keyboard layout of callers thread. If you need other keyboard layout then you can use ToUnicodeEx that have additional parameter HKL dwhkl.

Proper use of ToUnicode/ToUnicodeEx is tricky because it could emit several characters on a single key press. Also there there could be dead keys...

But for simple case it could be something like this:

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, &unicodeChar, 1, flags) != 1)
        return L'\0';

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

    return unicodeChar;
}

Upvotes: 0

Related Questions