开发者

Handling USB Barcode Scanner acting as a keyboard, with header/trailers from anywhere on the form

开发者 https://www.devze.com 2023-01-31 04:07 出处:网络
In a winforms app, I need to read input from a standard USB barcode scanner, one whichmakes iteself appears as a USB keyboard to windows. This has to work without giving focus to a particular control

In a winforms app, I need to read input from a standard USB barcode scanner, one which makes iteself appears as a USB keyboard to windows. This has to work without giving focus to a particular control (ie, I can't say "click on this textbox then scan the barcode"). The scanner is configured to output a header and trailer to every codes it scans.

I'd rather don't go the "raw开发者_StackOverflow社区" way, ie, hooking directly into the USB input or Windows events (WM_INPUT and such).

I can of course trap the keystrokes in ProcessCmdKey, but then I don't seem to be able to properly identify the keys for the header/trailer (^~{ and }~^ respectively).

Any idea how this can be done properly in managed code?


This works, but it's kinda ugly:

    [DllImportAttribute("User32.dll")]
    public static extern int ToAscii(int uVirtKey, int uScanCode, byte[] lpbKeyState, byte[] lpChar, int uFlags);

    [DllImportAttribute("User32.dll")]
    public static extern int GetKeyboardState(byte[] pbKeyState);

    public static char GetAsciiCharacter(int uVirtKey, int uScanCode)
    {
        byte[] lpKeyState = new byte[256];
        GetKeyboardState(lpKeyState);
        byte[] lpChar = new byte[2];
        if (ToAscii(uVirtKey, uScanCode, lpKeyState, lpChar, 0) == 1)
            return (char)lpChar[0];
        else
            return new char();
    }

    protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
    {
        if(keyData == Keys.ShiftKey || keyData == Keys.Shift)
            return base.ProcessCmdKey(ref msg, keyData);

        char keyChar = GetAsciiCharacter((int) (keyData & Keys.KeyCode), (((int) msg.LParam) & 0x1000000));

        if(keyChar == '\0')
            return base.ProcessCmdKey(ref msg, keyData);

        _currentSequence.Add(keyChar);

        if (_currentSequence.ToString() == "^~{")
        {
            _handlingInputFromScanner = true;
            _scannerBuffer.Clear();
            return true;
        }

        if (_currentSequence.ToString() == "}~^")
        {
            _handlingInputFromScanner = false;
            OnScannerRead.Invoke(this, new ScannerReadEventArgs { ScannerData = _scannerBuffer.ToString() });
            _scannerBuffer.Clear();
            return true;
        }

        if (keyChar == '}' || keyChar == '{' || keyChar == '~' || keyChar == '^')
        {
            return true;
        }

        if (_handlingInputFromScanner)
        {
            _scannerBuffer.Append(keyChar);
            return true;
        }

        return base.ProcessCmdKey(ref msg, keyData);
    }


ProcessCmdKey is the right place to do it.


maybe a textbox hidden by a panel, that gets focus when the barcode is to be scanned, and then use the keydown event, that should get you the raw ascii values of the characters sent by the scanner

0

精彩评论

暂无评论...
验证码 换一张
取 消