Работа с USB-сканером штрих-кода, выполняющим функции клавиатуры, с заголовком / трейлерами из любой точки формы - PullRequest
0 голосов
/ 16 декабря 2010

В приложении winforms мне нужно прочитать ввод со стандартного USB-сканера штрих-кода, который делает себя в виде USB-клавиатуры для Windows.Это должно работать без акцентирования внимания на конкретном элементе управления (т. Е. Я не могу сказать «нажмите на это текстовое поле, а затем отсканируйте штрих-код»).Сканер настроен на вывод заголовка и трейлера для каждого кода, который он сканирует.

Я бы предпочел не идти «сырым» путем, то есть подключаться непосредственно к входу USB или событиям Windows (WM_INPUTтакие).

Я, конечно, могу перехватывать нажатия клавиш в ProcessCmdKey, но тогда мне кажется, что я не могу правильно определить ключи для заголовка / трейлера (^ ~ {и} ~ ^ соответственно).

Есть идеи, как это можно сделать правильно в управляемом коде?

Ответы [ 3 ]

3 голосов
/ 17 декабря 2010

Это работает, но довольно уродливо:

    [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);
    }
0 голосов
/ 16 декабря 2010

может быть текстовое поле, скрытое панелью, которое получает фокус при сканировании штрих-кода, а затем использует событие keydown, которое должно получить необработанные значения ascii символов, отправленных сканером

0 голосов
/ 16 декабря 2010

ProcessCmdKey - правильное место, чтобы сделать это.

...