C#上位机——父子窗口
创建一个类
第一步:主窗体建立委托
第二步:在主窗体的事件中使用委托
第三步:将副窗体中的方法赋给委托
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO.Ports;
using System.Text;
using System.Windows.Forms;namespace 串口助手
{public partial class Form1 : Form{private bool isOpen = false;private bool isRxShow = true;private List<byte> reciveBuffer = new List<byte>();private List<byte> sendBuffer = new List<byte>();private int reciveCount = 0;private int sendCount = 0;private Queue<byte> bufferQueue = null;private bool isHeadRecive = false;private int frameLenth = 0;public TransmitData transmitData;//SerialPortpublic Form1(){InitializeComponent();Control.CheckForIllegalCrossThreadCalls = false;}private void Form1_Load(object sender, EventArgs e){//在设计页面已经预先添加了COM1 COM2 COM3 //this.port_cbb.Items.Add("COM4");//this.port_cbb.Items.Add("COM5");//this.port_cbb.SelectedIndex = 2;//this.baud_cbb.SelectedIndex = 1;//this.check_cbb.SelectedIndex = 0;//this.databit_cbb.SelectedIndex = 3;//this.stopbit_cbb.SelectedIndex = 0;// 给发送框添加预设文本// this.send_rtb.Text = "我是发送框";// 给接收框添加预设文本// this.recive_rtb.Text = "我是接收框";serialLoad();// 实例化bufferQueue = new Queue<byte>();Form2 fr2 = new Form2();// 接收数据委托窗体2 ReciveData 执行显示transmitData += fr2.ReciveData;// 窗体2发送委托窗体1 sendBytes 执行发送fr2.useForm1Send += sendBytes;fr2.Show();}private void sendBytes(byte[] data){serialPort1.Write(data, 0, data.Length);sendCount += data.Length;sencount_tssl.Text = sendCount.ToString();}private void serialLoad(){EncodingInfo[] encodingInfos = Encoding.GetEncodings();RegistryKey keyCom = Registry.LocalMachine.OpenSubKey(@"Hardware\DeviceMap\SerialComm");string[] sSubKeys = keyCom.GetValueNames();port_cbb.Items.Clear();foreach (var sValue in sSubKeys){string portName = (string)keyCom.GetValue(sValue);port_cbb.Items.Add(portName);}this.port_cbb.SelectedIndex = 0;this.baud_cbb.SelectedIndex = 1;this.check_cbb.SelectedIndex = 0;this.databit_cbb.SelectedIndex = 3;this.stopbit_cbb.SelectedIndex = 0;}private void sendData(){serialPort1.Write(sendBuffer.ToArray(),0,sendBuffer.Count);sendCount += sendBuffer.Count;sencount_tssl.Text = sendCount.ToString();}private void send_btn_Click(object sender, EventArgs e){// 如果发送的数据不为空,则接收if (this.send_rtb.Text != "" && serialPort1.IsOpen){Console.WriteLine(Transform.ToHexString(sendBuffer.ToArray()));sendData();}else{MessageBox.Show("请先输入发送数据!");}}private void open_btn_Click(object sender, EventArgs e){try{if (serialPort1.IsOpen == false){serialPort1.PortName = port_cbb.Text;serialPort1.BaudRate = Convert.ToInt32(baud_cbb.Text);serialPort1.DataBits = Convert.ToInt32(databit_cbb.Text);switch (check_cbb.SelectedIndex){// none odd even case 0:serialPort1.Parity = Parity.None;break;case 1:serialPort1.Parity = Parity.Odd;break;case 2:serialPort1.Parity = Parity.Even;break;default:serialPort1.Parity = Parity.None;break;}switch (stopbit_cbb.SelectedIndex){// 1 1.5 2case 0:serialPort1.StopBits = StopBits.One;break;case 1:serialPort1.StopBits = StopBits.OnePointFive;break;case 2:serialPort1.StopBits = StopBits.Two;break;default:serialPort1.StopBits = StopBits.One;break;}serialPort1.Open();isOpen = true;open_btn.Text = "关闭串口";}else{serialPort1.Close();isOpen = false;open_btn.Text = "打开串口";}}catch (Exception ex){MessageBox.Show(ex.ToString()+serialPort1.PortName.ToString());}}private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e){if (isRxShow == false) return;// 1,需要读取有效的数据 BytesToReadbyte[] dataTemp = new byte[serialPort1.BytesToRead];serialPort1.Read(dataTemp,0,dataTemp.Length);reciveBuffer.AddRange(dataTemp);reciveCount += dataTemp.Length;//?. = 如果transmitData !=nulltransmitData?.Invoke(dataTemp);this.Invoke(new EventHandler(delegate{// 显示接收数据的长度recivecount_tssl.Text = reciveCount.ToString();if (startData_chb.Checked == false){if (!recivehex_chb.Checked){// 2, 编码格式的选择string str = Encoding.GetEncoding("gb2312").GetString(dataTemp);// 3,0x00 -> \0 结束 不会显示str = str.Replace("\0", "\\0");recive_rtb.AppendText(str);// recive_rtb.AppendText(Encoding.GetEncoding("gb2312").GetString(dataTemp).Replace("\0", "\\0"));}else{// 十六进制是选中的状态下recive_rtb.AppendText(Transform.ToHexString(dataTemp, " "));}}else{// 解析数据 queueforeach (byte item in dataTemp){// 入列bufferQueue.Enqueue(item);}// 解析获取帧头if (isHeadRecive == false){foreach (byte item in bufferQueue.ToArray()){if (item != 0x7f){// 出列bufferQueue.Dequeue();Console.WriteLine("not 0x7f, Dequeue !!");}else{// get 0x7f from bufferQueueisHeadRecive = true;Console.WriteLine("0x7f is recived !!");break;}}}if (isHeadRecive == true){// 判断有数据帧长度if (bufferQueue.Count >= 2){Console.WriteLine(DateTime.Now.ToLongTimeString());Console.WriteLine($"show the data in bufferQueue{Transform.ToHexString(bufferQueue.ToArray())}");Console.WriteLine($"frame lenth ={String.Format("{0:X2}", bufferQueue.ToArray()[1])}");frameLenth = bufferQueue.ToArray()[1];// 一帧完整的数据长度判断,不代表数据是正确的if(bufferQueue.Count>=1+1+frameLenth+2){byte[] frameBuffer = new byte[1 + 1 + frameLenth + 2];Array.Copy(bufferQueue.ToArray(), 0, frameBuffer, 0, frameBuffer.Length);if(crc_chech(frameBuffer)){Console.WriteLine("frame is check ok,pick it");data_txb.Text = Transform.ToHexString(frameBuffer);data1_txb.Text = String.Format("{0:X2}", frameBuffer[2]);data2_txb.Text = String.Format("{0:X2}", frameBuffer[3]);data3_txb.Text = String.Format("{0:X2}", frameBuffer[4]);data4_txb.Text = String.Format("{0:X2}", frameBuffer[5]);}else{// 无效数据Console.WriteLine("bad frame, drop it");}for(int i=0; i<1 + 1+frameLenth+2;i++){bufferQueue.Dequeue();}isHeadRecive = false;}}//接续接收数据}}}));}private bool crc_chech(byte[] frameBuffer){/*大端模式: 是指数据的高字节保存在内存的低地址中,* 而数据的低字节保存在内存的高地址中,这样的存储* 模式有点儿类似于把数据当作字符串顺序处理:地址* 由小向大增加,而数据从高位往低位放;这和我们的* 阅读习惯一致。* * 小端模式: 是指数据的高字节保存在内存的高地址中,* 而数据的低字节保存在内存的低地址中,这种存储模* 式将地址的高低和数据位权有效地结合起来,高地址* 部分权值高,低地址部分权值低。*/bool ret = false;byte[] temp = new byte[frameBuffer.Length-2];Array.Copy(frameBuffer, 0, temp, 0, temp.Length);byte[] crcdata = DataCheck.DataCrc16_Ccitt(temp, DataCheck.BigOrLittle.BigEndian);if (crcdata[0] == frameBuffer[frameBuffer.Length - 2] &&crcdata[1]== frameBuffer[frameBuffer.Length-1]){// check okret = true;}return ret;}private void stop_btn_Click(object sender, EventArgs e){if (isRxShow == true){isRxShow = false;stop_btn.Text = "取消暂停";}else{isRxShow = true;stop_btn.Text = "暂停";}}private void recivehex_chb_CheckedChanged(object sender, EventArgs e){if (recive_rtb.Text == "") return;if (recivehex_chb.Checked){recive_rtb.Text = Transform.ToHexString(reciveBuffer.ToArray()," ");}else{recive_rtb.Text = Encoding.GetEncoding("gb2312").GetString(reciveBuffer.ToArray()).Replace("\0","\\0");}}private void clear_btn_Click(object sender, EventArgs e){reciveBuffer.Clear();reciveCount = 0;recivecount_tssl.Text = "0";recivecount_tssl.Text = "";recive_rtb.Text = "";}private void autoclear_chb_CheckedChanged(object sender, EventArgs e){if (autoclear_chb.Checked){timer1.Start();}else{timer1.Stop();}}private void timer1_Tick(object sender, EventArgs e){if (recive_rtb.Text.Length > 4096){reciveBuffer.Clear();recive_rtb.Text = "";recivecount_tssl.Text = "";}}private void send_rtb_Leave(object sender, EventArgs e){if (sendhex_chb.CheckState == CheckState.Checked){if (DataEncoding.IsHexString(send_rtb.Text.Replace(" ", ""))){sendBuffer.Clear();sendBuffer.AddRange(Transform.ToBytes(send_rtb.Text.Replace(" ", "")));}else{MessageBox.Show("请输入正确的十六进制数据!!");send_rtb.Select();}}else{sendBuffer.Clear();sendBuffer.AddRange(Encoding.GetEncoding("gb2312").GetBytes(send_rtb.Text));}}private void send_rtb_TextChanged(object sender, EventArgs e){// 十六进制切换 会出现问题 这问题就是0x00 转换}private void sendhex_chb_CheckedChanged(object sender, EventArgs e){if (send_rtb.Text == "") return;if (sendhex_chb.Checked == true){send_rtb.Text = Transform.ToHexString(sendBuffer.ToArray(), " ");}else { send_rtb.Text = Encoding.GetEncoding("gb2312").GetString(sendBuffer.ToArray()).Replace("\0","\\0");}}private void sendclear_btn_Click(object sender, EventArgs e){sendBuffer.Clear();send_rtb.Text = "";sendCount = 0;sencount_tssl.Text = "0";}}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;namespace 串口助手
{public partial class Form2 : Form{public TransmitData useForm1Send;public Form2(){InitializeComponent();}public void ReciveData(byte[] dataTemp){// 2, 编码格式的选择string str = Encoding.GetEncoding("gb2312").GetString(dataTemp);// 3,0x00 -> \0 结束 不会显示str = str.Replace("\0", "\\0");richTextBox1.AppendText(str);}private void button1_Click(object sender, EventArgs e){useForm1Send?.Invoke(Encoding.GetEncoding("gb2312").GetBytes(textBox1.Text));}private void Form2_Load(object sender, EventArgs e){}}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;namespace 串口助手
{public delegate void TransmitData(byte[] data);public class TransmitEventAgrs:EventArgs{}
}