Winform开发框架之读卡器和条码扫描枪的数据接收处理

简介:

在我们开发一些项目的时候,一般需要一些外围的设备进行数据处理,如ID/IC读卡器获取卡号、激光条码扫描枪、USB摄像头、USB方式的小票据打印机(POS打印机)、USB来电录音盒、普通打印机等一系列附属设备。借助这些设备,可以使我们的业务流程更严谨,输入数据更方便,或者能够一些特殊的数据等功能。本文主要介绍其中的ID读卡器(IC读卡器)快速读取卡号,以及实用激光条码枪的条码扫描录入功能,后面的一些硬件设备的处理,后续文章在继续介绍。

1、设备介绍

前面介绍的设备,在很多场合上都可能用到,如我的会员管理系统里面,就需要用到下面的设备处理。

本文主要针对性了解ID读卡器和条码枪的设备数据处理,这两种设备虽然不同,但是它们相似的地方就是都支持在光标处录入数据的,就有点类似我们的键盘快速录入一样,当然激光条码枪也支持很多种方式的事件处理操作,这是后话。

2、ID读卡器数据读取界面和条码扫描枪读取界面的分析介绍

在我的会员管理系统里面,录入卡号一般是通过ID读卡器获取的,在界面上设置一个可以弹出录入的文本框,也方便手工录入卡号,如下面的界面功能所示。

当然,有时候,我们可能不需要提供手工录入,那么就不能通过光标录入方式获取扫描的内容,因为我们把输入框设置为只读的了,所以这种情况,就就应该通过事件来获取设备的输入内容。

在条码枪处理读取条形码或者二维码的时候,我们一般都是和商品相关的地方使用条形码,二维码也可以使用,条形码可能一般带有数据供阅读,二维码则没有,但是都可以通过设备读取出来到文本框里面,一般如果录入,就停放光标在文本框就可以了,如商品的信息的录入。在我们需要输入条码的地方点一下,然后操作条码枪录入条码即可,这种不需要额外的代码处理。

但是对于一些我们需要快速录入商品信息的界面,如客户消费界面,那么就需要对条码的事件进行处理了。

例如下面的界面,在消费确认前的产品录入,我们都是通过条码枪的快速扫描产品进行录入的,这时候条码枪就代替了手工的录入,我们可以每次扫描一次,就在列表里面自动增加一个对应商品的记录,非常方便的了。

3、通用的读卡操作和条码扫描枪操作实现

在前面小节介绍了一些利用ID读卡器录入数据和使用条码枪的场景,对于如果是在可输入文本框里面获得内容,不用任何编码,如果是在只读界面或者窗体上获得设备的数据,那么就可以通过事件进行处理了,那么读卡器和扫描枪的事件应该如何处理的呢。

我的做法,是统一在我的Winform开发框架的界面层基类模块里面,增加一些硬件相关的处理类和界面,这样在各个框架派生出来的项目就可以很方便使用了。

其中Device里面的CardReader就是IC、ID读卡器获取操作的处理,一般来说,这些卡都是以00开始的,所以我们的处理类,通过一个Time来控制连续获取数据的处理就可以了,主要就是监听KeyUp事件。

以CardReader为例,它的完整代码如下所示。

    /// <summary>
    /// 读卡器封装类
    /// </summary>
    public class CardReader
    {
        private Control _hostCtrl;
        private string _cardCode;
        private Timer _timer;
        private const int CARD_CODE_LEN = 10;
        private const string CARD_CODE_START = "00";

        /// <summary>
        /// 读卡器读到一张卡的事件
        /// </summary>
        public event CardReadEventHandler CardRead;

        /// <summary>
        /// 默认读卡器(挂在主窗体上,会被主窗体初始化,在模块里用肯定是安全的)
        /// </summary>
        public static CardReader Default { get; set; }

        /// <summary>
        /// 构造器
        /// </summary>
        /// <param name="hostCtrl">接受键盘事件的宿主控件</param>
        public CardReader(Control hostCtrl)
        {
            _hostCtrl = hostCtrl;
            if (_hostCtrl is Form)
            {
                (_hostCtrl as Form).KeyPreview = true;
            }
            _hostCtrl.KeyUp += new KeyEventHandler(hostCtrl_KeyUp);
            _cardCode = "";
            _timer = new Timer();
            _timer.Interval = 20;
            _timer.Tick += new EventHandler(timer_Tick);
            _timer.Start();
        }

        /// <summary>
        /// 判断是否卡号
        /// </summary>
        /// <param name="code"></param>
        /// <returns></returns>
        public static bool IsCardCode(string code)
        {
            return code.Length == CARD_CODE_LEN && code.StartsWith(CARD_CODE_START);
        }

        /// <summary>
        /// 定时器到期的事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void timer_Tick(object sender, EventArgs e)
        {
            //达到一定的位数才开始判断
            if (_cardCode.Length >= CARD_CODE_LEN)
            {
                _cardCode = _cardCode.Trim((char)13);
                if (IsCardCode(_cardCode))
                {
                    _timer.Stop();
                    OnCardRead(_cardCode);
                }
            }
            _cardCode = "";
            _timer.Start();
        }

        /// <summary>
        /// 监听按键弹起的事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void hostCtrl_KeyUp(object sender, KeyEventArgs e)
        {
            _timer.Stop();
            _cardCode = _cardCode + (char)e.KeyValue;
            _timer.Start();
        }

        private void OnCardRead(string scanCode)
        {
            if (CardRead != null)
            {
                CardRead(scanCode);
            }
        }

    }

    /// <summary>
    /// 读卡器读到一张卡的事件处理委托
    /// </summary>
    /// <param name="cardCode"></param>
    public delegate void CardReadEventHandler(string cardCode);

CardReader封装类, 的使用操作如下所示。我们通过事件就可以获取到完整的输入内容,然后进行数据的绑定或处理即可,代码如下所示。

    public partial class FrmProcessConsumption : BaseDock
    {
        /// <summary>
        /// 会员信息
        /// </summary>
        private MemberInfo memberInfo { get; set; }

        /// <summary>
        /// 读卡器接口
        /// </summary>
        private CardReader cardReader;

        public FrmProcessConsumption()
        {
            InitializeComponent();

             ................................

            cardReader = new CardReader(this);
            cardReader.CardRead += new CardReadEventHandler(cardReader_CardRead);   
        }

        void cardReader_CardRead(string cardCode)
        {
            this.txtMember_CardNo.Text = cardCode;

            BindMemberData();
        }

然后我们为了方便使用,还可以定义一个统一的处理读卡器和扫描枪的接收数据的小窗口。

这个弹出的小窗口用来处理读卡器,扫描枪等信息的录入就可以了,当然上述的如CardReader/USBScanner还是可以独立使用,如我们在一个只读控件或者窗口里面,一样可以监听到对应的设备数据读取操作,但设备有数据读取完成过后,就会触发相应的事件了。

下面代码就是上面设备信息读取的代码

    /// <summary>
    /// 读卡器、USB条码扫描器、串口条码扫描器数据读取及显示窗体
    /// </summary>
    public partial class DeviceReaderDialog : BaseForm
    {
        private CardReader _cardReader;
        private USBScanner _usbScanner;public DeviceReaderDialog(DeviceType type = DeviceType.Card)
        {
            InitializeComponent();
            //能手填
            this.Readonly = false;

            if (type == DeviceType.Card)
            {
                this._cardReader = new CardReader(this);
                this._cardReader.CardRead += new CardReadEventHandler(_cardReader_CardRead);
            }
            else if (type == DeviceType.UsbScanner)
            {
                this._usbScanner = new USBScanner(this);
                this._usbScanner.ScannerRead += new ScannerReadEventHandler(Scanner_ScannerRead);
            }
        }

        void Scanner_ScannerRead(string scanCode)
        {
            this.txtCode.Text = scanCode;
            DialogResult = DialogResult.OK;
        }

        void _cardReader_CardRead(string cardCode)
        {
            this.txtCode.Text = cardCode;
            DialogResult = DialogResult.OK;
        }

        public string Code
        {
            get { return txtCode.Text; }
        }

        public bool Readonly
        {
            get { return txtCode.Properties.ReadOnly; }
            set
            {
                txtCode.Properties.ReadOnly = value;
                this.btnOK.Enabled = !value;
                this.btnOK.Visible = !value;
            }
        }

        private void DeviceReaderDialog_Load(object sender, EventArgs e)
        {
            if (!this.Readonly)
            {
                this.KeyDown += new KeyEventHandler(DeviceReaderDialog_KeyDown);
            }
        }

        void DeviceReaderDialog_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                this.DialogResult = DialogResult.OK;
            }
        }
    }

 本文转自博客园伍华聪的博客,原文链接:Winform开发框架之读卡器和条码扫描枪的数据接收处理,如需转载请自行联系原博主。



目录
相关文章
|
3月前
|
编解码 网络协议 前端开发
如何实现Android平台GB28181设备接入模块按需打开摄像头并回传数据
后台采集摄像头,如果想再进一步扩展,可以把android平台gb28181的camera2 demo,都移植过来,实现功能更强大的国标设备侧,这里主要是展示,收到国标平台侧的回传请求后,才打开摄像头,才开始编码打包,最大限度的减少资源的占用
|
4月前
|
供应链 物联网 Android开发
使用LabVIEW开发RFID读卡器程序
使用LabVIEW开发RFID读卡器程序
58 0
|
6月前
|
数据采集 运维 监控
LabVIEW发开发电状态监测系统
LabVIEW发开发电状态监测系统
39 5
|
11月前
|
前端开发 UED 计算机视觉
前端调取摄像头并实现拍照功能
前端调取摄像头并实现拍照功能
1041 0
|
存储 网络协议 小程序
我的小工具,用C和python实现远程读卡器,远程读写消费卡片
我的小工具,用C和python实现远程读卡器,远程读写消费卡片
我的小工具,用C和python实现远程读卡器,远程读写消费卡片
|
存储 编解码 关系型数据库
案例分享:Qt激光加工焊接设备信息化软件研发(西门子PLC,mysql数据库,用户权限控制,界面设计,参数定制,播放器,二维图,rgv小车,期限控制,参数调试等)
国产大型机床中Qt上位机激光焊接系统软件案例分享,介绍了Qt在国产化机床上的各种应用案例,并附上案例的具体功能界面供大家学习
案例分享:Qt激光加工焊接设备信息化软件研发(西门子PLC,mysql数据库,用户权限控制,界面设计,参数定制,播放器,二维图,rgv小车,期限控制,参数调试等)
|
JSON 小程序 前端开发
微信小程序接入NFC,使用HCE模拟主机卡完成NFC刷卡发送消息
微信小程序接入NFC,使用HCE模拟主机卡完成NFC刷卡发送消息
752 0
微信小程序接入NFC,使用HCE模拟主机卡完成NFC刷卡发送消息
|
存储 编解码 关系型数据库
案例分享:Qt工程机械真空激光焊接系统软件产品定制(西门子PLC,mysql数据库,用户权限控制,界面配置,参数定制,播放器,二维图标,rgv小车,期限控制,参数调试等)
基于Qt的真空焊接系统工程机械案例分享。1.ui由本司美工承担设计,显示分辨率1280 x 1024,同时支持鼠标操作。2.权限控制:三种权限,分为管理员(可以定制模块界面,修改产品名称等定制化软件和其他权限,同时具备编程员和操作员权限),编程员(新建工件,参数,调试功能等与生产相关的权限,同时具备操作员权限),操作员(加工相关的操作权限),三个等级对所有界面进行区分使用,并可进行管理;3.专家可增删改编程员,操作员;编程员可增删改操作员;4.与西门子PLC通讯,兼容S7全系,项目使用S7-1500...
案例分享:Qt工程机械真空激光焊接系统软件产品定制(西门子PLC,mysql数据库,用户权限控制,界面配置,参数定制,播放器,二维图标,rgv小车,期限控制,参数调试等)
|
传感器 移动开发 vr&ar
实现摇一摇功能- H5 设备运动事件DeviceMotionEvent DeviceOrientationEvent
新年不是搞了个摇签的功能吗,弹幕效果咱们前面讲过了,今天来说说摇一摇效果
518 0
实现摇一摇功能- H5 设备运动事件DeviceMotionEvent DeviceOrientationEvent
自制电脑红外遥控接收器(PC软解码)
网上有很多介绍红外遥控接收器制作的文章,但其中大部分是用单片进行红外解码,然后再通过串口或USB把解码后的按键信息传入到PC的。这样的电路制作起来,不仅造价相对偏高,而且需要对单片编程,这会令大部分软件开发爱好者望而却步
1137 0