using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Windows.Forms; using LB_VisionProcesses.BarcodeReaders; namespace LB_VisionProcesses.BarcodeReaders { /// /// 读码器配置与测试窗体 /// public partial class BarcodeReaderForm : Form { private IBarcodeReader _reader; private string _currentSN; private LB_VisionProcesses.Processes.BarcodeReaderProcess _process; private string _processPath; public BarcodeReaderForm() { InitializeComponent(); } public BarcodeReaderForm(LB_VisionProcesses.Processes.BarcodeReaderProcess process, string processPath) { InitializeComponent(); _process = process; _processPath = processPath; // 加载流程参数到 UI if (_process.Params.Inputs.ContainsKey("设备品牌")) cmbBrand.Text = _process.Params.Inputs["设备品牌"].ToString(); if (_process.Params.Inputs.ContainsKey("设备SN")) cmbSN.Text = _process.Params.Inputs["设备SN"].ToString(); if (_process.Params.Inputs.ContainsKey("触发模式")) radSoftTrigger.Checked = _process.Params.Inputs["触发模式"].ToString() == "软触发"; if (_process.Params.Inputs.ContainsKey("超时时间")) txtTimeout.Text = _process.Params.Inputs["超时时间"].ToString(); } private void BarcodeReaderForm_Load(object sender, EventArgs e) { // 初始化品牌列表 cmbBrand.Items.Clear(); foreach (var brand in Enum.GetValues(typeof(BarcodeReaderBrand))) { if ((BarcodeReaderBrand)brand != BarcodeReaderBrand.Unsupported) { cmbBrand.Items.Add(brand); } } if (cmbBrand.Items.Count > 0) cmbBrand.SelectedIndex = 0; UpdateUIStatus(); } private void btnRefresh_Click(object sender, EventArgs e) { try { if (cmbBrand.SelectedItem == null) return; var brand = (BarcodeReaderBrand)cmbBrand.SelectedItem; using (var tempReader = BarcodeReaderFactory.CreateReader(brand)) { var devices = tempReader.GetDeviceList(); cmbSN.Items.Clear(); if (devices != null && devices.Count > 0) { cmbSN.Items.AddRange(devices.ToArray()); cmbSN.SelectedIndex = 0; } } lblStatus.Text = $"设备列表已刷新,找到 {cmbSN.Items.Count} 个设备"; } catch (Exception ex) { MessageBox.Show($"刷新设备列表失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } } private void btnOpen_Click(object sender, EventArgs e) { try { if (cmbSN.SelectedItem == null && string.IsNullOrEmpty(cmbSN.Text)) { MessageBox.Show("请选择或输入设备序列号"); return; } _currentSN = cmbSN.Text; var brand = (BarcodeReaderBrand)cmbBrand.SelectedItem; if (_reader != null) { _reader.BarcodeRead -= Reader_BarcodeRead; _reader.Dispose(); } _reader = BarcodeReaderFactory.CreateReader(brand); _reader.BarcodeRead += Reader_BarcodeRead; if (_reader.Open(_currentSN)) { lblStatus.Text = $"设备 {_currentSN} 已打开"; UpdateUIStatus(); } else { MessageBox.Show("设备打开失败,请检查连接或占用状态"); } } catch (Exception ex) { MessageBox.Show($"打开设备异常: {ex.Message}"); } } private void btnClose_Click(object sender, EventArgs e) { if (_reader != null) { _reader.Close(); lblStatus.Text = "设备已关闭"; UpdateUIStatus(); } } private void btnStart_Click(object sender, EventArgs e) { if (_reader != null && _reader.IsConnected) { // 设置触发模式(根据 UI 选择) _reader.SetTriggerMode(radSoftTrigger.Checked); if (_reader.StartGrabbing()) { lblStatus.Text = "采集已开始"; UpdateUIStatus(); } } } private void btnStop_Click(object sender, EventArgs e) { if (_reader != null && _reader.IsGrabbing) { if (_reader.StopGrabbing()) { lblStatus.Text = "采集已停止"; UpdateUIStatus(); } } } private void btnSoftTrigger_Click(object sender, EventArgs e) { if (_reader != null && _reader.IsGrabbing) { _reader.SoftTrigger(); lblStatus.Text = "已执行软触发"; } else { lblStatus.Text = "请先开始采集再执行触发"; } } private void radTrigger_CheckedChanged(object sender, EventArgs e) { if (_reader != null && _reader.IsConnected) { _reader.SetTriggerMode(radSoftTrigger.Checked); lblStatus.Text = radSoftTrigger.Checked ? "已切换至软触发模式" : "已切换至硬触发/自动模式"; } } private void Reader_BarcodeRead(object sender, BarcodeEventArgs e) { // 异步更新 UI if (this.InvokeRequired) { this.BeginInvoke(new Action(Reader_BarcodeRead), sender, e); return; } try { // 更新结果列表 lstBarcodes.Items.Clear(); if (e.Barcodes != null && e.Barcodes.Count > 0) { foreach (var code in e.Barcodes) { lstBarcodes.Items.Add($"{DateTime.Now:HH:mm:ss} - {code}"); } } else { lstBarcodes.Items.Add($"{DateTime.Now:HH:mm:ss} - 未读到条码"); } // 更新预览图像 if (e.Image != null) { // 释放旧图像,防止内存泄漏 var oldImg = picPreview.Image; picPreview.Image = new Bitmap(e.Image); // 拷贝一份防止被 SDK 内部释放 oldImg?.Dispose(); } } catch (Exception ex) { // 静默处理 UI 更新异常 Console.WriteLine($"UI更新异常: {ex.Message}"); } } private void UpdateUIStatus() { bool isConnected = _reader?.IsConnected ?? false; bool isGrabbing = _reader?.IsGrabbing ?? false; btnOpen.Enabled = !isConnected; btnClose.Enabled = isConnected; cmbBrand.Enabled = !isConnected; cmbSN.Enabled = !isConnected; btnRefresh.Enabled = !isConnected; btnStart.Enabled = isConnected && !isGrabbing; btnStop.Enabled = isGrabbing; btnSoftTrigger.Enabled = isGrabbing && radSoftTrigger.Checked; grpParams.Enabled = isConnected; } private void BarcodeReaderForm_FormClosing(object sender, FormClosingEventArgs e) { // 关闭前保存参数到流程 if (_process != null) { _process.Params.Inputs["设备品牌"] = cmbBrand.Text; _process.Params.Inputs["设备SN"] = cmbSN.Text; _process.Params.Inputs["触发模式"] = radSoftTrigger.Checked ? "软触发" : "硬触发"; if (int.TryParse(txtTimeout.Text, out int timeout)) _process.Params.Inputs["超时时间"] = timeout; _process.Save(_processPath); } if (_reader != null) { if (_reader.IsGrabbing) _reader.StopGrabbing(); _reader.Close(); _reader.BarcodeRead -= Reader_BarcodeRead; _reader.Dispose(); _reader = null; } } } }