diff --git a/.gitignore b/.gitignore
index 7bf46c5..94d1d68 100644
--- a/.gitignore
+++ b/.gitignore
@@ -30,3 +30,13 @@ bld/
/XCoder40/Entity
/XCoder40/obj4
/Config
+/netcoreapp3.0
+/XCoder.pdb
+/XCoder.exe.config
+/XCoder.exe
+/XCode.pdb
+/XCode.dll
+/NewLife.Net.pdb
+/NewLife.Net.dll
+/NewLife.Core.pdb
+/NewLife.Core.dll
diff --git a/XCoder/XCom/SerialTransport.cs b/XCoder/XCom/SerialTransport.cs
index 1284846..1ebf425 100644
--- a/XCoder/XCom/SerialTransport.cs
+++ b/XCoder/XCom/SerialTransport.cs
@@ -373,6 +373,7 @@ namespace NewLife.Net
public static Dictionary<String, String> GetNames()
{
var dic = new Dictionary<String, String>(StringComparer.OrdinalIgnoreCase);
+#if !NC30
using (var key = Registry.LocalMachine.OpenSubKey(@"HARDWARE\DEVICEMAP\SERIALCOMM", false))
using (var usb = Registry.LocalMachine.OpenSubKey(@"SYSTEM\CurrentControlSet\Enum\USB", false))
{
@@ -417,6 +418,8 @@ namespace NewLife.Net
}
}
}
+#endif
+
return dic;
}
diff --git a/XCoderLinux/Program.cs b/XCoderLinux/Program.cs
index 2db58c5..6f56138 100644
--- a/XCoderLinux/Program.cs
+++ b/XCoderLinux/Program.cs
@@ -24,6 +24,7 @@ namespace XCoder
Application.Init();
var window = new SharpApp();
window.ShowAll();
+ // Window.InteractiveDebugging = true;
//XTrace2.UseWinForm(window);
Application.Run();
}
diff --git a/XCoderLinux/SharpApp.cs b/XCoderLinux/SharpApp.cs
index 8d06a03..a13f2d5 100644
--- a/XCoderLinux/SharpApp.cs
+++ b/XCoderLinux/SharpApp.cs
@@ -7,7 +7,8 @@ using Gdk;
using Gtk;
using NewLife.Reflection;
//using XApi;
-using XNet;
+//using XNet;
+using XCom;
using Window = Gtk.Window;
namespace XCoder
@@ -40,13 +41,12 @@ namespace XCoder
private void SharpApp_Shown(System.Object sender, System.EventArgs e)
{
var set = XConfig.Current;
- //if (set.Width > 0 || set.Height > 0)
- //{
- // WidthRequest = set.Width;
- // //Top = set.Top;
- // //Left = set.Left;
- // HeightRequest = set.Height;
- //}
+ if (set.Width > 0 || set.Height > 0)
+ {
+ DefaultWidth = set.Width;
+ DefaultHeight = set.Height;
+ //SetDefaultSize(set.Width, set.Height);
+ }
SetPosition(WindowPosition.Center);
@@ -54,9 +54,9 @@ namespace XCoder
AddMenu();
- //var xapi = new FrmMain();
+ var frm = new FrmMain();
- //_windowBox.PackStart(xapi, true, true, 0);
+ _windowBox.PackStart(frm, true, true, 0);
Add(_windowBox);
diff --git a/XCoderLinux/XCoderLinux.csproj b/XCoderLinux/XCoderLinux.csproj
index be84ff4..1158eff 100644
--- a/XCoderLinux/XCoderLinux.csproj
+++ b/XCoderLinux/XCoderLinux.csproj
@@ -31,6 +31,8 @@
<Compile Include="..\XCoder\IXForm.cs" Link="IXForm.cs" />
<Compile Include="..\XCoder\XApi\ApiConfig.cs" Link="XApi\ApiConfig.cs" />
<Compile Include="..\XCoder\XApi\MyApiController.cs" Link="XApi\MyApiController.cs" />
+ <Compile Include="..\XCoder\XCom\SerialPortConfig.cs" Link="XCom\SerialPortConfig.cs" />
+ <Compile Include="..\XCoder\XCom\SerialTransport.cs" Link="XCom\SerialTransport.cs" />
<Compile Include="..\XCoder\XNet\BenchHelper.cs" Link="XNet\BenchHelper.cs" />
<Compile Include="..\XCoder\XNet\IPPacket.cs" Link="XNet\IPPacket.cs" />
<Compile Include="..\XCoder\XNet\MySqlParser.cs" Link="XNet\MySqlParser.cs" />
@@ -44,6 +46,7 @@
<PackageReference Include="GtkSharp" Version="3.22.25.24" />
<PackageReference Include="NewLife.Core" Version="8.4.2019.1109" />
<PackageReference Include="NewLife.XCode" Version="9.14.2019.1109" />
+ <PackageReference Include="System.IO.Ports" Version="4.6.0" />
</ItemGroup>
<ItemGroup>
@@ -51,6 +54,17 @@
<Folder Include="Engine\" />
</ItemGroup>
+ <ItemGroup>
+ <Compile Update="XCom\FrmMain.cs" />
+ <Compile Update="XCom\FrmMain.designer.cs">
+ <DependentUpon>FrmMain.cs</DependentUpon>
+ </Compile>
+ <Compile Update="XCom\SerialPortList.cs" />
+ <Compile Update="XCom\SerialPortList.designer.cs">
+ <DependentUpon>SerialPortList.cs</DependentUpon>
+ </Compile>
+ </ItemGroup>
+
<!--<ItemGroup>
<Reference Include="NewLife.Core">
<HintPath>..\..\Bin\netstandard2.1\NewLife.Core.dll</HintPath>
diff --git a/XCoderLinux/XCom/FrmMain.cs b/XCoderLinux/XCom/FrmMain.cs
new file mode 100644
index 0000000..f0f211b
--- /dev/null
+++ b/XCoderLinux/XCom/FrmMain.cs
@@ -0,0 +1,220 @@
+using System;
+using System.ComponentModel;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using Gtk;
+using NewLife.Log;
+using NewLife.Threading;
+using NewLife.Windows;
+using XCoder;
+using XCoder.Util;
+
+namespace XCom
+{
+ [DisplayName("串口调试工具")]
+ public partial class FrmMain : VBox, IXForm
+ {
+ /// <summary>业务日志输出</summary>
+ ILog BizLog;
+
+ #region 窗体
+ public FrmMain()
+ {
+ InitializeComponent();
+
+ // 动态调节宽度高度,兼容高DPI
+ //this.FixDpi();
+
+ //Icon = IcoHelper.GetIcon("串口");
+ }
+
+ private void FrmMain_Load(Object sender, EventArgs e)
+ {
+ var log = TextFileLog.Create(null, "Serial_{0:yyyy_MM_dd}.log");
+ BizLog = txtReceive.Combine(log);
+ txtReceive.UseWinFormControl();
+
+ //txtReceive.SetDefaultStyle(12);
+ //txtSend.SetDefaultStyle(12);
+ //numMutilSend.SetDefaultStyle(12);
+
+ //gbReceive.Tag = gbReceive.Label;
+ //gbSend.Tag = gbSend.Label;
+
+ //var menu = spList.Menu;
+ //txtReceive.ContextMenuStrip = menu;
+
+ //// 添加清空
+ //menu.Items.Insert(0, new ToolStripSeparator());
+ //var ti = new ToolStripMenuItem("清空");
+ //menu.Items.Insert(0, ti);
+ //ti.Click += mi清空_Click;
+
+ // 加载保存的颜色
+ //UIConfig.Apply(txtReceive);
+
+ //ti = new ToolStripMenuItem("日志着色");
+ //ti.Name = "日志着色";
+ //menu.Items.Insert(2, ti);
+ //ti.Click += miCheck_Click;
+ //ti.Checked = XConfig.Current.ColorLog;
+ }
+ #endregion
+
+ #region 收发数据
+ void Connect()
+ {
+ spList.Connect();
+ var st = spList.Port;
+ //st.FrameSize = 8;
+ if (st == null) return;
+
+ // 需要考虑UI线程
+ st.Disconnected += Disconnect;
+
+ // 发现USB2401端口,自动发送设置命令
+ if (st.Description.Contains("USB2401") || st.Description.Contains("USBSER"))
+ {
+ var cmd = "AT+SET=00070000000000";
+ st.Send(cmd.GetBytes());
+ BizLog.Info(cmd);
+ //TextControlLog.WriteLog(txtReceive, cmd);
+ }
+
+ "连接串口{0}".F(st.PortName).SpeechTip();
+
+ btnConnect.Label = "关闭";
+
+ //var menu = txtReceive.ContextMenuStrip;
+ //var mi = menu.Items.Find("日志着色", false).FirstOrDefault() as ToolStripMenuItem;
+
+ var cfg = XConfig.Current;
+ //cfg.ColorLog = mi.Checked;
+ cfg.Save();
+ }
+
+ void Disconnect(Object sender, EventArgs e) =>
+ Application.Invoke((s, e) =>
+ {
+ //if (spList.Enabled) return;
+ if (btnConnect.Label == "打开") return;
+
+ var st = spList.Port;
+ if (st != null) st.Disconnected -= Disconnect;
+ spList.Disconnect();
+
+ "串口已断开".SpeechTip();
+
+ btnConnect.Label = "打开";
+ });
+
+ private void btnConnect_Click(Object sender, EventArgs e)
+ {
+ var btn = sender as Button;
+ if (btn.Label == "打开")
+ Connect();
+ else
+ Disconnect(null, null);
+ }
+
+ void OnReceived(Object sender, StringEventArgs e)
+ {
+ var line = e.Value;
+ //TextControlLog.WriteLog(txtReceive, line);
+
+ BizLog?.Info(line);
+ }
+
+ Int32 _pColor = 0;
+ Int32 lastReceive = 0;
+ Int32 lastSend = 0;
+ //private void timer1_Tick(Object sender, EventArgs e)
+ //{
+ // var sp = spList.Port;
+ // if (sp != null)
+ // {
+ // // 检查串口是否已断开,自动关闭已断开的串口,避免内存暴涨
+ // if (!spList.Sensitive && btnConnect.Label == "打开")
+ // {
+ // Disconnect(null,null);
+ // return;
+ // }
+
+ // var rcount = spList.BytesOfReceived;
+ // var tcount = spList.BytesOfSent;
+ // if (rcount != lastReceive)
+ // {
+ // gbReceive.Label = (gbReceive.Tag + "").Replace("0", rcount + "");
+ // lastReceive = rcount;
+ // }
+ // if (tcount != lastSend)
+ // {
+ // gbSend.Label = (gbSend.Tag + "").Replace("0", tcount + "");
+ // lastSend = tcount;
+ // }
+
+ // var set = XConfig.Current;
+ // if (set.ColorLog) txtReceive.ColourDefault(_pColor);
+ // _pColor = txtReceive.TextLength;
+ // }
+ //}
+
+ private void btnSend_Click(Object sender, EventArgs e)
+ {
+ var str = txtSend.Buffer.Text;
+ if (String.IsNullOrEmpty(str))
+ {
+ MessageBox.Show("发送内容不能为空!");
+ //txtSend.Focus();
+ return;
+ }
+
+ // 多次发送
+ var count = (Int32)numMutilSend.Value;
+ var sleep = (Int32)numSleep.Value;
+ if (count <= 0) count = 1;
+ if (sleep <= 0) sleep = 100;
+
+ // 处理换行
+ str = str.Replace("\n", "\r\n");
+
+ if (count == 1)
+ {
+ spList.Send(str);
+ return;
+ }
+
+ ThreadPoolX.QueueUserWorkItem(() =>
+ {
+ for (var i = 0; i < count; i++)
+ {
+ spList.Send(str);
+
+ if (count > 1) Thread.Sleep(sleep);
+ }
+ });
+ }
+ #endregion
+
+ #region 右键菜单
+ private void mi清空_Click(Object sender, EventArgs e)
+ {
+ txtReceive.Buffer.Clear();
+ spList.ClearReceive();
+ }
+
+ private void mi清空2_Click(Object sender, EventArgs e)
+ {
+ txtSend.Buffer.Clear();
+ spList.ClearSend();
+ }
+
+ //private void miCheck_Click(Object sender, EventArgs e)
+ //{
+ // //var mi = sender as ToolStripMenuItem;
+ // //mi.Checked = !mi.Checked;
+ //}
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/XCoderLinux/XCom/FrmMain.designer.cs b/XCoderLinux/XCom/FrmMain.designer.cs
new file mode 100644
index 0000000..2704bb1
--- /dev/null
+++ b/XCoderLinux/XCom/FrmMain.designer.cs
@@ -0,0 +1,457 @@
+using Gtk;
+using NewLife.Windows;
+
+namespace XCom
+{
+ partial class FrmMain
+ {
+ #region Windows 窗体设计器生成的代码
+
+ /// <summary>
+ /// </summary>
+ private void InitializeComponent()
+ {
+ this.gbReceive = new Frame();
+ this.txtReceiveScrolledWindow = new ScrolledWindow();
+ this.txtReceive = new TextView();
+ //this.menuReceive = new ContextMenuStrip(this.components);
+ //this.toolStripMenuItem1 = new ToolStripMenuItem();
+ //this.mi日志着色 = new ToolStripMenuItem();
+ //this.toolStripMenuItem3 = new ToolStripSeparator();
+ //this.mi显示应用日志 = new ToolStripMenuItem();
+ //this.mi显示编码日志 = new ToolStripMenuItem();
+ //this.mi显示发送数据 = new ToolStripMenuItem();
+ //this.mi显示接收数据 = new ToolStripMenuItem();
+ //this.mi显示统计信息 = new ToolStripMenuItem();
+ //this.menuSend = new ContextMenuStrip(this.components);
+ //this.mi清空2 = new ToolStripMenuItem();
+ this.btnConnect = new Button();
+ //this.timer1 = new Timer(this.components);
+ //this.fontDialog1 = new FontDialog();
+ //this.colorDialog1 = new ColorDialog();
+ this.label1 = new Label();
+ this.lbAddr = new Label();
+ this.cbMode = new ComboBox(new string[] { });
+ this.cbLocal = new ComboBox(new string[] { });
+ this.cbRemote = ComboBoxText.NewWithEntry();
+ this.pnlSetting = new HBox();
+ this.numPort = new SpinButton(1, 63353, 1);
+ this.label5 = new Label();
+ this.gbSend = new Frame();
+ this.boxSend = new VBox();
+ this.boxSendSetting = new HBox();
+ this.numThreads = new SpinButton(1, 100000, 1);
+ this.numSleep = new SpinButton(1000, 1000000, 1);
+ this.txtSendScrolledWindow = new ScrolledWindow();
+ this.txtSend = new TextView();
+ this.btnSend = new Button();
+ this.numMutilSend = new SpinButton(1, 1000000, 1);
+ this.label2 = new Label();
+ this.label7 = new Label();
+ this.label8 = new Label();
+ //this.toolTip1 = new ToolTip(this.components);
+ this.spList = new SerialPortList();
+ //
+ // gbReceive
+ //
+ this.gbReceive.Add(this.txtReceiveScrolledWindow);
+ this.gbReceive.Margin = 2;
+ this.gbReceive.Name = "gbReceive";
+ //this.gbReceive.SetSizeRequest(878, 298);
+ // gbReceive.Margin = 10;
+ this.gbReceive.Label = "接收区:已接收0字节";
+ //this.gbReceive.Halign = Align.Fill;
+ //this.gbReceive.Valign = Align.Fill;
+ this.gbReceive.ShadowType = ShadowType.Out;
+ //
+ // txtReceiveScrolledWindow
+ //
+ this.txtReceiveScrolledWindow.Add(this.txtReceive);
+ this.txtReceiveScrolledWindow.CanFocus = true;
+ this.txtReceiveScrolledWindow.ShadowType = ShadowType.In;
+ //this.txtReceiveScrolledWindow.Vexpand = true;
+ //
+ // txtReceive
+ //
+ // this.txtReceive.ContextMenuStrip = this.menuReceive;
+ // this.txtReceive.Dock = DockStyle.Fill;
+ // this.txtReceive.HideSelection = false;
+ // this.txtReceive.Location = new System.Drawing.Point(4, 25);
+ this.txtReceive.Margin = 1;
+ this.txtReceive.Name = "txtReceive";
+ // this.txtReceive.Size = new System.Drawing.Size(970, 269);
+ this.txtReceive.Editable = false;
+ // 滚动方法 https://stackoverflow.com/questions/37824865/gtk-textview-auto-scroll-when-text-is-added-to-text-buffer
+ this.txtReceive.SizeAllocated += TxtReceive_SizeAllocated;
+ ////
+ //// menuReceive
+ ////
+ //this.menuReceive.ImageScalingSize = new System.Drawing.Size(32, 32);
+ //this.menuReceive.Items.AddRange(new ToolStripItem[] {
+ //this.toolStripMenuItem1,
+ //this.mi日志着色,
+ //this.toolStripMenuItem3,
+ //this.mi显示应用日志,
+ //this.mi显示编码日志,
+ //this.mi显示发送数据,
+ //this.mi显示接收数据,
+ //this.mi显示统计信息});
+ //this.menuReceive.Name = "menuSend";
+ //this.menuReceive.Size = new System.Drawing.Size(189, 206);
+ ////
+ //// toolStripMenuItem1
+ ////
+ //this.toolStripMenuItem1.Name = "toolStripMenuItem1";
+ //this.toolStripMenuItem1.Size = new System.Drawing.Size(188, 28);
+ //this.toolStripMenuItem1.Text = "清空";
+ //this.toolStripMenuItem1.Click += new System.EventHandler(this.mi清空_Click);
+ ////
+ //// mi日志着色
+ ////
+ //this.mi日志着色.Name = "mi日志着色";
+ //this.mi日志着色.Size = new System.Drawing.Size(188, 28);
+ //this.mi日志着色.Text = "日志着色";
+ //this.mi日志着色.Click += new System.EventHandler(this.miCheck_Click);
+ ////
+ //// toolStripMenuItem3
+ ////
+ //this.toolStripMenuItem3.Name = "toolStripMenuItem3";
+ //this.toolStripMenuItem3.Size = new System.Drawing.Size(185, 6);
+ ////
+ //// mi显示应用日志
+ ////
+ //this.mi显示应用日志.Name = "mi显示应用日志";
+ //this.mi显示应用日志.Size = new System.Drawing.Size(188, 28);
+ //this.mi显示应用日志.Text = "显示应用日志";
+ //this.mi显示应用日志.Click += new System.EventHandler(this.miCheck_Click);
+ ////
+ //// mi显示编码日志
+ ////
+ //this.mi显示编码日志.Name = "mi显示编码日志";
+ //this.mi显示编码日志.Size = new System.Drawing.Size(188, 28);
+ //this.mi显示编码日志.Text = "显示编码日志";
+ //this.mi显示编码日志.Click += new System.EventHandler(this.miCheck_Click);
+ ////
+ //// mi显示发送数据
+ ////
+ //this.mi显示发送数据.Name = "mi显示发送数据";
+ //this.mi显示发送数据.Size = new System.Drawing.Size(188, 28);
+ //this.mi显示发送数据.Text = "显示发送数据";
+ //this.mi显示发送数据.Click += new System.EventHandler(this.miCheck_Click);
+ ////
+ //// mi显示接收数据
+ ////
+ //this.mi显示接收数据.Name = "mi显示接收数据";
+ //this.mi显示接收数据.Size = new System.Drawing.Size(188, 28);
+ //this.mi显示接收数据.Text = "显示接收数据";
+ //this.mi显示接收数据.Click += new System.EventHandler(this.miCheck_Click);
+ ////
+ //// mi显示统计信息
+ ////
+ //this.mi显示统计信息.Name = "mi显示统计信息";
+ //this.mi显示统计信息.Size = new System.Drawing.Size(188, 28);
+ //this.mi显示统计信息.Text = "显示统计信息";
+ //this.mi显示统计信息.Click += new System.EventHandler(this.miCheck_Click);
+ ////
+ //// menuSend
+ ////
+ //this.menuSend.ImageScalingSize = new System.Drawing.Size(32, 32);
+ //this.menuSend.Items.AddRange(new ToolStripItem[] {
+ //this.mi清空2});
+ //this.menuSend.Name = "menuSend";
+ //this.menuSend.Size = new System.Drawing.Size(117, 32);
+ ////
+ //// mi清空2
+ ////
+ //this.mi清空2.Name = "mi清空2";
+ //this.mi清空2.Size = new System.Drawing.Size(116, 28);
+ //this.mi清空2.Text = "清空";
+ //this.mi清空2.Click += new System.EventHandler(this.mi清空2_Click);
+ //
+ // btnConnect
+ //
+ // this.btnConnect.Location = new System.Drawing.Point(748, 12);
+ this.btnConnect.Margin = 4;
+ this.btnConnect.Name = "btnConnect";
+ // this.btnConnect.Size = new System.Drawing.Size(100, 44);
+ // this.btnConnect.TabIndex = 3;
+ this.btnConnect.Label = "打开";
+ this.btnConnect.Clicked += new System.EventHandler(this.btnConnect_Click);
+ ////
+ //// timer1
+ ////
+ //this.timer1.Enabled = true;
+ //this.timer1.Interval = 300;
+ //this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
+ //
+ // label1
+ //
+ //this.label1.AutoSize = true;
+ this.label1.Xalign = 0.8F;
+ this.label1.Yalign = 0.5F;
+ this.label1.MarginTop = 4;
+ this.label1.MarginBottom = 4;
+ this.label1.Name = "label1";
+ //this.label1.WidthRequest = 62;
+ //this.label1.HeightRequest = 18;
+ this.label1.Text = "模式:";
+ //
+ // lbAddr
+ //
+ // this.lbAddr.AutoSize = true;
+ // this.lbAddr.Location = new System.Drawing.Point(374, 14);
+ this.lbAddr.Xalign = 0.8F;
+ this.lbAddr.Yalign = 0.5F;
+ this.lbAddr.MarginTop = 4;
+ this.lbAddr.MarginBottom = 4;
+ this.lbAddr.Name = "lbAddr";
+ //this.lbAddr.WidthRequest = 62;
+ //this.lbAddr.HeightRequest = 18;
+ this.lbAddr.Text = "远程:";
+ //
+ // cbMode
+ //
+ //this.cbMode.DropDownStyle = ComboBoxStyle.DropDownList;
+ //this.cbMode.FormattingEnabled = true;
+ //this.cbMode.Location = new System.Drawing.Point(72, 11);
+ //this.cbMode.Margin = 4;
+ this.cbMode.Active = 1;
+ this.cbMode.Name = "cbMode";
+ //this.cbMode.SetSizeRequest(1, 1);
+ //this.cbMode.Changed += new System.EventHandler(this.cbMode_SelectedIndexChanged);
+ //
+ // cbLocal
+ //
+ //this.cbLocal.Active = 1;
+ this.cbLocal.Name = "cbLocal";
+ //this.cbLocal.SetSizeRequest(1, 1);
+ //this.cbLocal.Changed += new System.EventHandler(this.cbLocal_SelectedIndexChanged);
+ //
+ // cbRemote
+ //
+ //this.cbRemote.Margin = 4;
+ this.cbRemote.Name = "cbRemote";
+ //this.cbRemote.SetSizeRequest(200, 18);
+ // this.cbRemote.Size = new System.Drawing.Size(247, 26);
+ this.cbRemote.Sensitive = true;
+ //this.cbRemote.
+ //
+ // spList
+ //
+ this.spList.BytesOfReceived = 0;
+ this.spList.BytesOfSent = 0;
+ this.spList.Name = "spList";
+ this.spList.Port = null;
+ this.spList.SelectedPort = "COM1(Serial0)";
+ this.spList.ReceivedString += new System.EventHandler<NewLife.Windows.StringEventArgs>(this.OnReceived);
+ //
+ // pnlSetting
+ //
+ this.pnlSetting.PackStart(this.spList, false, false, 1);
+ //this.pnlSetting.PackStart(this.label1, false, false, 1);
+ //this.pnlSetting.PackStart(this.cbMode, false, false, 1);
+ //this.pnlSetting.PackStart(this.label5, false, false, 1);
+ //this.pnlSetting.PackStart(this.cbLocal, false, false, 1);
+ //this.pnlSetting.PackStart(this.lbAddr, false, false, 1);
+ //this.pnlSetting.PackStart(this.cbRemote, false, false, 1);
+ //this.pnlSetting.PackStart(this.numPort, false, false, 1);
+ this.pnlSetting.PackStart(this.btnConnect, false, false, 1);
+
+ //this.pnlSetting.Add();
+ //this.pnlSetting.Position = 5;// .Location = new System.Drawing.Point(14, 12);
+ this.pnlSetting.Margin = 2;
+ this.pnlSetting.Name = "pnlSetting";
+ // this.pnlSetting.Valign = Align.Fill;
+ // this.pnlSetting.Halign = Align.Fill;
+ // this.pnlSetting.SetSizeRequest(708, 20);
+ // pnlSetting.Orientation = Orientation.Horizontal;
+ //this.pnlSetting.Size = new System.Drawing.Size(708, 46);
+ //this.pnlSetting.TabIndex = 13;
+ //
+ // numPort
+ //
+ // this.numPort.Location = new System.Drawing.Point(270, 10);
+ this.numPort.Margin = 4;
+ this.numPort.Name = "numPort";
+ this.numPort.Value = 8080;
+ //this.numPort.SetSizeRequest(94, 28);
+ //
+ // label5
+ //
+ //this.label5.AutoSize = true;
+ //this.label5.Location = new System.Drawing.Point(218, 14);
+ this.label5.Xalign = 0.8F;
+ this.label5.Yalign = 0.5F;
+ this.label5.MarginTop = 4;
+ this.label5.MarginBottom = 4;
+ this.label5.Name = "label5";
+ //this.label5.SetSizeRequest(62, 18);
+ this.label5.Text = "本地:";
+ //
+ // gbSend
+ //
+ this.gbSend.Add(this.boxSend);
+ // this.gbSend.Controls.Add(this.numThreads);
+ // this.gbSend.Controls.Add(this.numSleep);
+ // this.gbSend.Controls.Add(this.btnSend);
+ // this.gbSend.Controls.Add(this.numMutilSend);
+ // this.gbSend.Controls.Add(this.label2);
+ // this.gbSend.Controls.Add(this.label7);
+ // this.gbSend.Location = new System.Drawing.Point(14, 424);
+ this.gbSend.Margin = 1;
+ this.gbSend.Name = "gbSend";
+ //this.gbSend.SetSizeRequest(778, 126);
+ this.gbSend.Label = "发送区:已发送0字节";
+ //
+ // boxSend
+ //
+ this.boxSend.PackStart(this.txtSendScrolledWindow, false, false, 2);
+ this.boxSend.PackStart(this.boxSendSetting, false, false, 2);
+ // this.boxSend.Orientation = Orientation.Vertical;
+ this.boxSend.Margin = 1;
+ this.boxSend.Name = "boxSend";
+ //
+ // boxSendSetting
+ //
+ this.boxSendSetting.PackStart(this.label7, false, false, 2);
+ this.boxSendSetting.PackStart(this.numMutilSend, false, false, 2);
+ this.boxSendSetting.PackStart(this.label8, false, false, 2);
+ this.boxSendSetting.PackStart(this.numThreads, false, false, 2);
+ this.boxSendSetting.PackStart(this.label2, false, false, 2);
+ this.boxSendSetting.PackStart(this.numSleep, false, false, 2);
+ this.boxSendSetting.PackStart(this.btnSend, false, false, 2);
+ this.boxSendSetting.Margin = 1;
+ this.boxSendSetting.Name = "sendSetting";
+ //
+ // numThreads
+ //
+ this.numThreads.Margin = 4;
+ this.numThreads.Name = "numThreads";
+ //this.numThreads.SetSizeRequest(78, 28);
+ // this.toolTip1.SetToolTip(this.numThreads, "模拟多客户端发送,用于压力测试!");
+ //
+ // numSleep
+ //
+ this.numSleep.Margin = 1;
+ this.numSleep.Name = "numSleep";
+ //this.numSleep.SetSizeRequest(109, 28);
+ //
+ // txtSendScrolledWindow
+ //
+ this.txtSendScrolledWindow.CanFocus = true;
+ this.txtSendScrolledWindow.ShadowType = ShadowType.In;
+ this.txtSendScrolledWindow.Vexpand = true;
+ this.txtSendScrolledWindow.Add(this.txtSend);
+ //
+ // txtSend
+ //
+ // this.txtSend.ContextMenuStrip = this.menuSend;
+ // this.txtSend.Location = new System.Drawing.Point(0, 28);
+ this.txtSend.Margin = 4;
+ this.txtSend.Name = "txtSend";
+ //this.txtSend.SetSizeRequest(621, 86);
+ this.txtSend.WrapMode = WrapMode.Word;
+ //this.txtSend.Editable = false;
+ //
+ // btnSend
+ //
+ this.btnSend.Margin = 4;
+ this.btnSend.Name = "btnSend";
+ //this.btnSend.SetSizeRequest(75, 45);
+ this.btnSend.Label = "发送";
+ this.btnSend.Clicked += new System.EventHandler(this.btnSend_Click);
+ //
+ // numMutilSend
+ //
+ this.numMutilSend.Margin = 4;
+ this.numMutilSend.Name = "numMutilSend";
+ //this.numMutilSend.SetSizeRequest(109, 28);
+ //
+ // label2
+ //
+ // this.label2.Location = new System.Drawing.Point(729, 87);
+ this.label2.Margin = 4;
+ this.label2.Name = "label2";
+ //this.label2.SetSizeRequest(62, 18);
+ this.label2.Text = "间隔:";
+ //
+ // label7
+ //
+ // this.label7.Location = new System.Drawing.Point(729, 39);
+ this.label7.Margin = 4;
+ this.label7.Name = "label7";
+ //this.label7.SetSizeRequest(62, 18);
+ this.label7.Text = "次数:";
+ //
+ // label8
+ //
+ this.label8.Margin = 4;
+ this.label8.Name = "label8";
+ //this.label8.SetSizeRequest(62, 18);
+ this.label8.Text = "线程:";
+ ////
+ //// FrmMain
+ ////
+ //this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 18F);
+ //this.AutoScaleMode = AutoScaleMode.Font;
+ //this.ClientSize = new System.Drawing.Size(1000, 568);
+ this.PackStart(this.pnlSetting, false, false, 2);
+ this.PackStart(this.gbReceive, true, true, 2);
+ this.PackStart(this.gbSend, false, false, 2);
+ //this.Margin = new Padding(4);
+ //this.Name = "FrmMain";
+ //this.StartPosition = FormStartPosition.CenterScreen;
+ //this.Text = "Api调试";
+ this.Shown += new System.EventHandler(this.FrmMain_Load);
+ //this.menuReceive.ResumeLayout(false);
+ //this.menuSend.ResumeLayout(false);
+ //this.pnlSetting.ResumeLayout(false);
+ //this.pnlSetting.PerformLayout();
+ //((System.ComponentModel.ISupportInitialize)(this.numPort)).EndInit();
+ //((System.ComponentModel.ISupportInitialize)(this.numThreads)).EndInit();
+ //((System.ComponentModel.ISupportInitialize)(this.numSleep)).EndInit();
+ //((System.ComponentModel.ISupportInitialize)(this.numMutilSend)).EndInit();
+ //this.ResumeLayout(false);
+ //this.PerformLayout();
+ //this.Fill = true;
+ //this.Halign = Align.Fill;
+ //this.Valign = Align.Fill;
+ this.Orientation = Orientation.Vertical;
+ }
+
+ private void TxtReceive_SizeAllocated(System.Object o, SizeAllocatedArgs args)
+ {
+ var s = o as TextView;
+
+ s.ScrollToIter(s.Buffer.EndIter, 0, false, 0, 0);
+ }
+ #endregion
+
+ private Frame gbReceive;
+ private Button btnConnect;
+ private ScrolledWindow txtReceiveScrolledWindow;
+ private TextView txtReceive;
+ private Label label1;
+ private Label lbAddr;
+ private ComboBox cbMode;
+ private ComboBox cbLocal;
+ private ComboBoxText cbRemote;
+ private HBox pnlSetting;
+ private Frame gbSend;
+ private VBox boxSend;
+ private HBox boxSendSetting;
+ private SpinButton numSleep;
+ private ScrolledWindow txtSendScrolledWindow;
+ private TextView txtSend;
+ private Button btnSend;
+ private SpinButton numMutilSend;
+ private Label label2;
+ private Label label7;
+ private Label label8;
+ private SpinButton numThreads;
+ private SpinButton numPort;
+ private Label label5;
+ private NewLife.Windows.SerialPortList spList;
+ }
+}
+
diff --git a/XCoderLinux/XCom/SerialPortList.cs b/XCoderLinux/XCom/SerialPortList.cs
new file mode 100644
index 0000000..2421fcb
--- /dev/null
+++ b/XCoderLinux/XCom/SerialPortList.cs
@@ -0,0 +1,565 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.IO;
+using System.IO.Ports;
+using System.Linq;
+using System.Text;
+using Gtk;
+using NewLife.Log;
+using NewLife.Net;
+using NewLife.Threading;
+using XCoder.Util;
+
+namespace NewLife.Windows
+{
+ /// <summary>串口列表控件</summary>
+ [DefaultEvent("ReceivedString")]
+ public partial class SerialPortList : HBox
+ {
+ #region 属性
+ /// <summary>端口</summary>
+ public SerialTransport Port { get; set; }
+
+ /// <summary>选择的端口</summary>
+ public String SelectedPort { get { return cbName.GetActiveObject() + ""; } set { } }
+
+ /// <summary>收到的字节数</summary>
+ public Int32 BytesOfReceived { get; set; }
+
+ /// <summary>发送的字节数</summary>
+ public Int32 BytesOfSent { get; set; }
+ #endregion
+
+ #region 构造
+ /// <summary></summary>
+ public SerialPortList()
+ {
+ InitializeComponent();
+ }
+
+ TimerX _timer;
+ private void SerialPortList_Load(Object sender, EventArgs e)
+ {
+ LoadInfo();
+
+ // 挂载定时器
+ _timer = new TimerX(OnCheck, null, 300, 300);
+
+ //if (Parent is Form frm)
+ //{
+ // frm.FormClosing += frm_FormClosing;
+ //}
+ }
+
+ //void frm_FormClosing(Object sender, FormClosingEventArgs e)
+ //{
+ // SaveInfo();
+
+ // _timer.Dispose();
+ // _timer = null;
+
+ // if (Port != null) Port.Close();
+ //}
+ #endregion
+
+ #region 加载保存信息
+ /// <summary>加载配置信息</summary>
+ public void LoadInfo()
+ {
+ ShowPorts();
+
+ //BindMenu(mi数据位, On数据位Click, new Int32[] { 5, 6, 7, 8 });
+ //BindMenu(mi停止位, On停止位Click, Enum.GetValues(typeof(StopBits)));
+ //BindMenu(mi校验, On校验Click, Enum.GetValues(typeof(Parity)));
+
+ //var arr = new Int32[] { 1200, 2400, 4800, 9600, 14400, 19200, 38400, 56000, 57600, 115200, 128000, 194000, 256000, 512000, 1024000, 2048000 };
+ var bs = new List<Int32>(new Int32[] { 1200, 2400, 4800, 9600, 14400, 19200, 38400, 56000, 57600, 115200, 128000, 194000, 256000, 512000, 1024000, 2048000 });
+
+ var cfg = SerialPortConfig.Current;
+ if (cfg.BaudRate > 0 && !bs.Contains(cfg.BaudRate)) bs.Add(cfg.BaudRate);
+ cbBaudrate.AppendValues(bs);
+
+ cbName.SetActive(cfg.PortName);
+ cbBaudrate.SetActive(cfg.BaudRate);
+ //SetMenuItem(mi数据位, cfg.DataBits);
+ //SetMenuItem(mi停止位, cfg.StopBits);
+ //SetMenuItem(mi校验, cfg.Parity);
+
+ //cbEncoding.DataSource = new String[] { Encoding.UTF8.WebName, Encoding.ASCII.WebName, Encoding.UTF8.WebName };
+ // 添加编码子菜单
+ var encs = new Encoding[] { Encoding.UTF8, Encoding.ASCII, Encoding.UTF7, Encoding.Unicode, Encoding.BigEndianUnicode/*, Encoding.UTF32,Encoding.GetEncoding("GB2312") */};
+ var list = new List<Encoding>(encs);
+ // 暂时不用这么多编码
+ //list.AddRange(Encoding.GetEncodings().Select(e => e.GetEncoding()).Where(e => !encs.Contains(e)));
+ var k = 0;
+ //foreach (var item in list)
+ //{
+ // if (k++ == encs.Length)
+ // {
+ // var sep = new ToolStripSeparator();
+ // mi字符串编码.DropDownItems.Add(sep);
+ // }
+ // var ti = mi字符串编码.DropDownItems.Add(item.EncodingName) as ToolStripMenuItem;
+ // ti.Name = item.WebName;
+ // ti.Tag = item;
+ // ti.Checked = item.WebName.EqualIgnoreCase(cfg.WebEncoding);
+ // ti.Click += On编码Click;
+ //}
+
+ //miHEX编码接收.Checked = cfg.HexShow;
+ //mi字符串编码.Checked = !cfg.HexShow;
+ //miHex不换行.Checked = !cfg.HexNewLine;
+ //miHex自动换行.Checked = cfg.HexNewLine;
+ //miHEX编码发送.Checked = cfg.HexSend;
+ //miDTR.Checked = cfg.DtrEnable;
+ //miRTS.Checked = cfg.RtsEnable;
+ //miBreak.Checked = cfg.BreakState;
+ }
+
+ /// <summary>保存配置信息</summary>
+ public void SaveInfo()
+ {
+ try
+ {
+ var cfg = SerialPortConfig.Current;
+ cfg.PortName = cbName.GetActiveObject() + "";
+ if (cbBaudrate.GetActiveObject() != null)
+ cfg.BaudRate = (Int32)cbBaudrate.GetActiveObject();
+ //else
+ // cfg.BaudRate = cbBaudrate.ToInt();
+ //cfg.DataBits = (Int32)cbDataBit.GetActiveObject();
+ //cfg.StopBits = (StopBits)cbStopBit.GetActiveObject();
+ //cfg.Parity = (Parity)cbParity.GetActiveObject();
+ //cfg.Encoding = (Encoding)cbEncoding.GetActiveObject();
+ //cfg.WebEncoding = cbEncoding.GetActiveObject() + "";
+
+ //cfg.HexSend = chkHEXSend.Checked;
+ //cfg.HexShow = chkHEXShow.Checked;
+
+ cfg.Save();
+ }
+ catch (Exception ex)
+ {
+ XTrace.WriteException(ex);
+ }
+ }
+
+ String _ports = null;
+ DateTime _nextport = DateTime.MinValue;
+ /// <summary>下拉框显示串口</summary>
+ public void ShowPorts()
+ {
+ if (_nextport > DateTime.Now) return;
+ _nextport = DateTime.Now.AddSeconds(1);
+
+ var ps = SerialTransport.GetPortNames();
+ var str = String.Join(",", ps);
+ // 如果端口有所改变,则重新绑定
+ if (_ports != str)
+ {
+ if (_ports != null) "串口有改变".SpeechTip();
+
+ _ports = str;
+
+ Application.Invoke((s, e) =>
+ {
+ var old = cbName.GetActiveObject() + "";
+ cbName.AppendValues(ps.ToList());
+ if (!String.IsNullOrEmpty(old) && Array.IndexOf(ps, old) >= 0) cbName.SetActive(old);
+ });
+ }
+ }
+ #endregion
+
+ #region 菜单设置
+ ///// <summary>右键菜单</summary>
+ //public ContextMenuStrip Menu { get { return contextMenuStrip1; } }
+
+ //void On数据位Click(Object sender, EventArgs e)
+ //{
+ // SelectMenu(sender);
+
+ // var mi = sender as ToolStripMenuItem;
+ // var cfg = SerialPortConfig.Current;
+ // cfg.DataBits = (Int32)mi.Tag;
+ //}
+
+ //void On停止位Click(Object sender, EventArgs e)
+ //{
+ // SelectMenu(sender);
+
+ // var mi = sender as ToolStripMenuItem;
+ // var cfg = SerialPortConfig.Current;
+ // cfg.StopBits = (StopBits)mi.Tag;
+ //}
+
+ //void On校验Click(Object sender, EventArgs e)
+ //{
+ // SelectMenu(sender);
+
+ // var mi = sender as ToolStripMenuItem;
+ // var cfg = SerialPortConfig.Current;
+ // cfg.Parity = (Parity)mi.Tag;
+ //}
+
+ //void On编码Click(Object sender, EventArgs e)
+ //{
+ // // 不要选其它
+ // var mi = sender as ToolStripMenuItem;
+ // if (mi == null) return;
+ // //foreach (ToolStripMenuItem item in (mi.OwnerItem as ToolStripMenuItem).DropDownItems)
+ // //{
+ // // item.Checked = item == mi;
+ // //}
+ // SelectMenu(sender);
+
+ // // 保存编码
+ // var cfg = SerialPortConfig.Current;
+ // cfg.WebEncoding = mi.Name;
+ //}
+
+ //private void mi字符串编码_Click(Object sender, EventArgs e)
+ //{
+ // var cfg = SerialPortConfig.Current;
+ // //cfg.HexShow = miHEX编码接收.Checked = !mi字符串编码.Checked;
+ // cfg.HexShow = SelectMenu(sender, mi字符串编码, miHEX编码接收) == 1;
+
+ // // 收起菜单
+ // contextMenuStrip1.Hide();
+ //}
+
+ //private void miHex自动换行_Click(Object sender, EventArgs e)
+ //{
+ // var cfg = SerialPortConfig.Current;
+ // //cfg.HexNewLine = ti.Tag.ToBoolean();
+ // cfg.HexNewLine = SelectMenu(sender) == 1;
+ //}
+
+ //private void miHEX编码发送_Click(Object sender, EventArgs e)
+ //{
+ // var cfg = SerialPortConfig.Current;
+ // miHEX编码发送.Checked = !miHEX编码发送.Checked;
+ // cfg.HexSend = miHEX编码发送.Checked;
+ //}
+
+ //private void miDTR_Click(Object sender, EventArgs e)
+ //{
+ // var mi = sender as ToolStripMenuItem;
+ // mi.Checked = !mi.Checked;
+ //}
+ #endregion
+
+ #region 窗体
+ /// <summary>连接串口</summary>
+ public void Connect()
+ {
+ var name = cbName.GetActiveObject() + "";
+ if (String.IsNullOrEmpty(name))
+ {
+ "请选择串口".SpeechTip();
+ MessageBox.Show("请选择串口!");
+ //cbName.Focus();
+ return;
+ }
+ var p = name.IndexOf("(");
+ if (p > 0) name = name.Substring(0, p);
+
+ SaveInfo();
+ var cfg = SerialPortConfig.Current;
+
+ var pt = Port;
+ if (pt != null)
+ {
+ // 如果上次没有关闭,则关闭
+ try
+ {
+ pt.Close();
+ }
+ catch
+ {
+ pt = null;
+ }
+ }
+ if (pt == null) pt = new SerialTransport();
+ pt.PortName = name;
+ pt.BaudRate = cfg.BaudRate;
+ pt.Parity = cfg.Parity;
+ pt.DataBits = cfg.DataBits;
+ pt.StopBits = cfg.StopBits;
+
+ //pt.Open();
+
+ pt.Disconnected += Port_Disconnected;
+ pt.Received += OnReceived;
+ pt.Open();
+
+ //pt.EnsureCreate();
+
+ Port = pt;
+
+ var sp = pt.Serial;
+ // 这几个需要打开端口以后才能设置
+ //try
+ //{
+ // if (sp.DtrEnable != miDTR.Checked) sp.DtrEnable = miDTR.Checked;
+ // if (sp.RtsEnable != miRTS.Checked) sp.RtsEnable = miRTS.Checked;
+ // if (sp.BreakState != miBreak.Checked) sp.BreakState = miBreak.Checked;
+ //}
+ //catch { }
+
+ Sensitive = false;
+ }
+
+ void Port_Disconnected(Object sender, EventArgs e)
+ {
+ Disconnect();
+ }
+
+ /// <summary>断开串口连接</summary>
+ public void Disconnect()
+ {
+ var pt = Port;
+ if (pt != null)
+ {
+ Port = null;
+ pt.Disconnected -= Port_Disconnected;
+ pt.Received -= OnReceived;
+ pt.Close();
+ }
+
+ ShowPorts();
+
+ Sensitive = true;
+ }
+
+ private void OnCheck(Object state)
+ {
+ if (Sensitive) ShowPorts();
+ }
+ #endregion
+
+ #region 菜单辅助
+ //ToolStripItem FindMenu(String name)
+ //{
+ // return contextMenuStrip1.Items.Find(name, false)[0];
+ //}
+
+ //void BindMenu(ToolStripMenuItem ti, EventHandler handler, IEnumerable em)
+ //{
+ // ti.DropDownItems.Clear();
+ // foreach (var item in em)
+ // {
+ // var tsi = ti.DropDownItems.Add(item + "");
+ // tsi.Tag = item;
+ // tsi.Click += handler;
+ // }
+ //}
+
+ //void SetMenuItem(ToolStripMenuItem ti, Object value)
+ //{
+ // foreach (ToolStripMenuItem item in ti.DropDownItems)
+ // {
+ // item.Checked = item + "" == value + "";
+ // }
+ //}
+
+ ///// <summary>在一个菜单列表中点击某一个菜单,改变菜单选择并返回选中的菜单索引</summary>
+ ///// <param name="sender"></param>
+ ///// <param name="ms"></param>
+ //Int32 SelectMenu(Object sender, params ToolStripMenuItem[] ms)
+ //{
+ // var mi = sender as ToolStripMenuItem;
+ // if (mi == null) return -1;
+
+ // var idx = -1;
+ // for (var i = 0; i < ms.Length; i++)
+ // {
+ // if (ms[i] == mi)
+ // {
+ // ms[i].Checked = true;
+ // idx = i;
+ // }
+ // else
+ // ms[i].Checked = false;
+ // }
+ // return idx;
+ //}
+
+ ///// <summary>在同级菜单中选择</summary>
+ ///// <param name="sender"></param>
+ ///// <param name="tsi"></param>
+ ///// <returns></returns>
+ //Int32 SelectMenu(Object sender, ToolStripItem tsi = null)
+ //{
+ // if (tsi == null) tsi = (sender as ToolStripMenuItem).OwnerItem;
+
+ // var ms = (tsi as ToolStripMenuItem).DropDownItems;
+ // if (ms == null) return -1;
+
+ // var arr = new ToolStripMenuItem[ms.Count];
+ // ms.CopyTo(arr, 0);
+
+ // return SelectMenu(sender, arr);
+ //}
+ #endregion
+
+ #region 收发数据
+ /// <summary>发送字节数组</summary>
+ /// <param name="data"></param>
+ public void Send(Byte[] data)
+ {
+ if (data == null || data.Length <= 0) return;
+
+ BytesOfSent += data.Length;
+
+ Port.Send(data);
+ }
+
+ /// <summary>发送字符串。根据配置进行十六进制编码</summary>
+ /// <param name="str"></param>
+ /// <returns>发送字节数</returns>
+ public Int32 Send(String str)
+ {
+ var cfg = SerialPortConfig.Current;
+ // 16进制发送
+ Byte[] data = null;
+ if (cfg.HexSend)
+ data = str.ToHex();
+ else
+ data = cfg.Encoding.GetBytes(str);
+
+ Send(data);
+
+ return data.Length;
+ }
+
+ //public event SerialReceived Received;
+ /// <summary>收到数据时触发。第一个参数是数据,第二个参数返回是否继续往下传递数据</summary>
+ [Browsable(true)]
+ [EditorBrowsable(EditorBrowsableState.Always)]
+ public event EventHandler<BufferEventArgs> Received;
+
+ /// <summary>收到数据时转为字符串后触发该事件。注意字符串编码和十六进制编码。</summary>
+ /// <remarks>如果需要收到的数据,可直接在<seealso cref="Port"/>上挂载事件</remarks>
+ [Browsable(true)]
+ [EditorBrowsable(EditorBrowsableState.Always)]
+ public event EventHandler<StringEventArgs> ReceivedString;
+
+ MemoryStream _stream;
+ StreamReader _reader;
+ void OnReceived(Object sender, ReceivedEventArgs e)
+ {
+ var data = e.Packet.ReadBytes();
+ if (data == null || data.Length < 1) return;
+
+ BytesOfReceived += data.Length;
+
+ // 处理数据委托
+ if (Received != null)
+ {
+ var e2 = new BufferEventArgs { Value = data };
+ Received(this, e2);
+ if (!e2.Cancel) return;
+ // 外部可能修改了数据
+ data = e2.Value;
+ //if (!BufferEventArgs.Invoke(Received, data)) return null;
+ }
+
+ // 处理字符串委托
+ if (ReceivedString == null) return;
+
+ var cfg = SerialPortConfig.Current;
+
+ var line = "";
+ if (cfg.HexShow)
+ {
+ if (data.Length > 32)
+ line = "[{0}]=\r\n{1}".F(data.Length, data.ToHex("-", 32));
+ else
+ line = "[{0}]={1}".F(data.Length, data.ToHex("-", 32));
+ if (cfg.HexNewLine) line += Environment.NewLine;
+ }
+ else
+ {
+ line = cfg.Encoding.GetString(data);
+ if (_stream == null)
+ _stream = new MemoryStream();
+ else if (_stream.Length > 10 * 1024 && _stream.Position == _stream.Length) // 达到最大大小时,从头开始使用
+ _stream = new MemoryStream();
+ _stream.Write(data);
+ _stream.Seek(-1 * data.Length, SeekOrigin.Current);
+
+ if (_reader == null ||
+ _reader.BaseStream != _stream ||
+ _reader.CurrentEncoding != cfg.Encoding)
+ _reader = new StreamReader(_stream, cfg.Encoding);
+ line = _reader.ReadToEnd();
+ // 替换掉无效数据
+ line = line.Replace("\0", null);
+ }
+
+ ReceivedString?.Invoke(this, new StringEventArgs { Value = line });
+ }
+ #endregion
+
+ #region 收发统计
+ /// <summary>清空发送</summary>
+ public void ClearSend()
+ {
+ BytesOfSent = 0;
+
+ var sp = Port;
+ if (sp != null)
+ {
+ try
+ {
+ if (sp.Serial != null) sp.Serial.DiscardOutBuffer();
+ }
+ catch { }
+ }
+ }
+
+ /// <summary>清空接收</summary>
+ public void ClearReceive()
+ {
+ BytesOfReceived = 0;
+ if (_stream != null) _stream.SetLength(0);
+
+ var sp = Port;
+ if (sp != null)
+ {
+ try
+ {
+ if (sp.Serial != null) sp.Serial.DiscardInBuffer();
+ }
+ catch { }
+ }
+ }
+ #endregion
+ }
+
+ /// <summary>字符串事件参数</summary>
+ public class StringEventArgs : EventArgs
+ {
+ private String _Value;
+ /// <summary>字符串值</summary>
+ public String Value { get { return _Value; } set { _Value = value; } }
+ }
+
+ /// <summary>缓冲区事件参数</summary>
+ public class BufferEventArgs : CancelEventArgs
+ {
+ private Byte[] _Value;
+ /// <summary>缓冲区数据</summary>
+ public Byte[] Value { get { return _Value; } set { _Value = value; } }
+
+ //public static Boolean Invoke(EventHandler<BufferEventArgs> handler, Object sender, Byte[] buf)
+ //{
+ // var e = new BufferEventArgs { Value = buf, Cancel = false };
+ // handler(sender, e);
+ // return e.Cancel;
+ //}
+ }
+}
\ No newline at end of file
diff --git a/XCoderLinux/XCom/SerialPortList.designer.cs b/XCoderLinux/XCom/SerialPortList.designer.cs
new file mode 100644
index 0000000..9d5a0fe
--- /dev/null
+++ b/XCoderLinux/XCom/SerialPortList.designer.cs
@@ -0,0 +1,203 @@
+using Gtk;
+
+namespace NewLife.Windows
+{
+ partial class SerialPortList
+ {
+ #region 组件设计器生成的代码
+
+ /// <summary>
+ /// </summary>
+ private void InitializeComponent()
+ {
+ this.cbBaudrate = new ComboBox(new string[] { });
+ this.label2 = new Label();
+ this.cbName = new ComboBox(new string[] { });
+ this.label3 = new Label();
+ //this.contextMenuStrip1 = new ContextMenuStrip(this.components);
+ //this.mi数据位 = new ToolStripMenuItem();
+ //this.mi停止位 = new ToolStripMenuItem();
+ //this.mi校验 = new ToolStripMenuItem();
+ //this.mi高级 = new ToolStripMenuItem();
+ //this.miDTR = new ToolStripMenuItem();
+ //this.miRTS = new ToolStripMenuItem();
+ //this.miBreak = new ToolStripMenuItem();
+ //this.toolStripMenuItem1 = new ToolStripSeparator();
+ //this.mi字符串编码 = new ToolStripMenuItem();
+ //this.miHEX编码接收 = new ToolStripMenuItem();
+ //this.miHex不换行 = new ToolStripMenuItem();
+ //this.miHex自动换行 = new ToolStripMenuItem();
+ //this.miHEX编码发送 = new ToolStripMenuItem();
+ //this.toolStripMenuItem2 = new ToolStripSeparator();
+ //this.contextMenuStrip1.SuspendLayout();
+ //
+ // cbBaudrate
+ //
+ this.cbBaudrate.Name = "cbBaudrate";
+ //
+ // label2
+ //
+ this.label2.Name = "label2";
+ this.label2.Text = "波特率:";
+ //
+ // cbName
+ //
+ this.cbName.Name = "cbName";
+ //
+ // label3
+ //
+ this.label3.Name = "label3";
+ this.label3.Text = "端口:";
+ ////
+ //// contextMenuStrip1
+ ////
+ ////this.contextMenuStrip1.Items.AddRange(new ToolStripItem[] {
+ ////this.mi数据位,
+ ////this.mi停止位,
+ ////this.mi校验,
+ ////this.mi高级,
+ ////this.toolStripMenuItem1,
+ ////this.mi字符串编码,
+ ////this.miHEX编码接收,
+ ////this.miHEX编码发送,
+ ////this.toolStripMenuItem2});
+ ////this.contextMenuStrip1.Name = "contextMenuStrip1";
+ ////this.contextMenuStrip1.Size = new System.Drawing.Size(149, 170);
+ ////
+ //// mi数据位
+ ////
+ //this.mi数据位.Name = "mi数据位";
+ //this.mi数据位.Size = new System.Drawing.Size(148, 22);
+ //this.mi数据位.Text = "数据位";
+ ////
+ //// mi停止位
+ ////
+ //this.mi停止位.Name = "mi停止位";
+ //this.mi停止位.Size = new System.Drawing.Size(148, 22);
+ //this.mi停止位.Text = "停止位";
+ ////
+ //// mi校验
+ ////
+ //this.mi校验.Name = "mi校验";
+ //this.mi校验.Size = new System.Drawing.Size(148, 22);
+ //this.mi校验.Text = "校验";
+ ////
+ //// mi高级
+ ////
+ //this.mi高级.DropDownItems.AddRange(new ToolStripItem[] {
+ //this.miDTR,
+ //this.miRTS,
+ //this.miBreak});
+ //this.mi高级.Name = "mi高级";
+ //this.mi高级.Size = new System.Drawing.Size(148, 22);
+ //this.mi高级.Text = "高级";
+ ////
+ //// miDTR
+ ////
+ //this.miDTR.Name = "miDTR";
+ //this.miDTR.Size = new System.Drawing.Size(110, 22);
+ //this.miDTR.Text = "DTR";
+ //this.miDTR.Click += new System.EventHandler(this.miDTR_Click);
+ ////
+ //// miRTS
+ ////
+ //this.miRTS.Name = "miRTS";
+ //this.miRTS.Size = new System.Drawing.Size(110, 22);
+ //this.miRTS.Text = "RTS";
+ //this.miRTS.Click += new System.EventHandler(this.miDTR_Click);
+ ////
+ //// miBreak
+ ////
+ //this.miBreak.Name = "miBreak";
+ //this.miBreak.Size = new System.Drawing.Size(110, 22);
+ //this.miBreak.Text = "Break";
+ //this.miBreak.Click += new System.EventHandler(this.miDTR_Click);
+ ////
+ //// toolStripMenuItem1
+ ////
+ //this.toolStripMenuItem1.Name = "toolStripMenuItem1";
+ //this.toolStripMenuItem1.Size = new System.Drawing.Size(145, 6);
+ ////
+ //// mi字符串编码
+ ////
+ //this.mi字符串编码.Name = "mi字符串编码";
+ //this.mi字符串编码.Size = new System.Drawing.Size(148, 22);
+ //this.mi字符串编码.Text = "字符串编码";
+ //this.mi字符串编码.Click += new System.EventHandler(this.mi字符串编码_Click);
+ ////
+ //// miHEX编码接收
+ ////
+ //this.miHEX编码接收.DropDownItems.AddRange(new ToolStripItem[] {
+ //this.miHex不换行,
+ //this.miHex自动换行});
+ //this.miHEX编码接收.Name = "miHEX编码接收";
+ //this.miHEX编码接收.Size = new System.Drawing.Size(148, 22);
+ //this.miHEX编码接收.Text = "HEX编码接收";
+ //this.miHEX编码接收.Click += new System.EventHandler(this.mi字符串编码_Click);
+ ////
+ //// miHex不换行
+ ////
+ //this.miHex不换行.Name = "miHex不换行";
+ //this.miHex不换行.Size = new System.Drawing.Size(124, 22);
+ //this.miHex不换行.Tag = "false";
+ //this.miHex不换行.Text = "不换行";
+ //this.miHex不换行.Click += new System.EventHandler(this.miHex自动换行_Click);
+ ////
+ //// miHex自动换行
+ ////
+ //this.miHex自动换行.Name = "miHex自动换行";
+ //this.miHex自动换行.Size = new System.Drawing.Size(124, 22);
+ //this.miHex自动换行.Tag = "true";
+ //this.miHex自动换行.Text = "自动换行";
+ //this.miHex自动换行.Click += new System.EventHandler(this.miHex自动换行_Click);
+ ////
+ //// miHEX编码发送
+ ////
+ //this.miHEX编码发送.Name = "miHEX编码发送";
+ //this.miHEX编码发送.Size = new System.Drawing.Size(148, 22);
+ //this.miHEX编码发送.Text = "HEX编码发送";
+ //this.miHEX编码发送.Click += new System.EventHandler(this.miHEX编码发送_Click);
+ ////
+ //// toolStripMenuItem2
+ ////
+ //this.toolStripMenuItem2.Name = "toolStripMenuItem2";
+ //this.toolStripMenuItem2.Size = new System.Drawing.Size(145, 6);
+ //
+ // SerialPortList
+ //
+ //this.ContextMenuStrip = this.contextMenuStrip1;
+ this.PackStart(this.label3, false, false, 1);
+ this.PackStart(this.cbName, false, false, 1);
+ this.PackStart(this.label2, false, false, 1);
+ this.PackStart(this.cbBaudrate, false, false, 1);
+ this.Name = "SerialPortList";
+ this.Shown += new System.EventHandler(this.SerialPortList_Load);
+ //this.contextMenuStrip1.ResumeLayout(false);
+ //this.ResumeLayout(false);
+ //this.PerformLayout();
+ }
+
+ #endregion
+
+ private ComboBox cbBaudrate;
+ private Label label2;
+ private ComboBox cbName;
+ private Label label3;
+ //private ContextMenuStrip contextMenuStrip1;
+ //private ToolStripMenuItem mi数据位;
+ //private ToolStripMenuItem mi停止位;
+ //private ToolStripMenuItem mi校验;
+ //private ToolStripMenuItem mi字符串编码;
+ //private ToolStripMenuItem miHEX编码接收;
+ //private ToolStripMenuItem miHex不换行;
+ //private ToolStripMenuItem miHex自动换行;
+ //private ToolStripMenuItem mi高级;
+ //private ToolStripMenuItem miDTR;
+ //private ToolStripMenuItem miRTS;
+ //private ToolStripMenuItem miBreak;
+ //private ToolStripSeparator toolStripMenuItem1;
+ //private ToolStripSeparator toolStripMenuItem2;
+ //private ToolStripMenuItem miHEX编码发送;
+
+ }
+}