c#完美区分USB条码枪与键盘输入的方案

用以下winapi可获取设备原始输入信息,即包含硬件标识的信息:

        [DllImport("User32.dll")]
        extern static uint GetRawInputData(IntPtr hRawInput, uint uiCommand, IntPtr pData, ref uint pcbSize, uint cbSizeHeader);

        [DllImport("User32.dll")]
        extern static bool RegisterRawInputDevices(RAWINPUTDEVICE[] pRawInputDevice, uint uiNumDevices, uint cbSize);

        [DllImport("User32.dll")]
        extern static uint GetRawInputDeviceInfo(IntPtr hDevice, uint uiCommand, IntPtr pData, ref uint pcbSize);

重写窗体的消息处理函数,当接收到WM_INPUT消息时,则进行该消息所对应的原始输入信息的获取,然后即可得到硬件标识(在不知道条码枪的硬件标识的情况下,可将GetScannerName变量设置为true,然后将首个进行键盘消息录入的硬件标识为条码枪)之后即可将条码枪录入标识变量IsScannerInput设置为true:

public FrmMain()
        {
            InitializeComponent();

            RegWM_INPUT();
        }

/// <summary>
        /// 订阅WM_INPUT消息
        /// </summary>
        private void RegWM_INPUT()
        {
            RAWINPUTDEVICE[] rid = new RAWINPUTDEVICE[1];
            rid[0].usUsagePage = 0x01;
            rid[0].usUsage = 0x06;
            rid[0].dwFlags = RIDEV_INPUTSINK;//RIDEV_INPUTSINK | RIDEV_NoLegacy;//当前设置:焦点非当前窗口时依旧接收到WM_INPUT消息,可根据此特性实现当使用条码枪时激活本窗口
            rid[0].hwndTarget = this.Handle;
            RegisterRawInputDevices(rid, (uint)rid.Length, (uint)Marshal.SizeOf(rid[0]));
        }

protected override void WndProc(ref Message m)
        {
            if (m.Msg == WM_INPUT)
            {
                processMessage(m);
            }
            base.WndProc(ref m);
        }

        private void processMessage(Message message)
        {
            uint dwSize = 0;
            GetRawInputData(message.LParam, RID_INPUT, IntPtr.Zero, ref dwSize, (uint)Marshal.SizeOf(typeof(RAWINPUTHEADER)));
            IntPtr buffer = Marshal.AllocHGlobal((int)dwSize);
            GetRawInputData(message.LParam, RID_INPUT, buffer, ref dwSize, (uint)Marshal.SizeOf(typeof(RAWINPUTHEADER)));
            RAWINPUT raw = (RAWINPUT)Marshal.PtrToStructure(buffer, typeof(RAWINPUT));
            uint size = (uint)Marshal.SizeOf(typeof(RID_DEVICE_INFO));
            GetRawInputDeviceInfo(raw.header.hDevice, RIDI_DEVICENAME, IntPtr.Zero, ref size);
            IntPtr pData = Marshal.AllocHGlobal((int)size);
            GetRawInputDeviceInfo(raw.header.hDevice, RIDI_DEVICENAME, pData, ref size);
            string deviceName = (string)Marshal.PtrToStringAnsi(pData);
            if (GetScannerName)
            {
                ScannerName = txtTiaoMaQiang.Text = deviceName;
                GetScannerName = false;
            }
            if (deviceName == ScannerName)
            {
                IsScannerInput = true;
                this.Activate();
                if (raw.keyboard.Flags == 1)
                {
                    switch (raw.keyboard.VKey)//目前是仅转译了数字,如需字母与符号可在此扩展
                    {
                        case 0x30:
                            ScannerCodeCache.Append('0');
                            break;
                        case 0x31:
                            ScannerCodeCache.Append('1');
                            break;
                        case 0x32:
                            ScannerCodeCache.Append('2');
                            break;
                        case 0x33:
                            ScannerCodeCache.Append('3');
                            break;
                        case 0x34:
                            ScannerCodeCache.Append('4');
                            break;
                        case 0x35:
                            ScannerCodeCache.Append('5');
                            break;
                        case 0x36:
                            ScannerCodeCache.Append('6');
                            break;
                        case 0x37:
                            ScannerCodeCache.Append('7');
                            break;
                        case 0x38:
                            ScannerCodeCache.Append('8');
                            break;
                        case 0x39:
                            ScannerCodeCache.Append('9');
                            break;
                        case 0x3a:
                            ScannerCodeCache.Append('0');
                            break;
                        case 0x0d:
                            {
                                string _scannerCode = ScannerCodeCache.ToString();
                                ScannerCodeCache.Clear();
                                MessageDxUtil.ShowTips(_scannerCode);
                                break;
                            }
                    }
                }
            }
            else
            {
                IsScannerInput = false;
            }
            //下面两句是释放了缓存
            Marshal.FreeHGlobal(buffer);
            Marshal.FreeHGlobal(pData);
        }

重写窗口的ProcessKeyPreview函数:

protected override bool ProcessKeyPreview(ref Message m)//重写此函数可拦截扫码枪字符输入
        {
            if (IsScannerInput)//如果为条码枪输入则不对窗口内的控件进行录入
            {
                return true;
            }
            return base.ProcessKeyPreview(ref m);
        }
protected override bool ProcessDialogKey(Keys keyData)//重写此函数可拦截扫码枪回车触发按钮
        {
            if (IsScannerInput)
            {
                return true;
            }
            return base.ProcessDialogKey(keyData);
        }

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值