Cipherlab CPT9300手持扫描枪开发体验
设备:Cipherlab CPT9300
OS :WinCE 6 R2
主要功能:一维、二维条码扫描。
用途: 大型仓库收发货识别扫描。
资源: 厂家有SDK提供,.net可外部调用的3个Dll及pdf开发手册(英文)。
开发: vs2008 + .Net CF 3.5
调试: 直接连接设备,未使用仿真机。
编码过程:
1、主界面及代码,详细请看注释。
代码:
using System; using System.Linq; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Reflection; using Cipherlab.SystemAPI; using System.Threading; namespace CF35_9300Demo { public partial class DemoMainForm : Form { //SysInfo 是WinCe系统信息的结构体,比如操作系统版本号、设备ID等 private Member.SysInfo m_DeviceSysInfo; /// <summary> /// 重写Text为了让主界面响应扫描结果而已 /// </summary> public override string Text { get { return base.Text; } set { base.Text = value; if (value.IndexOf("SDK") == -1) { MessageBox.Show(value, "Scan Result", MessageBoxButtons.OK, MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1); } } } public DemoMainForm() { InitializeComponent(); string tmp = string.Empty; Member.GetAPIVersion(ref tmp); tmp = string.Format("API Ver:{0}",tmp); Text += tmp; //.PadLeft(20,(char)32); Member.GetSysInfo(ref m_DeviceSysInfo); webBrowser1.Navigate(new Uri("http://datacool.cnblogs.com")); } /// <summary> /// 测试GDI直接绘制文字到指定位置,奇怪的是界面上Y轴,也就是Form的Top0-28这段区域会被遮挡。看起来那里有个光标,那行被挡住了。 /// </summary> /// <param name="e"></param> protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); e.Graphics.DrawString("App Builded By DataCool." + Environment.NewLine + "CopyRight By DataCool© 2012.", this.Font,new SolidBrush(Color.Red),new Rectangle(this.Left+2,this.Top+28,this.Width-40,60)); } /// <summary> /// 测试调用WCF服务,看起来是使用WebService方式,.Net CF 3.5工程里面没有“添加服务引用”. /// 获取远程数据库服务器的系统时间,修改本地WinCE的系统时间。 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button1_Click(object sender, EventArgs e) { CF35_9300Demo.QxTransQuery.QxTransQryService queryServiceProxy = new CF35_9300Demo.QxTransQuery.QxTransQryService(); var ds = queryServiceProxy.SDNA_Store_QueryData("select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual","qixuan520"); if (ds != null) { button1.Text = ds.Tables[0].Rows[0][0].ToString(); var dt = DateTime.Parse(button1.Text); var sysdt = new SystemTime(); sysdt.wYear = (short)dt.Year; sysdt.wMonth = (short)dt.Month; sysdt.wDay = (short)dt.Day; sysdt.wHour = (short)dt.Hour; sysdt.wMinute = (short)dt.Minute; sysdt.wSecond = (short)dt.Second; Win32API.SetLocalTime(ref sysdt); MessageBox.Show("系统时间已经更改为:"+button1.Text+"。", "Result", MessageBoxButtons.OK, MessageBoxIcon.Asterisk, MessageBoxDefaultButton.Button1); } } /// <summary> /// 测试 Linq To Object /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button2_Click(object sender, EventArgs e) { int[] buffer = new int[] { 1, 3, 5, 67 }; button2.Text = buffer.FirstOrDefault().ToString() + @"\" + buffer.Where(v => v > 5).FirstOrDefault().ToString(); } private void button3_Click(object sender, EventArgs e) { StringBuilder sb = new StringBuilder(); sb.AppendLine(string.Format("OS版本:{0}。 ", m_DeviceSysInfo.OsVer)); sb.AppendLine(string.Format("设备名称:{0}。 ", m_DeviceSysInfo.DevDesc)); sb.AppendLine(string.Format("设备ID:{0}。 ", m_DeviceSysInfo.SerialNum)); sb.AppendLine(string.Format("WiFi Mac:{0}。 ", m_DeviceSysInfo.WiFiAddress)); sb.AppendLine(string.Format("出厂日期:{0}。 ", m_DeviceSysInfo.ManuDate)); sb.AppendLine(string.Format("MicroPVer:{0}。", m_DeviceSysInfo.MicroPVer)); textBox1.Text = sb.ToString(); StringBuilder sb2 = new StringBuilder(); foreach (string p in m_DeviceSysInfo.PropsValueToStringArray()) { sb2.AppendLine(p); } textBox1.Text += sb2.ToString(); } private void button5_Click(object sender, EventArgs e) { MsgForm testFrm = new MsgForm(this); //初始化激光扫描组件,要1、2秒。只需要调用一次 int b1 = Reader.ReaderEngineAPI.InitReader(); } } /// <summary> /// 扩展结构体Member.SysInfo,将所有属性和值ToString(). /// 有谁知道如何使用反射简化这个写法,因为是结构体不是类。试过反射不出来 /// </summary> public static class SysInfoExt { public static string[] PropsValueToStringArray(this Member.SysInfo info) { string[] result = new string[] { string.Join(":", new string[] { "BootloaderVer", info.BootloaderVer}), string.Join(":", new string[] { "BTAddress", info.BTAddress}), string.Join(":", new string[] { "DevCFG", info.DevCFG}), string.Join(":", new string[] { "DevDesc", info.DevDesc}), string.Join(":", new string[] { "IMEI", info.IMEI}), string.Join(":", new string[] { "ManuDate", info.ManuDate}), string.Join(":", new string[] { "Manufactory", info.Manufactory}), string.Join(":", new string[] { "MicroPVer", info.MicroPVer}), string.Join(":", new string[] { "SerialNum", info.SerialNum}), string.Join(":", new string[] { "SerialNumPCBA", info.SerialNumPCBA}), string.Join(":", new string[] { "SerialNumReadOnly", info.SerialNumReadOnly}), string.Join(":", new string[] { "WiFiAddress", info.WiFiAddress}) }; return result; } } }
2、激光扫描相关编码(Reader)
using System; using System.Linq; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using Microsoft.WindowsCE.Forms; using System.Runtime.InteropServices; using Cipherlab.SystemAPI; namespace CF35_9300Demo { public struct SystemTime { public short wYear; public short wMonth; public short wDayOfWeek; public short wDay; public short wHour; public short wMinute; public short wSecond; public short wMilliseconds; } public class MsgForm : MessageWindow { public UInt32 decodeMsg = 0; int b1 = 0; byte[] lpbuf = new byte[25]; string tmp; public Form msgform; public MsgForm(Form msgFrm) { msgform = msgFrm; decodeMsg = Win32API.RegisterWindowMessage("WM_DECODEDATA"); } protected override void WndProc(ref Message m) { if (m.Msg == decodeMsg) { if (m.WParam.ToInt32().Equals(7)) { b1 = Reader.ReaderEngineAPI.GetDecodeData(ref tmp); msgform.Text = tmp; } } base.WndProc(ref m); } } /// <summary> /// Win32API,WinCE自带 /// </summary> public class Win32API { [DllImport("coredll.dll", SetLastError = true)] public static extern uint RegisterWindowMessage(string lpString); [DllImport("coredll.dll", SetLastError = true)] public static extern int SetLocalTime(ref SystemTime lpSystemTime); } }
SDK接口方式是使用Window Message方式,程序和接口(DLL)进行通信,程序先注册自定义消息"WM_DECODEDATA",然后按键进行扫描Dll扫描到条码后同过WM_DECODEDATA消息发送扫描到的条码给程序,程序窗口重写WndProc方法进行拦截,调用"Reader.ReaderEngineAPI.GetDecodeData(ref tmp);"获取Dll返回的条码字符串。
结论:
1、该设备有点贵哦,上万的售价啊。
2、开发比较简单有CF3.5和厂家提供的SDK开发包的支持像我等小白也可以开发。
最后上一张程序运行时的图:
作者:数据酷软件
出处:https://www.cnblogs.com/datacool/archive/2012/09/25/CPT9300_CF35_DEMO.html
关于作者:20年编程从业经验,持续关注MES/ERP/POS/WMS/工业自动化
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明。
联系方式: qq:71008973;wx:6857740733
基于人脸识别的考勤系统 地址: https://gitee.com/afeng124/viewface_attendance_ext
自己开发安卓应用框架 地址: https://gitee.com/afeng124/android-app-frame
WPOS(warehouse+pos) 后台演示地址: http://47.239.106.75:8080/
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构