USB接口的扫码枪基本就相当于一个电脑外设,在WINDOWS系统中,甚至可以简单到不做任何处理,就能在焦点位置获取扫码枪返回的数据。但是作为一个程序员,总是会遇到客户各种神奇的需求,比如一个比较常见的功能:客户手拿扫码枪不管扫什么,软件都能自动辨别是什么类型的条码,叭叭叭扫好几种条码的时候,软件能够区分出来各种条码,并且根据条码调出相关数据。

呐,这个需求的话,就直接把手动更改焦点位置来扫码的可能性pass了,客户没有那么智能,并且客户很懒。这样的话,就需要根据条码的内容来确定是什么条码,然后再和后台数据一起显示到软件界面上。

这个时候就确定了软件有关扫码枪方面需要实现的功能:无视焦点,后台获取扫码枪的数据,然后就是业务逻辑了。这篇文章就是介绍WPF如何实现无焦点获取扫码枪数据。

这里需要感谢一下简书上的一位大佬,他的一篇文章基本解决我的需求,但是其中很多地方讲解的不太详细,我在这里再画蛇添足一下,dalao勿怪。

现在放出几个关键点的代码,加以说明,全部代码在最后放出链接:
1.扫描监听器BarcodeScannerListener

使用WindowInteropHelper获取传入窗体的句柄,并且绑定ThreadFilterMessage事件,达到从而可以触发ProcessRawInputMessage方法

/// <summary>
/// 将监听器附着到窗体上
/// </summary>
/// <param name="form">需要附着的窗体(WPF)</param>
public void Attach(Window form)
{var helper = new WindowInteropHelper(form);IntPtr hwnd = helper.Handle;form.KeyDown += (sender, args) =>{if (_ControlHandled){args.Handled = true;_ControlHandled = false;}};DoAttach(hwnd);
}/// <summary>
/// 监听绑定
/// </summary>
/// <param name="hwnd">设备指针</param>
private void DoAttach(IntPtr hwnd)
{this.keystrokeBuffer = new StringBuilder();this.InitializeBarcodeScannerDeviceHandles();this.interopHelper.HookRawInput(hwnd);//this.HookHandleEvents(form);//this.AssignHandle(ptr);this.filter = new BarcodeScannerKeyDownMessageFilter();ComponentDispatcher.ThreadFilterMessage -= ComponentDispatcher_ThreadFilterMessage;ComponentDispatcher.ThreadFilterMessage += ComponentDispatcher_ThreadFilterMessage;//Application.AddMessageFilter(this.filter);
}

ProcessRawInputMessage方法中,判断传入的字符串是否是扫码枪设置的结束字符(扫码的字符串是一个一个传入的),如果不是,就加入到Buffer中,如果是,则触发FireBarcodeScanned方法

/// <summary>
/// 处理WM_INPUT消息
/// </summary>
/// <param name="rawInputHeader">rawInputHeader的指针</param>
/// <returns>按键是否被处理</returns>
private bool ProcessRawInputMessage(IntPtr rawInputHeader)
{BarcodeScannerDeviceInfo deviceInfo;bool handled;bool keystroke;string localBuffer;IntPtr rawInputDeviceHandle;handled = false;keystroke = false;localBuffer = string.Empty;rawInputDeviceHandle = IntPtr.Zero;this.interopHelper.GetRawInputInfo(rawInputHeader,ref rawInputDeviceHandle,ref keystroke,ref localBuffer);
if (this.devices.TryGetValue(rawInputDeviceHandle, out deviceInfo) && keystroke){handled = true;// 这里判断的是Tab按键,可以更换为其他按键if (localBuffer.Length == 1 && (localBuffer[0] == 0x09 || localBuffer[0] == '\t')){this.FireBarcodeScanned(deviceInfo);}else{this.keystrokeBuffer.Append(localBuffer);}}return handled;
}

FireBarcodeScanned方法中,则会调用界面初始化时,绑定的事件,传入扫码的字符串

/// <summary>
/// 触发扫码事件
/// </summary>
/// <param name="deviceInfo">扫码设备信息</param>
private void FireBarcodeScanned(BarcodeScannerDeviceInfo deviceInfo)
{string barcode;EventHandler handler;barcode = this.keystrokeBuffer.ToString();if (barcode.Length > 0){handler = this.BarcodeScanned;this.keystrokeBuffer = new StringBuilder();if (handler != null){handler(this, new BarcodeScannedEventArgs(barcode, deviceInfo));}}
}

2.页面调用

这里我使用的MVVM模式,所以在ViewModel层调用,但是只要能拿到View的对象,在那一层都没有关系

BarcodeScannerListener = new BarcodeScannerListener();
BarcodeScannerListener.Attach((Window)GetView());
BarcodeScannerListener.BarcodeScanned += OnBarcodeScanned;

在传入的事件中,获取Barcode属性即可得到扫描的值

private void OnBarcodeScanned(object sender, EventArgs e)
{string barcode = ((BarcodeScannedEventArgs)e).Barcode;DoBarcodeScanned(barcode);
}

3.配置条码枪的硬件ID

需要在windows设备管理器中,找到扫码枪的设备ID

就是在这里,原文作者没有讲清楚。

第一步:寻找USB设备的ID;Win10系统在设备管理->人体学输入设备->找到USB选项的设备ID

 第二步:在程序中确认设备ID写入,并且测试SDK

这其中涉及到App.config的编程和设备ID的解析,还有一个&符号的转义,这里我就不赘述了。

完整Demo

WPF实现无线扫码枪无焦点自动获取数据并逻辑处理相关推荐

  1. USB扫码枪无焦点输入到指定页面、指定文件框中

    USB扫码枪无焦点输入到指定页面.指定文件框中 USB扫码枪无焦点输入到指定页面.指定文件框中 新建工程添一个MDIParent窗口,两个FORM窗口.第一步添加一个类(ScanerHook),代码如 ...

  2. [C#.Net]全局钩子实现USB扫码枪无焦点状态下扫入

    [C#.Net]全局钩子实现USB扫码枪无焦点状态下扫入 [C#.Net]全局钩子实现USB扫码枪无焦点状态下扫入 [C#.Net]全局钩子实现USB扫码枪无焦点状态下扫入 1.扫描枪获取数据原理基本 ...

  3. java表单自动绑定数据_java工作流系统表单自动 获取数据

    关键词:工作流快速开发平台  工作流流设计  业务流程管理   asp.net 开源工作流  bpm工作流系统  java工作流主流框架  自定义工作流引擎 表单设计器  流程设计器 什么是数据自动获 ...

  4. 肝!不需要一行 Python 代码,也可以自动获取数据

    今天给大伙介绍一下 RPA,有时候你可能会使用代码去编写自动化相关的操作,不过对于一些在 GUI 上的的重复操作,实际上可以直接使用机器人流程自动化,监视使用者在软件 GUI 里面的工作,然后直接在这 ...

  5. 如何使用表格自动获取网页上的表格数据,并自动刷新

    简介 本文介绍了如何通过Excel获取每日的基金净值,并自动刷新,方便各个平台的基金进行统计.这里假设从平台1在2019年8月20日购买编号为000001基金100元,从平台2在2019年8月19日购 ...

  6. 简单的低频指数投资二:每天定时获取数据

    apscheduler是一个python定时任务框架,我们可以利用它来完成一个每天自动获取数据并且发出交易指令的系统. from apscheduler.schedulers.blocking imp ...

  7. Ract基础之恰当的获取数据二

    1.创建一个组件来从服务端获取数据,并展示,如下 import React from 'react'class Gists extends React.Component{constructor(pr ...

  8. 扫码枪(条码枪)v1.0可以实现无焦点捕获扫码输入,并可上传数据到服务器

    扫码枪(条码枪CCSP Scan)v1.0扫可以实现无焦点捕获输入,支持串口和USB接口,并上传数据服务. github 小巧精悍,不到1M. 下载 USB接口 设置 串口 概述 1. 分为免费版和注 ...

  9. 爬虫三(Bs4搜索、Selenium基本使用、无界面浏览器、Selenium自动登录百度案例、自动获取12306登录验证码案例、切换选项卡、浏览器前进后退、登录Cnblogs获取Cookie自动点赞)

    文章标题 一.Bs4搜索文档树 二.CSS选择器 三.selenium基本使用 四.无界面浏览器 五.selenium其他使用 1)自动登录百度案例 2)获取位置属性大小.文本 3)自动获取12306 ...

  10. android edittext自动获取焦点,Android取消EditText自动获取默认焦点

    Android取消EditText自动获取默认焦点 发布时间:2020-10-02 14:08:30 来源:脚本之家 阅读:142 作者:ganchuanpu 最近在通讯录新建联系人=中,一进入一个页 ...

最新文章

  1. 计算机硬件 OR CX 1,计算机硬件第三章ppt
  2. mongoDB入门必读(概念与实战并重)
  3. spring AbstractBeanDefinition创建bean类型是动态代理类的方式
  4. 弃医从码 | 从肄业少年到失业青年,再到科技工程师的逆袭人生路
  5. WordPress响应式Alt_Blog主题 简约博客主题
  6. centos8下搭建gotk3(go语言gtk库) x86_64-w64-mingw32交叉编译环境
  7. 现实世界的Windows Azure:就Metanga采访MetraTech公司CEO,Scott Swartz先生
  8. adb shell am 的用法
  9. Git储藏和引用日志
  10. Mysqldump 1449 错误解决 mysqldump: Got error: 1449
  11. 一种改进的樽海鞘群算法-附代码
  12. 错误排查:Cloudera Manager Agent 的 Parcel 目录位于可用空间小于 10.0 吉字节 的文件系统上。 /opt/cloudera/parcels...
  13. 竞价域名是干什么的?为什么要进行域名竞价?
  14. java中if条件函数怎么用_if函数,多个条件怎么使用
  15. 如何使用 Firebase 建立短網址?
  16. 飞行汽车能顺利上天吗?
  17. 【打卡-Coggle竞赛学习2023年3月】对话意图识别
  18. Spark随笔(三):straggler的产生原因
  19. Permissions 0777 for ‘/home/***/.ssh/id_rsa‘ are too open.
  20. ORC工具(使用阿里云统一文字识别接口实现)

热门文章

  1. 管家婆服务器怎么找文件夹,请问管家婆数据备份在哪里?如何恢复?
  2. xlsxwriter 简单用法
  3. 冲突域和广播域的理解
  4. 助力公益数字化 火山引擎向公益机构捐赠多款技术产品
  5. 常见门电路逻辑符号对照(三态门,同或门,异或门,或非门,与或非门, 传输门,全加器,半加器,基本rs触发器,同步rs触发器,jk触发器,d触发器)
  6. 微信小程序开发之路(3)— 添加一个Button按钮点击事件
  7. 图片裁切批处理_Imgbot 在线图片批量处理工具 支持缩放、压缩、裁切、水印等...
  8. 医院为什么要上患者随访管理系统?
  9. PowerDesigner将PDM导出生成WORD文档(rtf文档)
  10. 关于手动误删表空间文件出现ora01033解决办法