我有一台条形码扫描仪(起着键盘的作用),当然我的键盘也挂在计算机上了。该软件正在接受扫描仪和键盘的输入。我只需要接受扫描仪的输入。该代码用C#编写。有没有一种方法可以“禁用”键盘输入并仅接受来自扫描仪的输入?
注意:键盘是笔记本电脑的一部分…因此无法拔出。另外,我尝试将以下代码保护为覆盖的值Boolean ProcessDialogKey(System.Windows.Forms.Keys keyData){return true; }但是,除了忽略键盘的击键操作外,条形码扫描器的输入也将被忽略。
我无法让扫描程序发送标记字符,因为其他应用程序正在使用该扫描器,添加标记字符流将意味着修改其他代码。
另外,由于扫描的条形码可能是单字符条形码,因此我无法使用确定输入是否来自条形码扫描仪的计时方法(如果输入的是一堆字符,然后是暂停)。
是的,我正在从流中读取数据。
我正在尝试遵循以下文章:从WinForms中的键盘区分条形码扫描仪。但是我有以下问题:
Nicholas Piasecki在http://nicholas.piasecki.name/blog/2009/02/distinguishing- barcode-scanners-from-the-keyboard-in- winforms/上发布的有关C#解决方案源代码的后续问题:
“ \ ?? \ HID#Vid_0536&Pid_01c1&MI_01#9&25ca5370&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}”
“ \ ?? \ HID#Vid_0536&Pid_01c1&MI_00#9&38e10b9&0&0000#{884b96c3-56ef-11d1-bc8c-00a0c91405dd}”
“ \ ?? \ HID#Vid_413c&Pid_2101&MI_00#8&1966e83d&0&0000#{884b96c3-56ef-11d1-bc8c-00a0c91405dd}”
“ \ ?? \ HID#Vid_413c&Pid_3012#7&960fae0&0&0000#{378de44c-56ef-11d1-bc8c-00a0c91405dd}” “ \ ?? \ Root#RDP_KBD#0000#{884b96c3-56ef-11d1-bc8c-00a0c91405dd}”“ \ ?? \ ACPI#PNP0303#4&2f94427b&0#{884b96c3-56ef-11d1-bc8c-00a0c91405dd}“” \ ?? \ Root#RDP_MOU#0000#{378de44c-56ef-11d1-bc8c-00a0c91405dd}“” \ ?? \ ACPI#PNP0F13 #4&2f94427b&0#{378de44c-56ef-11d1-bc8c-00a0c91405dd}”
因此,对于HID#Vid_0536&Pid_01c1,有2个条目;那会导致扫描不起作用吗?
好的,所以看来我不得不找出一种不依赖于扫描程序发送的ASCII 0x04字符的方法…因为我的扫描程序不发送该字符。之后,将触发条形码扫描事件,并显示带有条形码的弹出窗口。因此,感谢尼古拉斯的帮助。
您可以像我最近一样使用Raw Input API区分键盘和扫描仪。连接了多少个键盘或类似键盘的设备都没有关系;您将WM_INPUT在击键映射到通常在KeyDown事件中通常看到的与设备无关的虚拟键之前看到一个。
WM_INPUT
KeyDown
执行其他人推荐的操作和配置扫描仪以在条形码前后发送哨兵字符要容易得多。(您通常可以通过扫描扫描仪用户手册背面的特殊条形码来进行此操作。)然后,主窗体的KeyPreview事件可以监视那些滚动结束并吞下任何子控件的关键事件(如果该控件处于读取条形码的中间)。或者,如果您想成为更高级的爱好者,则可以使用低级键盘钩SetWindowsHookEx()来监视那些哨兵并将其吞入那里(这样做的好处是,即使您的应用程序没有关注焦点,您仍然可以得到该事件)。
KeyPreview
SetWindowsHookEx()
除其他外,我无法更改条形码扫描器上的哨兵值,因此我不得不走复杂的路线。绝对是痛苦的。如果可以,请保持简单!
-
七年后的更新: 如果您的用例是从USB条码扫描器读取的,则Windows 10具有一个内置的友好,友好的API Windows.Devices.PointOfService.BarcodeScanner。它是一个UWP / WinRT API,但您也可以从常规桌面应用程序中使用它。那就是我现在正在做的。这是一些示例代码,直接从我的应用程序中获取要点:
Windows.Devices.PointOfService.BarcodeScanner
{ 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。相信我,您的理智是值得的。