Ama*_*tel 22 c# barcode-scanner
我有一个条形码扫描仪(就像一个键盘),当然我有一个键盘太连接到计算机.该软件接受来自扫描仪和键盘的输入.我只需要接受扫描仪的输入.代码是用C#编写的.有没有办法从键盘"禁用"输入,只接受扫描仪的输入?
注意:键盘是笔记本电脑的一部分...因此无法拔下插头.此外,我尝试将以下代码保护覆盖布尔ProcessDialogKey(System.Windows.Forms.Keys keyData){return true; 但是,随着忽略键盘上的击键,条形码扫描器输入也被忽略.
我不能让扫描仪发送sentinal字符,因为扫描仪正被其他应用程序使用,添加一个sentinal字符流意味着修改其他代码.
此外,我无法使用定时方法来确定输入是否来自条形码扫描仪(如果它是一堆字符后跟一个暂停),因为扫描的条形码可能是单字符条形码.
是的,我正在从流中读取数据.
我试图跟随文章:在WinForms中区分条形码扫描器和键盘.不过我有以下问题:
关于C#解决方案源代码的后续问题由Nicholas Piasecki在http://nicholas.piasecki.name/blog/2009/02/distinguishing-barcode-scanners-from-the-keyboard-in-winforms/上发布:
"\ ??\HID#Vid_0536&Pid_01c1MI_01 9 25ca5370&0 {4d1e55b2-F16F-11CF-88cb-001111000030}"
"\ ??\HID#Vid_0536&Pid_01c1MI_00 9 38e10b9&0 {884b96c3-56ef-11D1-bc8c-00a0c91405dd}"
"\ ??\HID#Vid_413c&Pid_2101&MI_00#8&1966e83d&0 {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有两个条目; 可能导致扫描不起作用?
好吧所以我似乎不得不想办法不依赖于扫描仪发送的ASCII 0x04字符...因为我的扫描仪不发送该字符.之后,条形码扫描事件被触发,并显示带有条形码的弹出窗口.谢谢尼古拉斯的帮助.
Nic*_*cki 17
您可以使用Raw Input API来区分键盘和扫描仪,就像我最近做的那样.你连接了多少键盘或类似键盘的设备并不重要; WM_INPUT在按键被映射到您通常在KeyDown事件中看到的与设备无关的虚拟键之前,您将看到一个.
更容易做其他人推荐的事情,并配置扫描仪在条形码之前和之后发送哨兵角色.(您通常通过扫描扫描仪用户手册背面的特殊条形码来完成此操作.)然后,KeyPreview如果条形码读取过程中您的主窗体事件可以观察那些滚动结束并吞下任何子控件的关键事件.或者,如果你想成为发烧友,你可以使用一个低级别的键盘钩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;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
当然,您需要一个支持USB HID POS的条形码扫描仪,而不仅仅是键盘楔形.如果你的扫描仪只是一个键盘楔子,我建议在eBay上买一个像二手Honeywell 4600G一样的东西,价格只要25美元.相信我,你的理智是值得的.