之前实现的消息转换器是初级版,实现比较粗糙。主要给出实现示例,和论证抽取消息转换器接口和实现消息转换中心是可行的。
这次扩展了实用性,和用“文本交互窗”论证扩展性。
一样的,“文本框交互窗口”实现转换器接口,此功能为了调试设备人为干涉消息测试使用,以及记录仪器传输日志用。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
namespace MessageSwitch
{
///<summary NoteObject="Class">
/// [功能描述:写文本实现] <para/>
/// [创建者:zlz] <para/>
/// [创建时间:2021年11月14日] <para/>
///<说明>
/// [说明:写文本实现]<para/>
///</说明>
///<修改记录>
/// [修改时间:本次修改时间]<para/>
/// [修改内容:本次修改内容]<para/>
///</修改记录>
///<修改记录>
/// [修改时间:本次修改时间]<para/>
/// [修改内容:本次修改内容]<para/>
///</修改记录>
///</summary>
public partial class UCTxtWindow : UserControl, IMessageSwitch
{
/// <summary>
/// 推送器
/// </summary>
private PushMessageToSwitch pushToSwitch;
/// <summary>
/// 类型
/// </summary>
SwitchType type;
/// <summary>
/// 写日志委托
/// </summary>
private WriteLog log;
/// <summary>
/// 唯一标识
/// </summary>
private string ID="";
/// <summary>
/// 输出出编码
/// </summary>
public Encoding Encoding
{
get;
set;
}
/// <summary>
/// 构造函数
/// </summary>
public UCTxtWindow()
{
InitializeComponent();
}
/// <summary>
/// 得到类型名字
/// </summary>
/// <returns>名字</returns>
public string GetTypeName()
{
return "文本窗" + ID;
}
/// <summary>
/// 得到配置,供主体保存配置
/// </summary>
/// <returns>配置串</returns>
public string GetConfig()
{
string confStr = txtLogPath.Text+"#"+cmbEncoding.Text;
return confStr;
}
/// <summary>
/// 设置配置,供主体用保存的配置初始化
/// </summary>
/// <param name="confStr">配置串</param>
/// <returns>是否成功</returns>
public bool SetConfig(string confStr)
{
string[] arr = confStr.Split('#');
if (arr.Length != 2)
{
MessageBox.Show("串口配置格式不对!应该是#分隔的2位", "提示");
return false;
}
txtLogPath.Text = arr[0];
cmbEncoding.Text = arr[1];
if (cmbEncoding.Text != "")
{
Encoding = GetEncodingByStr(cmbEncoding.Text);
}
return true;
}
/// <summary>
/// 设置推送委托
/// </summary>
/// <param name="push">推送器</param>
/// <param name="ptype">类型</param>
/// <param name="plog">日志委托</param>
/// <returns></returns>
public bool SetPushDelegate(PushMessageToSwitch push, SwitchType ptype, WriteLog plog)
{
pushToSwitch = push;
type = ptype;
log = plog;
return true;
}
/// <summary>
/// 启动串口
/// </summary>
/// <returns></returns>
public bool Start()
{
return true;
}
/// <summary>
/// 停止串口
/// </summary>
/// <returns></returns>
public bool Stop()
{
return true;
}
/// <summary>
/// 给串口发消息
/// </summary>
/// <param name="msgByteArr"></param>
/// <returns></returns>
public bool SendMessage(byte[] msgByteArr)
{
string lineStr = EncodingGetString(Encoding,msgByteArr);
lineStr = "接收:" + lineStr;
WritLogs(lineStr);
return true;
}
/// <summary>
/// 写日志
/// </summary>
/// <param name="log"></param>
private void WritLogs(string log)
{
try
{
if (txtLogPath.Text != "")
{
Util.WriteTxtAppend(txtLogPath.Text, log);
}
object[] para = new object[1];
para[0] = log;
this.Invoke(new WriteLog(WritLogsDo), para);
}
catch (Exception ex)
{
}
}
/// <summary>
/// 写日志
/// </summary>
/// <param name="log"></param>
private void WritLogsDo(string log)
{
if (txtReceive.Text.Length > 100000)
{
txtReceive.Text = "";
}
txtReceive.Text += DateTime.Now.ToString("HH:mm:ss ") + log + "\n";
}
/// <summary>
/// 得到反射串
/// </summary>
/// <returns>反射该实现的串</returns>
public string GetReflectStr()
{
return "MessageSwitch.UCTxtWindow,MessageSwitch.dll";
}
/// <summary>
/// 加载函数
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void UCSerialPort_Load(object sender, EventArgs e)
{
}
/// <summary>
/// 发送ASCII码
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnASCII_Click(object sender, EventArgs e)
{
Button btn = sender as Button;
object val = btn.Tag;
int valInt = Convert.ToInt32(val);
if (pushToSwitch != null)
{
string sendStr = ((char)valInt) + "";
WritLogs("发送:" + DealNotSeeToSeeChar(sendStr));
byte[] byteArray = EncodingStringToByte(Encoding,sendStr);
pushToSwitch(byteArray, type);
}
}
/// <summary>
/// 发送ASCII
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnASCII_Click_1(object sender, EventArgs e)
{
string val = txtASCIIVal.Text;
if (val != "")
{
int valInt = Convert.ToInt32(val);
if (pushToSwitch != null)
{
string sendStr = ((char)valInt) + "";
WritLogs("发送:" + DealNotSeeToSeeChar(sendStr));
byte[] byteArray = EncodingStringToByte(Encoding,sendStr);
pushToSwitch(byteArray, type);
}
}
}
/// <summary>
/// 发送串
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnSend_Click(object sender, EventArgs e)
{
string val = txtSend.Text;
if (val != "")
{
if (pushToSwitch != null)
{
WritLogs("发送:" + DealNotSeeToSeeChar(val));
byte[] byteArray = EncodingStringToByte(Encoding,val);
pushToSwitch(byteArray, type);
}
txtSend.Text = "";
}
}
/// <summary>
/// 选择日志路径
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnLogPath_Click(object sender, EventArgs e)
{
SaveFileDialog sf = new SaveFileDialog();
if (sf.ShowDialog() == DialogResult.OK)
{
txtLogPath.Text = sf.FileName;
}
}
/// <summary>
/// 处理不可见字符
/// </summary>
/// <param name="data">数据</param>
/// <returns>返回</returns>
public string DealNotSeeToSeeChar(string data)
{
for (int i = 0; i <= 31; i++)
{
if (i == 6)
{
data = data.Replace((char)i + "", "[ACK]");
}
else if (i == 5)
{
data = data.Replace((char)i + "", "[ENQ]");
}
else if (i == 4)
{
data = data.Replace((char)i + "", "[EOT]");
}
else if (i == 3)
{
data = data.Replace((char)i + "", "[ETX]");
}
else if (i == 2)
{
data = data.Replace((char)i + "", "[STX]");
}
else
{
data = data.Replace((char)i + "", "[" + i + "]");
}
}
data.Replace((char)127 + "", "[127]");
return data;
}
/// <summary>
/// 按字符串得到编码格式
/// </summary>
/// <param name="eco"></param>
/// <returns></returns>
private Encoding GetEncodingByStr(string eco)
{
if (eco == "Default")
{
return Encoding.Default;
}
else if (eco == "ASCII")
{
return Encoding.ASCII;
}
else if (eco == "UTF8")
{
return Encoding.UTF8;
}
else if (eco == "Unicode")
{
return Encoding.Unicode;
}
else if (eco == "UTF32")
{
return Encoding.UTF32;
}
else if (eco == "UTF7")
{
return Encoding.UTF7;
}
else if (eco == "BigEndianUnicode")
{
return Encoding.BigEndianUnicode;
}
return Encoding.Default;
}
/// <summary>
/// 按字符串得到编码格式
/// </summary>
/// <param name="eco"></param>
/// <returns></returns>
public string GetEncodingStr(Encoding eco)
{
if (eco == Encoding.Default)
{
return "Default";
}
else if (eco == Encoding.ASCII)
{
return "ASCII";
}
else if (eco == Encoding.UTF8)
{
return "UTF8";
}
else if (eco == Encoding.Unicode)
{
return "Unicode";
}
else if (eco == Encoding.UTF32)
{
return "UTF32";
}
else if (eco == Encoding.UTF7)
{
return "UTF7";
}
else if (eco == Encoding.BigEndianUnicode)
{
return "BigEndianUnicode";
}
return "Default";
}
/// <summary>
/// 按编码得到串
/// </summary>
/// <param name="encode">编码</param>
/// <param name="msgByteArr">比特</param>
/// <returns></returns>
private string EncodingGetString(Encoding encode, byte[] msgByteArr)
{
string lineStr = "";
if (encode != null && encode != Encoding.Default)
{
if (encode == Encoding.ASCII)
{
lineStr = System.Text.Encoding.ASCII.GetString(msgByteArr);
}
else if (encode == Encoding.UTF8)
{
lineStr = System.Text.Encoding.UTF8.GetString(msgByteArr);
}
else if (encode == Encoding.Unicode)
{
lineStr = System.Text.Encoding.Unicode.GetString(msgByteArr);
}
else if (encode == Encoding.UTF32)
{
lineStr = System.Text.Encoding.UTF32.GetString(msgByteArr);
}
else if (encode == Encoding.UTF7)
{
lineStr = System.Text.Encoding.UTF7.GetString(msgByteArr);
}
else if (encode == Encoding.BigEndianUnicode)
{
lineStr = System.Text.Encoding.BigEndianUnicode.GetString(msgByteArr);
}
}
else
{
lineStr = System.Text.Encoding.Default.GetString(msgByteArr);
}
return lineStr;
}
/// <summary>
/// 按编码转换串到比特数组
/// </summary>
/// <param name="encode">编码</param>
/// <param name="str">字符串</param>
/// <returns>比特数组</returns>
private byte[] EncodingStringToByte(Encoding encode, string str)
{
byte[] byteArray = null;
if (encode != null && encode != Encoding.Default)
{
if (encode == Encoding.ASCII)
{
byteArray = System.Text.Encoding.ASCII.GetBytes(str);
}
else if (encode == Encoding.UTF8)
{
byteArray = System.Text.Encoding.UTF8.GetBytes(str);
}
else if (encode == Encoding.Unicode)
{
byteArray = System.Text.Encoding.Unicode.GetBytes(str);
}
else if (encode == Encoding.UTF32)
{
byteArray = System.Text.Encoding.UTF32.GetBytes(str);
}
else if (encode == Encoding.UTF7)
{
byteArray = System.Text.Encoding.UTF7.GetBytes(str);
}
else if (encode == Encoding.BigEndianUnicode)
{
byteArray = System.Text.Encoding.BigEndianUnicode.GetBytes(str);
}
}
else
{
byteArray = System.Text.Encoding.Default.GetBytes(str);
}
return byteArray;
}
/// <summary>
/// 选择编码
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void cmbEncoding_SelectedValueChanged(object sender, EventArgs e)
{
if (cmbEncoding.Text == "Default")
{
Encoding = Encoding.Default;
}
else if (cmbEncoding.Text == "ASCII")
{
Encoding = Encoding.ASCII;
}
else if (cmbEncoding.Text == "UTF8")
{
Encoding = Encoding.UTF8;
}
else if (cmbEncoding.Text == "Unicode")
{
Encoding = Encoding.Unicode;
}
else if (cmbEncoding.Text == "UTF32")
{
Encoding = Encoding.UTF32;
}
else if (cmbEncoding.Text == "UTF7")
{
Encoding = Encoding.UTF7;
}
else if (cmbEncoding.Text == "BigEndianUnicode")
{
Encoding = Encoding.BigEndianUnicode;
}
}
}
}
然后增加输入端和输出端编码转换功能,以支持M接口不好处理的编码格式。
最终实现的“文本框交互窗口”可以开两个程序当聊天程序使用。
所有实现转换器接口的模块都能借助转换中心跳转,理论上没有跳的次数限制等。具体玩法和实现什么样的接口实例就看想象力和运用场景了。