2010-12-16 1 views
0

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

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

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

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

+1

Вы купили неправильный сканер. Получите тот, который действует как последовательный порт. – 2010-12-16 20:40:05

+0

Отсутствие контроля над этим; есть уже ~ 30 (разные модели/бренды, но все USB и все программируемые, насколько заголовок/трейлер идет, но не все они поддерживают серийный режим, хотя) сканеры покупаются и используются (в другом приложении). – 2010-12-16 20:50:12

ответ

0

ProcessCmdKey - это подходящее место для этого.

+0

Но тогда как я могу идентифицировать себя, скажем, «^»? Кажется, я не вижу в ProcessCmdKey ничего значимого, чтобы идентифицировать это. – 2010-12-16 18:36:37

0

может быть текстовое поле скрыты панелями, которая получает фокус, когда штрих-код для сканирования, а затем использовать KeyDown события, что вы должны получить исходные значения ASCii персонажей, посланных сканер

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