using BWP.WinFormControl; using BWP.WinFormControl.WeightDataFormat; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace ButcherWeight { partial class WeightForm { private IDataFormat _dataFormat; private Thread _inQueryThread, _outQueryThread; private bool _mainProcessIsRun; readonly StringBuilder _dataStrBuilder = new StringBuilder(); readonly ConcurrentQueue _dataQueue = new ConcurrentQueue(); private const int WmUpdDisplayMessage = 0x0500 + 2; private string _displayValue; private int _mainHandle; int MainHandle { get { if (_mainHandle == 0) { _mainHandle = WinApiSendMessage.FindWindow(null, this.Text); } return _mainHandle; } } void OpenSerialPort() { if (enableCheckBox.Checked) return; if (WeightContext.Config.RateSet == null) throw new Exception("请先配置称相关信息"); weightSerialPort.PortName = WeightContext.Config.ComSet; weightSerialPort.BaudRate = WeightContext.Config.RateSet.Value; weightSerialPort.DataBits = WeightContext.Config.BitSet.Value; weightSerialPort.ReadBufferSize = 4096 * 100; if (!string.IsNullOrEmpty(WeightContext.Config.Format)) format = "{0:{format}}".Replace("{format}", WeightContext.Config.Format); switch (WeightContext.Config.WeightSet) { case "IND560": _dataFormat = new IND560DataFormat(); break; case "Xk3124": _dataFormat = new Xk3124DataFormat(); break; case "Xk3190A9": _dataFormat = new Xk3190A9DataFormat(); break; default: _dataFormat = new Xk3190D10DataFormat(); break; } if (!weightSerialPort.IsOpen) { try { weightSerialPort.Open(); } catch (InvalidOperationException) { MessageBox.Show(@"指定的端口已打开"); } catch (UnauthorizedAccessException) { MessageBox.Show(@"对端口的访问被拒绝"); } } } void ReadData() { _inQueryThread = new Thread(InQuery); _inQueryThread.Start(); _outQueryThread = new Thread(OutQuery); _outQueryThread.Start(); } string format = "{0:0.00}"; private void InQuery() { while (_mainProcessIsRun) { int availableCount = weightSerialPort.BytesToRead; if (availableCount == 0) { Thread.Sleep(1); } char[] buffer = new char[availableCount]; if (!weightSerialPort.IsOpen) { continue; } weightSerialPort.Read(buffer, 0, availableCount); foreach (var c in buffer) { if (c == _dataFormat.Beginchar) { _dataStrBuilder.Clear(); _dataStrBuilder.Append(c); } else if (c == _dataFormat.Endchar || _dataStrBuilder.Length > _dataFormat.Bufsize) { _dataStrBuilder.Append(c); _dataQueue.Enqueue(_dataStrBuilder.ToString()); _dataStrBuilder.Clear(); } else { _dataStrBuilder.Append(c); } } } } private void OutQuery() { while (_mainProcessIsRun) { try { bool isStatic; string str; string subStr; if (!_dataQueue.TryDequeue(out subStr)) { Thread.Sleep(1); continue; } // 解析接受的端口数据 if (_dataFormat.ParseAscii(subStr, out str, out isStatic)) { if (string.IsNullOrEmpty(str)) str = "0"; _displayValue = string.Format(format, decimal.Parse(str)); WinApiSendMessage.SendMessage(MainHandle, WmUpdDisplayMessage, 0, 0); } } catch (Exception) { Thread.Sleep(1000); continue; } Thread.Sleep(1); } } void DisableWeight() { _mainProcessIsRun = false; WeightValue = 0; format = "{0:0.00}"; Thread.Sleep(10); if (_inQueryThread.IsAlive) { _inQueryThread.Abort(); } if (_outQueryThread.IsAlive) { _outQueryThread.Abort(); } if (weightSerialPort.IsOpen) weightSerialPort.Close(); } public void enableCheckBox_Click(object sender, EventArgs e) { if (!enableCheckBox.Checked) { OpenSerialPort(); _mainProcessIsRun = true; ReadData(); } else DisableWeight(); enableCheckBox.CheckState = enableCheckBox.Checked ? CheckState.Unchecked : CheckState.Checked; readMaoBtn.Enabled = readPiBtn.Enabled = enableCheckBox.Checked; } decimal? WeightValue { get { if (!string.IsNullOrEmpty(weightLabel.Text)) return decimal.Parse(weightLabel.Text); return null; } set { weightLabel.Text = string.Format(format, value); } } protected override void DefWndProc(ref Message m) { switch (m.Msg) { case WmUpdDisplayMessage: weightLabel.Text = string.Format(format, decimal.Parse(_displayValue)); break; default: base.DefWndProc(ref m); break; } } } }