首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在C#中区分多个输入设备

如何在C#中区分多个输入设备
EN

Stack Overflow用户
提问于 2009-02-25 21:04:45
回答 6查看 32.5K关注 0票数 26

我有一个条形码扫描仪(它的作用就像一个键盘),当然我还有一个连在电脑上的键盘。软件同时接受来自扫描仪和键盘的输入。我只需要接受扫描仪的输入。代码是用C#编写的。有没有办法“禁用”键盘输入,只接受扫描仪的输入?

注:键盘是laptop...so的一部分,不能拔出。此外,我还尝试将以下代码保护覆盖Boolean ProcessDialogKey(System.Windows.Forms.Keys keyData) {ProcessDialogKey true;},但是在忽略键盘击键的同时,条形码扫描器输入也被忽略。

我不能让扫描器发送sentinal字符,因为扫描器正在被其他应用程序使用,添加sentinal字符流将意味着修改其他代码。

此外,我不能使用计时方法来确定输入是否来自条形码扫描仪(如果它是一串字符,后面跟着一个停顿),因为扫描的条形码可能是单字符条形码。

是的,我正在从流中读取数据。

我正在尝试跟随这篇文章:在WinForms中区分条形码扫描器和键盘。然而,我有以下问题:

  1. 由于其保护级别的原因,我收到NativeMethods无法访问的错误。似乎我需要导入一个dll;这样做正确吗?如果是这样,我该怎么做?
  2. Which override void WndProc(ref Message m)定义我应该使用,文章中有两个实现?
  3. Am ref a error to SecurityPermission( SecurityAction.LinkDemand,Flags = SecurityPermissionFlag.UnmanagedCode) error CS0246:找不到类型或命名空间名称'SecurityPermission‘(您是否缺少using指令或程序集引用?)。如何解决此错误?在包含以下内容的行上也有一个错误: if ((from hardwareId in hardwareIds
  4. deviceName.Contains(hardwareId) select hardwareId).Count() > 0) Error is error CS1026:)我将文章中的所有代码放在一个名为BarcodeScannerListener.cs?

的.cs文件中

关于Nicholas Piasecki在http://nicholas.piasecki.name/blog/2009/02/distinguishing-barcode-scanners-from-the-keyboard-in-winforms/上发布的C#解决方案源代码的后续问题

Visual

  • I无法在VS2005中打开该解决方案,因此我下载了 C# 2008速成版,并运行了代码。然而,在连接我的条形码扫描仪并扫描条形码后,程序无法识别扫描。我在OnBarcodeScanned方法中设置了一个断点,但它从未命中。我确实用通过设备管理器获得的条形码扫描仪的id更改了App.config。似乎有2个带有HID#Vid_0536&Pid_01c1的deviceNames (在连接扫描仪时从设备管理器获得)。我不知道这是不是导致扫描无法工作。在遍历deviceNames时,下面是我找到的设备列表(使用调试器):

"\??\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条目;这会导致扫描无法工作吗?

好的,看起来我必须找出一种不依赖于scanner...since发送的ASCII0x04字符的方法,我的扫描仪不会发送该字符。之后,触发条形码扫描事件,并显示带有条形码的弹出窗口。所以感谢Nicholas的帮助。

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2009-02-26 06:13:55

You could use the Raw Input API to distinguish between the keyboard and the scanner like I did recently.连接了多少键盘或类似键盘的设备并不重要;在击键被映射到通常在KeyDown事件中看到的与设备无关的虚拟键之前,您将看到一个WM_INPUT

更简单的方法是按照其他人的建议,将扫描仪配置为在条形码之前和之后发送前哨字符。(您通常通过扫描扫描仪用户手册背面的特殊条形码来完成此操作。)然后,如果主窗体的KeyPreview事件处于条形码读取过程中,它就可以看到这些滚动结束并吞下任何子控件的键事件。或者,如果你想更花哨一些,你可以使用一个带有SetWindowsHookEx()的低级键盘钩子来观察这些前哨,并在那里接受它们(这样做的好处是,即使你的应用程序没有焦点,你仍然可以获得事件)。

我不能改变我们的条形码扫描仪上的前哨数值,所以我不得不走复杂的路线。绝对是痛苦的。如果可以,尽量保持简单!

--

如果你的用例是从条形码扫描器读取数据,Windows10为这个内置的Windows.Devices.PointOfService.BarcodeScanner提供了一个友好的接口。它是一个UWP/WinRT API,但是你也可以从一个常规的桌面应用程序中使用它;这就是我现在正在做的。下面是一些示例代码,直接取自我的应用程序,为您提供要点:

代码语言:javascript
复制
{
    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的条形码扫描器,而不仅仅是一个键盘楔子。如果你的扫描仪只是一个键盘楔子,我建议你从eBay上买一台二手霍尼韦尔4600G之类的东西,大约25美元。相信我,你的理智是值得的。

票数 20
EN

Stack Overflow用户

发布于 2009-02-25 21:21:51

我在类似的情况下所做的是通过查看输入的速度来区分扫描和用户键入。

许多字符靠得很近,然后暂停就是扫描。其他的都是键盘输入。

我不太清楚您的需求,所以这可能不适合您,但这是我能做的最好的了:)

票数 3
EN

Stack Overflow用户

发布于 2009-02-25 21:10:38

这取决于您与设备交互的方式。无论如何,它不会是一个C#解决方案,它将是一个其他的库。您是否正在从流中读取数据?如果你只是敲击键盘,你可能对此无能为力。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/587840

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档