[置顶] 条码扫描枪的数据接收处理

时间:2023-01-13 11:48:19

在前面小节介绍了一些利用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();
}
[置顶]        条码扫描枪的数据接收处理

 

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