2010-12-16 21 views
0

In einer Winforms-App, muss ich die Eingabe von einem Standard-USB-Barcode-Scanner lesen, die als Windows-Tastatur erscheint. Dies muss funktionieren, ohne den Fokus auf ein bestimmtes Steuerelement zu legen (dh ich kann nicht sagen "klicke auf dieses Textfeld und scanne dann den Barcode"). Der Scanner ist so konfiguriert, dass er für jeden gescannten Code einen Header und einen Trailer ausgibt.Handhabung USB-Barcode-Scanner als eine Tastatur, mit Header/Anhänger von überall auf dem Formular

Ich würde lieber nicht den "rohen" Weg gehen, dh direkt in den USB-Eingang oder Windows-Ereignisse (WM_INPUT und so weiter) einhängen.

Ich kann natürlich die Tastenanschläge in ProcessCmdKey abfangen, aber dann scheint ich nicht in der Lage zu sein, die Schlüssel für den Header/Trailer (^ ~ {und} ~ ^) richtig zu identifizieren.

Haben Sie eine Idee, wie dies im verwalteten Code richtig gemacht werden kann?

+1

Sie haben den falschen Scanner gekauft. Holen Sie sich eine, die sich wie eine serielle Schnittstelle verhält. –

+0

Keine Kontrolle darüber; es gibt schon ~ 30 (verschiedene Modelle/Marken, aber alle USB und alle programmierbar, soweit Header/Trailer geht; nicht alle unterstützen den seriellen Modus) Scanner gekauft und in Gebrauch (in einer anderen App). –

Antwort

0

ProcessCmdKey ist der richtige Ort dafür.

+0

Aber wie kann ich dann sagen "^"? Ich habe in ProcessCmdKey nichts Sinnvolles zu erkennen bekommen. –

+0

Die Nachricht, nach der Sie suchen, ist WM_CHAR (0x0102). http://msdn.microsoft.com/en-us/library/ms646276.aspx – Tergiver

0

vielleicht eine Textbox von einem Panel versteckt, das dem Fokus erhält, wenn der Barcode, abgetastet werden soll und dann das KeyDown-Ereignis verwenden, das sollte man den rohen ascii-Wert des Zeichens durch den Scanner Diesen

+0

Funktioniert nicht, weil "wenn der Barcode gescannt werden soll" jederzeit in beliebiger Reihenfolge sein kann. Dies ist eine vielbeschäftigte Form, viel passiert dort. –

+0

Entschuldigung! Ich habe irgendwie das "kann nicht" in dem Bit über die Textbox verpasst – KutscheraIT

3

geschickt bekommen funktioniert, aber es ist irgendwie hässlich:

[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); 
    }