2009-02-25 118 views
19

我有一個條形碼掃描器(就像一個鍵盤),當然我也有一個鍵盤連接到計算機。該軟件正在接受來自掃描儀和鍵盤的輸入。我只需要接受掃描儀的輸入。代碼是用C#編寫的。有沒有辦法從鍵盤「禁用」輸入,只接受來自掃描儀的輸入?如何區分C#中的多個輸入設備

說明: 鍵盤是筆記本電腦的一部分...所以它不能拔掉。此外,我試着把下面的代碼 保護重寫布爾ProcessDialogKey(System.Windows.Forms.Keys keyData) { return true; } 但是,隨着忽略鍵盤的擊鍵,條形碼掃描儀輸入也被忽略。

我不能讓掃描儀發送正面字符,掃描儀正在被其他應用程序使用,並且添加正面字符流意味着要修改其他代碼。

此外,由於掃描的條形碼可能是單字符條形碼,因此我無法使用計時方法來確定輸入是否來自條形碼掃描儀(如果其中一串字符後跟暫停)。

是的,我正在讀取流中的數據。

我想跟着文章:從WinForms中的鍵盤區分條形碼掃描儀。不過,我有以下問題:

  1. 我收到一個錯誤NativeMethods由於其保護級別而無法訪問。看起來好像我需要導入一個dll;它是否正確?如果是這樣,我該怎麼做?
  2. 哪個保護覆蓋無效WndProc(ref消息m)定義應該使用,在文章中有兩個實現?
  3. 我得到一個與[SecurityPermission(SecurityAction.LinkDemand,Flags = SecurityPermissionFlag.UnmanagedCode)]錯誤相關的錯誤CS0246:無法找到類型或名稱空間名稱'SecurityPermission'(您是否缺少using指令或程序集引用? )。我如何解決這個錯誤?如果((從hardwareId中hardwareId其中deviceName.Contains(hardwareId)選擇hardwareId).Count()> 0)錯誤是錯誤CS1026:)期望。錯誤是錯誤的CS1026:)期望。
  4. 我應該將文章中的所有代碼放在一個名爲BarcodeScannerListener.cs的.cs文件中嗎?

關於C#的解決方案的源代碼後續問題發表尼古拉斯·皮亞塞茨基在http://nicholas.piasecki.name/blog/2009/02/distinguishing-barcode-scanners-from-the-keyboard-in-winforms/

  1. 我沒能在VS 2005中打開該解決方案,所以我下載的Visual C#2008 Express版本,並且代碼跑了。但是,在連接我的條形碼掃描儀並掃描條形碼後,程序無法識別掃描。我在OnBarcodeScanned方法中放置了一個斷點,但它從未被擊中。我確實使用設備管理器獲得的條形碼掃描器的ID更改了App.config。似乎有2個設備名與HID#Vid_0536 & Pid_01c1(從掃描儀連接時從設備管理器獲得)。我不知道這是否導致掃描不起作用。當遍歷deviceNames時,下面是我找到的設備列表(使用調試器):

「\?\ HID#Vid_0536 & Pid_01c1 & MI_01#9 & 25ca5370 0000#{4d1e55b2-F16F-11CF-88cb-001111000030} 「

」 \ ?? \ HID#Vid_0536 & Pid_01c1 & MI_00#9 & 38e10b9 0000#{884b96c3-56ef-11D1-bc8c-00a0c91405dd} 「

」 \ ?? \ HID#Vid_413c & Pid_2101 & MI_00#8 & 1966e83d 0000#{884b96c3-56ef-11D1-bc8c- 00a0c914 05dd} 「

」\ ?? \ HID#Vid_413c & Pid_3012#7 & 960fae0 0000#{378de44c-56ef-11D1-bc8c-00a0c91405dd}「
」 \ ?? \根#RDP_KBD#0000 #{884b96c3-56ef-11D1-bc8c-00a0c91405dd} 「 」\ ?? \ ACPI#PNP0303#4 & 2f94427b & 0#{884b96c3-56ef-11D1-bc8c-00a0c91405dd}「 」 \ ?? \根#RDP_MOU #0000#{378de44c-56ef-11D1-bc8c-00a0c91405dd}」 「\ ?? \ ACPI#PNP0F13#4 & 2f94427b & 0#{378de44c-56ef-11D1-bc8c-00a0c91405dd}」

所以有2個條目爲HID#Vid_0536 & Pid_01c1;可能導致掃描不起作用?

好吧,所以我似乎不得不找出一種方法,不依賴於掃描儀發送的ASCII 0x04字符...因爲我的掃描儀不發送該字符。之後,條形碼掃描事件將被觸發並顯示帶有條形碼的彈出窗口。所以謝謝尼古拉斯的幫助。

+0

拔下鍵盤。 – TheTXI 2009-02-25 21:09:16

+0

我在文章底部添加了一個示例代碼發佈。祝你好運! – 2009-02-28 00:11:21

+1

@NicholasPiasecki已經6年了,但仍然 - 爲什麼HTTP 410? – itsho 2015-10-24 21:00:25

回答

15

You could use the Raw Input API to distinguish between the keyboard and the scanner like I did recently.無論你連接了多少鍵盤或類似鍵盤的設備,在按鍵映射到通常在KeyDown事件中看到的與設備無關的虛擬鍵之前,您會看到一個WM_INPUT

更容易的是做其他人推薦的配置,並配置掃描儀在條形碼之前和之後發送哨兵字符。 (通常通過掃描掃描儀用戶手冊後面的特殊條形碼來完成此操作。)然後,如果主窗體處於讀取條形碼的中間,則主窗體的事件可以監視那些卷軸結束併吞下任何子控件的按鍵事件。或者,如果您想更有趣,可以使用SetWindowsHookEx()的低級鍵盤鉤來觀看那些哨兵並將它們吞下(這樣做的好處是即使您的應用程序沒有焦點,您仍然可以獲得該事件) 。

我無法改變我們的條形碼掃描儀的哨兵價值等因素,所以我不得不去複雜的路線。絕對是痛苦的。如果可以的話,保持簡單!

-

你的更新,七年後:如果你的用例是從一個USB條形碼掃描儀讀取時,Windows 10有一個漂亮的,友好的API此內置的Windows.Devices.PointOfService.BarcodeScanner。這是一個UWP/WinRT API,但您也可以從常規桌面應用程序使用它;這就是我現在正在做的事情。下面是它的一些示例代碼,直接從我的應用程序,給你要點:

{ 
    using System; 
    using System.Linq; 
    using System.Threading.Tasks; 
    using System.Windows; 
    using Windows.Devices.Enumeration; 
    using Windows.Devices.PointOfService; 
    using Windows.Storage.Streams; 
    using PosBarcodeScanner = Windows.Devices.PointOfService.BarcodeScanner; 

    public class BarcodeScanner : IBarcodeScanner, IDisposable 
    { 
     private ClaimedBarcodeScanner scanner; 

     public event EventHandler<BarcodeScannedEventArgs> BarcodeScanned; 

     ~BarcodeScanner() 
     { 
      this.Dispose(false); 
     } 

     public bool Exists 
     { 
      get 
      { 
       return this.scanner != null; 
      } 
     } 

     public void Dispose() 
     { 
      this.Dispose(true); 
      GC.SuppressFinalize(this); 
     } 

     public async Task StartAsync() 
     { 
      if (this.scanner == null) 
      { 
       var collection = await DeviceInformation.FindAllAsync(PosBarcodeScanner.GetDeviceSelector()); 
       if (collection != null && collection.Count > 0) 
       { 
        var identity = collection.First().Id; 
        var device = await PosBarcodeScanner.FromIdAsync(identity); 
        if (device != null) 
        { 
         this.scanner = await device.ClaimScannerAsync(); 
         if (this.scanner != null) 
         { 
          this.scanner.IsDecodeDataEnabled = true; 
          this.scanner.ReleaseDeviceRequested += WhenScannerReleaseDeviceRequested; 
          this.scanner.DataReceived += WhenScannerDataReceived; 

          await this.scanner.EnableAsync(); 
         } 
        } 
       } 
      } 
     } 

     private void WhenScannerDataReceived(object sender, BarcodeScannerDataReceivedEventArgs args) 
     { 
      var data = args.Report.ScanDataLabel; 

      using (var reader = DataReader.FromBuffer(data)) 
      { 
       var text = reader.ReadString(data.Length); 
       var bsea = new BarcodeScannedEventArgs(text); 
       this.BarcodeScanned?.Invoke(this, bsea); 
      } 
     } 

     private void WhenScannerReleaseDeviceRequested(object sender, ClaimedBarcodeScanner args) 
     { 
      args.RetainDevice(); 
     } 

     private void Dispose(bool disposing) 
     { 
      if (disposing) 
      { 
       this.scanner = null; 
      } 
     } 
    } 
} 

當然,你需要一個支持USB HID POS和不只是一個鍵盤口條形碼掃描儀。如果您的掃描儀僅僅是一個鍵盤楔子,我建議像25美元一樣在eBay上購買使用過的Honeywell 4600G。相信我,你的理智是值得的。

0

這取決於您與設備進行交互的方式。無論如何,它不會是一個C#解決方案,它會是一些其他庫。你是從流中讀取數據嗎?如果你只是按鍵,你可能無法做到這一點。

2

我在類似情況下所做的是通過查看輸入的速度來區分掃描和用戶打字。

很多字符非常接近,然後暫停是掃描。其他任何東西都是鍵盤輸入。

我並不確切地知道你的需求,所以也許不會爲你做,但它是我有:)

-1

我想你也許可以通過的DirectX API來區分多個鍵盤最好,或者如果這不起作用,通過原始輸入API。

0

我已經成功地完成了你們在這裏尋找的東西。我有一個應用程序,可以從Honeywell/Metrologic條碼掃描器接收所有條形碼字符數據。系統上沒有其他應用程序從掃描儀接收數據,並且鍵盤繼續正常工作。

我的應用程序使用原始輸入和可怕的低級鍵盤掛鉤系統的組合。與這裏寫的相反,我發現wm_input消息是在調用鍵盤鉤子函數之前收到的。我處理wm_input消息的代碼基本上設置了一個布爾變量來指定接收到的字符是否來自掃描器。在處理完wm_input之後立即調用的鍵盤掛鉤函數會吞服掃描儀的僞鍵盤數據,從而阻止其他應用程序接收數據。

鍵盤掛鉤函數必須放置在dll中,因爲您要截取所有系統鍵盤消息。此外,內存映射文件必須用於wm_input處理代碼與dll進行通信。

-1

我知道這是一個老線程,通過在WIN10中搜索條碼掃描找到它。 只需幾張紙條,以防有人需要。

霍尼韋爾的這些掃描儀有幾個USB接口。 一個是鍵盤+ Hid銷售點(複合設備)。 還有CDC-ACM(ComPort仿真)和Hid銷售點(單獨)+更多。

默認情況下,掃描儀暴露一個序列號,所以主機可以區分很多設備(我曾經有+20次連接)。有一個命令可以禁用序列號!

新模型在這方面的表現相同。 如果你想看到它,試試我的終端程序yat3(在my site上免費)。 它可以打開上面提到的所有接口,併爲這些設備量身定製。

使用鍵盤接口的一句話:
只能用它們作爲最後的手段。當涉及到異國情調的角色時,他們很慢,不太可靠。如果您想要將數據輸入到現有的應用程序,唯一的好處是使用。如果您仍然編碼,那麼從ComPort/HidPos-Device讀取更容易。