using LB_VisionProcesses.Communicators.SiemensS7; using LB_VisionProcesses.Communicators.TCom; using RJCP.IO.Ports; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.Drawing; using System.IO.Ports; using System.Linq; using System.Net.Sockets; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace LB_VisionProcesses.Communicators { public partial class CommunicatorForm : Form { BaseCommunicator communicator = new UARTPort(); CommunicatorConfig comConfig { get; set; } ConcurrentDictionary dicCommunicators { get; set; } string fullPath = string.Empty; public CommunicatorForm() { InitializeComponent(); //没有传入通讯句柄情况下可自由连接 btnConnect.Enabled = true; btnDisconnect.Enabled = false; btnSend.Enabled = false; btnRuleSend.Enabled = false; //测试功能禁用 grpTest.Enabled = false; } public CommunicatorForm(ConcurrentDictionary dicCommunicators, CommunicatorConfig comConfig, string fullPath) { InitializeComponent(); //传入通讯句柄后禁用连接/断开按键和输入控件 grpSetting.Enabled = false; this.dicCommunicators = dicCommunicators; this.comConfig = comConfig; this.fullPath = fullPath; this.Text = comConfig.strProcessName; foreach (var name in dicCommunicators.Keys) cmbCom.Items.Add(name); } private void CommunicatorForm_Load(object sender, EventArgs e) { // 使用 Enum.GetValues 获取 enum 类型的所有值 foreach (CommunicatorType type in Enum.GetValues(typeof(CommunicatorType))) { cmbType.Items.Add(type.ToString()); } //选择Com会触发ValueChanged事件,没有输入通讯口的情况下选择到-1 if (comConfig != null) { string CommunicatorName = comConfig.Params.Inputs["通讯口名"].ToString(); // 尝试转换字符串为枚举 if (!Enum.TryParse(comConfig.Params.Inputs["通讯类型"].ToString(), out CommunicatorType type)) type = CommunicatorType.Receiver; bool bRuleCheck = Convert.ToBoolean(comConfig.Params.Inputs["是否启用CRC校验"].ToString()); string Msg = comConfig.Params.Inputs["通讯消息"].ToString(); int Index = cmbCom.FindString(CommunicatorName); if (Index == -1 && cmbCom.Items.Count > 0) { //如果没有找到对应的通讯口名,则选择第一个可用的通讯口 CommunicatorName = cmbCom.Items[0].ToString(); Index = 0; } cmbCom.Text = CommunicatorName; cmbCom.SelectedIndex = Index; cmbType.Text = type.ToString(); ckbRuleCheck.Checked = bRuleCheck; txtMsg.Text = Msg; this.grpSetting.ForeColor= SystemColors.Control; } } private void cmbCom_SelectedIndexChanged(object sender, EventArgs e) { //复原原通讯口设置 if (comConfig != null) { communicator.MessageReceived -= ShowReceiveMsg; } string name = cmbCom.Text; if (dicCommunicators == null || !dicCommunicators.ContainsKey(name)) { MessageBox.Show("该通讯口不存在!"); return; } //更换通讯口 communicator = dicCommunicators[name]; communicator.MessageReceived += ShowReceiveMsg; if (communicator is UARTPort) { btnSend.Enabled = communicator.bConnected; btnRuleSend.Enabled = communicator.bConnected; cmbIP.Visible = true; txtIP.Visible = false; this.lblAddress.Visible = false; this.txtAddress.Visible = false; lblIP.Text = "串口号"; lblIP.Text = "波特率"; cmbIP.Text = communicator.CommunicatorConnections["地址"].ToString(); txtPort.Text = communicator.CommunicatorConnections["端口"].ToString(); this.grpSetting.ForeColor = SystemColors.Control; } else if (communicator is LocalMonitor) { btnSend.Enabled = communicator.bConnected; btnRuleSend.Enabled = communicator.bConnected; cmbIP.Visible = false; txtIP.Visible = true; this.lblAddress.Visible = false; this.txtAddress.Visible = false; lblIP.Text = "监控文件"; lblIP.Text = "写入文件"; txtIP.Text = communicator.CommunicatorConnections["地址"].ToString(); txtPort.Text = communicator.CommunicatorConnections["端口"].ToString(); this.grpSetting.ForeColor = SystemColors.Control; } else if (communicator is SiemensLBS7) { btnSend.Enabled = communicator.bConnected; cmbIP.Visible = false; txtIP.Visible = true; this.lblAddress.Visible = true; this.txtAddress.Visible = true; lblIP.Text = "IP"; lblIP.Text = "槽"; txtIP.Text = communicator.CommunicatorConnections["地址"].ToString(); txtPort.Text = communicator.CommunicatorConnections["端口"].ToString(); this.txtAddress.Text = communicator.CommunicatorConnections["变量地址"]?.ToString(); this.grpSetting.ForeColor = SystemColors.Control; btnRuleSend.Visible = false; } else { btnSend.Enabled = communicator.bConnected; btnRuleSend.Enabled = false; this.lblAddress.Visible = false; this.txtAddress.Visible = false; cmbIP.Visible = false; txtIP.Visible = true; lblIP.Text = " IP"; lblIP.Text = "端口"; txtIP.Text = communicator.CommunicatorConnections["地址"].ToString(); txtPort.Text = communicator.CommunicatorConnections["端口"].ToString(); } } private void cmbIP_Click(object sender, EventArgs e) { //统计可用端口 SerialPortStream temp = new SerialPortStream(); string[] ArryPort = temp.GetPortNames(); for (int i = 0; i < ArryPort.Length; i++) cmbIP.Items.Add(ArryPort[i]); } private void btnConnect_Click(object sender, EventArgs e) { if (communicator == null) return; if (communicator is UARTPort) { communicator.CommunicatorConnections.Add("地址", cmbIP.SelectedItem.ToString()); communicator.CommunicatorConnections.Add("端口", txtPort.Text); } else { communicator.CommunicatorConnections.Add("地址", txtIP.Text); communicator.CommunicatorConnections.Add("端口", txtPort.Text); } bool connectSuccess = communicator.Connect(); if (connectSuccess) { communicator.MessageReceived -= ShowReceiveMsg; communicator.MessageReceived += ShowReceiveMsg; } MessageBox.Show(connectSuccess ? "连接成功" : "连接失败,原因是" + communicator.Msg); } private void ShowReceiveMsg(string strReceiveMsg) { // 如果当前不是 UI 线程,则通过 Invoke 将操作调度到 UI 线程 if (this.InvokeRequired) { this.Invoke(new Action((msg) => { // 更新 UI 控件,比如显示接收到的消息 this.txtReceiveMsg.Text += ("[接收]" + DateTime.Now.ToString() + ":" + msg + "\r\n"); }), strReceiveMsg); } else { // 如果已经在 UI 线程上,直接更新 UI this.txtReceiveMsg.Text += ("[接收]" + DateTime.Now.ToString() + ":" + strReceiveMsg + "\r\n"); } } private void ShowSendMsg(string strSendMsg) { // 如果当前不是 UI 线程,则通过 Invoke 将操作调度到 UI 线程 if (this.InvokeRequired) { this.Invoke(new Action((msg) => { // 更新 UI 控件,比如显示接收到的消息 this.txtReceiveMsg.Text += ("[发送]" + DateTime.Now.ToString() + ":" + msg + "\r\n"); }), strSendMsg); } else { // 如果已经在 UI 线程上,直接更新 UI this.txtReceiveMsg.Text += ("[发送]" + DateTime.Now.ToString() + ":" + strSendMsg + "\r\n"); } } private void btnDisconnect_Click(object sender, EventArgs e) { if (communicator == null) return; bool result = communicator.Disconnect(); if (result) communicator.MessageReceived -= ShowReceiveMsg; MessageBox.Show(result ? "断开成功" : "断开失败,原因是:" + communicator.Msg); } private void btnSend_Click(object sender, EventArgs e) { if (communicator == null) return; communicator.SendMessage(txtSendMsg.Text); ShowSendMsg(txtSendMsg.Text); } private void btnRuleSend_Click(object sender, EventArgs e) { if (communicator == null) return; string SendMsg = txtSendMsg.Text; byte[] HexByte = BaseCommunicator.strToHexByte(SendMsg); ushort crcHexByte = BaseCommunicator.CRC16Calculate(HexByte, HexByte.Length); string crcString = crcHexByte.ToString("X4"); //HexByte = strToHexByte(strSendMsg + crcString); SendMsg = SendMsg + crcString; communicator.SendMessage(SendMsg); } private void btnRun_Click(object sender, EventArgs e) { if (communicator == null) return; // 尝试转换字符串为枚举 if (!Enum.TryParse(cmbType.Text, out CommunicatorType type)) return; CommunicatorConfig OriComConfig = new CommunicatorConfig(dicCommunicators); OriComConfig.Params.Inputs.Add("通讯口名", cmbCom.Text); OriComConfig.Params.Inputs.Add("通讯类型", type); OriComConfig.Params.Inputs.Add("是否启用CRC校验", ckbRuleCheck.Checked); OriComConfig.Params.Inputs.Add("通讯消息", txtMsg.Text); if (OriComConfig.Run()) { btnRun.BackColor = Color.Green; if (type == CommunicatorType.Receiver) ShowReceiveMsg(OriComConfig.Params.Outputs["收到消息"].ToString()); else ShowSendMsg(txtMsg.Text); } else btnRun.BackColor = Color.Red; } private void cmbIP_MouseClick(object sender, MouseEventArgs e) { cmbIP.Items.Clear(); //统计可用端口 SerialPortStream temp = new SerialPortStream(); string[] ArryPort = temp.GetPortNames(); for (int i = 0; i < ArryPort.Length; i++) cmbIP.Items.Add(ArryPort[i]); } private void CommunicatorForm_FormClosing(object sender, FormClosingEventArgs e) { //路径为空说明无需保存 if (string.IsNullOrEmpty(fullPath)) { e.Cancel = false; //确认关闭窗体 return; } DialogResult res = MessageBox.Show("是否保存?", "提示", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question); //保存结果信息 /// 参数1:显示文本,参数2:标题,参数3:按键类型,参数4:显示图标 if (res != DialogResult.Yes && res != DialogResult.No) //取消 { e.Cancel = true; //取消关闭窗体 return; } if (res == DialogResult.Yes) //保存VPP { // 尝试转换字符串为枚举 if (!Enum.TryParse(cmbType.Text, out CommunicatorType type)) { Debug.WriteLine("保存失败"); e.Cancel = false; //确认关闭窗体 return; } comConfig.Params.Inputs.Add("通讯口名", cmbCom.Text); comConfig.Params.Inputs.Add("通讯类型", type); comConfig.Params.Inputs.Add("是否启用CRC校验", ckbRuleCheck.Checked); comConfig.Params.Inputs.Add("通讯消息", txtMsg.Text); string directoryPath = Path.GetDirectoryName(fullPath); comConfig.Save(directoryPath); e.Cancel = false; //确认关闭窗体 return; } } private void CommunicatorForm_FormClosed(object sender, FormClosedEventArgs e) { if (communicator != null) communicator.MessageReceived -= ShowReceiveMsg; //路径为空说明为测试模式,需要释放通讯口 if (string.IsNullOrEmpty(fullPath) && communicator != null) communicator.Dispose(); } } }