1

winforms アプリでは、標準の USB バーコード スキャナーからの入力を読み取る必要があります。これにより、自分自身が USB キーボードとして Windows に表示されます。これは、特定のコントロールにフォーカスを与えずに機能する必要があります (つまり、「このテキスト ボックスをクリックしてからバーコードをスキャンする」とは言えません)。スキャナーは、スキャンするすべてのコードにヘッダーとトレーラーを出力するように構成されています。

私はむしろ「生の」方法、つまり、USB 入力または Windows イベント (WM_INPUT など) に直接フックすることはしたくありません。

もちろん、ProcessCmdKey でキーストロークをトラップすることはできますが、ヘッダー/トレーラーのキー (それぞれ ^~{ と }~^) を正しく識別できないようです。

マネージド コードでこれを適切に行う方法はありますか?

4

3 に答える 3

3

これは機能しますが、ちょっと醜いです:

    [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);
    }
于 2010-12-16T22:24:46.613 に答える
0

ProcessCmdKey は、それを行うのに適した場所です。

于 2010-12-16T18:29:07.113 に答える
0

おそらく、バーコードがスキャンされるときにフォーカスを取得するパネルによって隠されているテキストボックスであり、スキャナーによって送信された文字の生のASCII値を取得する必要があるkeydownイベントを使用します

于 2010-12-16T18:29:32.027 に答える