using OpenVinoSharp.Extensions;
using Sunny.UI;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Reflection.Emit;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.Button;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.Window;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
using MyCameras;
using System.Collections.Concurrent;
using MyVision.Forms.Pages;
using MyVision.Forms;
using MyProcesses;
using MyProcesses.Communicators;
using Newtonsoft.Json;
using SharpCompress.Common;
using OpenVinoSharp;
using System.Text.RegularExpressions;
using HalconDotNet;
using MyProcesses.Alogrithms.Halcon;
using MyCommunicators;
namespace MyVision
{
///
/// Windows10、Windows11 建议用UIForm2,更接近原生窗体使用体验,用UIForm也可以
/// WindowsXP、Windows7 建议使用UIForm
///
public partial class MainForm : UIForm2
{
ICamera camera = new MindCamera();
///
/// 相机集合(Key:相机SN,Value:相机句柄)
///
ConcurrentDictionary dicCameras = new ConcurrentDictionary();
int CamerasPageIndex = 2000;
///
/// 流程集合(Key:相机SN,Value:object为IProcess时,string为ID,object为ICamera时,string为SN)
///
ConcurrentDictionary> dicProcesses = new ConcurrentDictionary>();
int ProcessesPageIndex = 3000;
///
/// 通讯集合(Key:通讯名,Value:通讯句柄)
///
ConcurrentDictionary dicCommunicator = new ConcurrentDictionary();
ConcurrentDictionary allCommunicatorsConnectionString = new ConcurrentDictionary();
string allCommunicatorsConnectionStringPath = ".\\CommunicatorsConnection.json";
public MainForm()
{
InitializeComponent();
//关联窗体承载多页面框架的容器UITabControl
//窗体上如果只有一个UITabControl,也会自动关联,超过一个需要手动关联
this.MainTabControl = uiTabControl1;
uiNavBar1.TabControl = uiTabControl1;
uiNavMenu1.TabControl = uiTabControl1;
//uiNavBar1设置节点,也可以在Nodes属性里配置
uiNavBar1.Nodes.Add("测试");
uiNavBar1.Nodes.Add("相机");
uiNavBar1.Nodes.Add("流程");
uiNavBar1.Nodes.Add("通讯");
uiNavBar1.Nodes.Add("设置");
uiNavBar1.Nodes.Add("主题");
//设置初始页面索引(关联页面,唯一不重复即可)
int pageIndex = 1000;
uiNavBar1.SetNodePageIndex(uiNavBar1.Nodes[0], pageIndex);
uiNavBar1.SetNodeSymbol(uiNavBar1.Nodes[0], 61764);
TreeNode parent = uiNavMenu1.CreateNode("测试", 61764, 24, pageIndex);
//通过设置GUID关联,节点字体图标和大小由UIPage设置
uiNavMenu1.CreateChildNode(parent, AddPage(new UIPage(), Guid.NewGuid()));
//uiNavMenu1.CreateChildNode(parent, AddPage(new FDialogs(), Guid.NewGuid()));
//uiNavMenu1.CreateChildNode(parent, AddPage(new FEditor(), Guid.NewGuid()));
//uiNavMenu1.CreateChildNode(parent, AddPage(new FFrames(), Guid.NewGuid()));
pageIndex = 2000;
uiNavBar1.SetNodePageIndex(uiNavBar1.Nodes[1], pageIndex);
uiNavBar1.SetNodeSymbol(uiNavBar1.Nodes[1], 61501);
parent = uiNavMenu1.CreateNode("相机", 61501, 24, pageIndex);
CamerasPageIndex = pageIndex;
//通过设置PageIndex关联,节点文字、图标由相应的Page的Text、Symbol提供
int iCameraCount = 0;
foreach (var item in ((MindCamera)camera).GetListEnum())
{
MindCamera camera = new MindCamera();
if (camera.InitDevice(item.ToString(), this.Handle))
{
dicCameras.TryAdd(camera.SN, camera);
dicProcesses.TryAdd(camera.SN, new List());
uiNavMenu1.CreateChildNode(parent, AddPage(new CameraPage(dicCameras[camera.SN]), ++pageIndex));
//设置相机连接成功的小绿点提示
uiNavMenu1.SetNodeTipsText(parent.Nodes[iCameraCount], " ", Color.Green, Color.White);
}
iCameraCount++;
}
//设置相机连接的个数显示
uiNavMenu1.ShowTips = true;
uiNavMenu1.SetNodeTipsText(uiNavMenu1.Nodes[1], iCameraCount.ToString(), iCameraCount == 0 ? Color.Red : Color.Green, Color.White);
pageIndex = 3000;
uiNavBar1.SetNodePageIndex(uiNavBar1.Nodes[2], pageIndex);
uiNavBar1.SetNodeSymbol(uiNavBar1.Nodes[2], 61451);
parent = uiNavMenu1.CreateNode("流程", 61451, 24, pageIndex);
ProcessesPageIndex = pageIndex;
//从数据库中读取流程
ProcessDatabasePage processDatabasePage = new ProcessDatabasePage(dicCameras, dicProcesses);
uiNavMenu1.CreateChildNode(parent, AddPage(processDatabasePage, ++pageIndex));
//直接关联(默认自动生成GUID)
foreach (var item in dicCameras.Values)
{
uiNavMenu1.CreateChildNode(parent, AddPage(new ProcessPage(item, processDatabasePage.dicProcesses[((BaseCamera)item).SN], dicCameras, dicCommunicator), ++pageIndex));
}
//uiNavMenu1.CreateChildNode(parent, AddPage(new FBarChart()));
//uiNavMenu1.CreateChildNode(parent, AddPage(new FDoughnutChart()));
//uiNavMenu1.CreateChildNode(parent, AddPage(new FLineChart()));
//uiNavMenu1.CreateChildNode(parent, AddPage(new FPieChart()));
pageIndex = 4000;
uiNavBar1.SetNodePageIndex(uiNavBar1.Nodes[3], pageIndex);
uiNavBar1.SetNodeSymbol(uiNavBar1.Nodes[3], 61971);
parent = uiNavMenu1.CreateNode("通讯", 61971, 24, pageIndex);
//直接关联(默认自动生成GUID)
LoadAllCommunicator();
uiNavMenu1.CreateChildNode(parent, AddPage(new CommunicatorsPage(dicCommunicator), ++pageIndex));
//uiNavMenu1.CreateChildNode(parent, AddPage(CreateInstance("Sunny.UI.Demo.FPipe")));
//uiNavMenu1.CreateChildNode(parent, AddPage(CreateInstance("Sunny.UI.Demo.FMeter")));
//uiNavMenu1.CreateChildNode(parent, AddPage(CreateInstance("Sunny.UI.Demo.FLed")));
//uiNavMenu1.CreateChildNode(parent, AddPage(CreateInstance("Sunny.UI.Demo.FLight")));
//uiNavMenu1.CreateChildNode(parent, AddPage(CreateInstance("Sunny.UI.Demo.FSwitch")));
pageIndex = 5000;
uiNavBar1.SetNodePageIndex(uiNavBar1.Nodes[4], pageIndex);
uiNavBar1.SetNodeSymbol(uiNavBar1.Nodes[4], 61459);
parent = uiNavMenu1.CreateNode("设置", 61459, 24, pageIndex);
//直接关联(默认自动生成GUID)
uiNavMenu1.CreateChildNode(parent, AddPage(new UIPage(), ++pageIndex));
uiNavBar1.SetNodeSymbol(uiNavBar1.Nodes[5], 61502);
var styles = UIStyles.PopularStyles();
foreach (UIStyle style in styles)
{
uiNavBar1.CreateChildNode(uiNavBar1.Nodes[5], style.DisplayText(), style.Value());
}
//var node = uiNavBar1.CreateChildNode(uiNavBar1.Nodes[4], "字体图标", 99999);
//uiNavBar1.SetNodeSymbol(node, 558426);
//node = uiNavBar1.CreateChildNode(uiNavBar1.Nodes[5], "多彩主题", UIStyle.Colorful.Value());
//uiNavBar1.SetNodeSymbol(node, 558295);
//左侧导航主节点关联页面
//uiNavMenu1.CreateNode(AddPage(new UIPage(), 99999));
//uiNavMenu1.CreateNode(AddPage(new FSymbols(), 99999));
//uiNavMenu1.CreateNode(AddPage(new FColorful(), UIStyle.Colorful.Value()));
//直接增加一个页面,不在左侧列表显示
//AddPage(new FCommon());
//选中第1001个节点("测试节点下的第一个节点")
uiNavMenu1.SelectPage(1001);
uiPanel2.Text = Text = Version;
RegisterHotKey(Sunny.UI.ModifierKeys.Shift, Keys.F8);
//根据页面类型获取页面
//FButton page = GetPage();
//if (page != null)
// page.Text.WriteConsole();
//根据页面索引获取页面
UIPage page1 = GetPage(1001);
if (page1 != null)
page1.Text.WriteConsole();
timer1.Start();
timer60.Start();
}
public bool LoadAllCommunicator()
{
if (!File.Exists(allCommunicatorsConnectionStringPath))
{
Console.WriteLine("文件不存在创建空文件");
// 获取不带文件名的目录路径
string directoryPath = Path.GetDirectoryName(allCommunicatorsConnectionStringPath);
SaveAllCommunicator();
return true;
}
string strJson = string.Empty;
using (StreamReader streamReader = new StreamReader(allCommunicatorsConnectionStringPath, Encoding.UTF8))
{
strJson = streamReader.ReadToEnd();
streamReader.Close();
}
allCommunicatorsConnectionString = JsonConvert.DeserializeObject>(strJson);
if (allCommunicatorsConnectionString == null)
{
UIMessageBox.ShowError("通讯端口加载失败");
return false;
}
foreach (var CommunicatorConnectionString in allCommunicatorsConnectionString)
{
string CommunicatorName = CommunicatorConnectionString.Key;
string CommunicatorAddress = CommunicatorConnectionString.Value;
// 定义正则表达式以提取协议、IP 地址和端口
//1. \((.*?)\):\(和 \) 是用于匹配括号的转义字符。
// (.*?) 是一个非贪婪的匹配,用来匹配类名(MyProcesses.Communicators.TCPServer 或 MyProcesses.Communicators.UARTPort)。
//2. ([^:] +):匹配冒号之前的部分,即地址(127.0.0.1 或 COM5)。这里使用了[^:] 来匹配除了冒号之外的任意字符。
//3. (\d +) :匹配端口号,确保它匹配一个或多个数字。
var regex = new Regex(@"\((.*?)\)([^:]+):(\d+)");
var match = regex.Match(CommunicatorAddress);
if (match.Success)
{
string ClassName = match.Groups[1].Value; // "TCP"
string IP = match.Groups[2].Value; // "127.0.0.1"
string PORT = match.Groups[3].Value; // "1111"
if (string.IsNullOrEmpty(ClassName) || string.IsNullOrEmpty(IP) || string.IsNullOrEmpty(PORT))
break;
//利用反射创建实例
Type type = ICommunicator.GetExecutingAssembly().GetType(ClassName);
if (type == null)
{
Console.WriteLine("Class not found.");
return false;
}
var Communicator = Activator.CreateInstance(type) as BaseCommunicator;
if (Communicator == null)
{
Console.WriteLine("BaseCommunicator not found.");
return false;
}
Communicator.CommunicatorConnections.Add("名称", CommunicatorName);
Communicator.CommunicatorConnections.Add("地址", IP);
Communicator.CommunicatorConnections.Add("端口", PORT);
if (!Communicator.Connect())
UIMessageBox.ShowError(Communicator.strMsg);
dicCommunicator.TryAdd(CommunicatorName, Communicator);
}
else
{
Console.WriteLine("No match found.");
}
}
return true;
}
public bool SaveAllCommunicator()
{
try
{
string strJson = string.Empty;
allCommunicatorsConnectionString = new ConcurrentDictionary();
foreach (var item in dicCommunicator)
{
string ClassName = item.Value.GetType().FullName;// "TCP"
string IP = item.Value.CommunicatorConnections["地址"].ToString();//"127.0.0.1"
string PORT = item.Value.CommunicatorConnections["端口"].ToString();//"1111"
if (string.IsNullOrEmpty(ClassName) || string.IsNullOrEmpty(IP) || string.IsNullOrEmpty(PORT))
break;
string CommunicatorConnectionString = $"({ClassName}){IP}:{PORT}";
allCommunicatorsConnectionString.TryAdd(item.Key, CommunicatorConnectionString);
}
strJson = JsonConvert.SerializeObject(allCommunicatorsConnectionString);
BaseCommunicator.JsonFormatting(ref strJson);
//判断文件夹是否存在,防呆输入为文件名称
string directoryPath = Path.GetDirectoryName(allCommunicatorsConnectionStringPath);
if (!Directory.Exists(directoryPath))
{
try
{
Directory.CreateDirectory(directoryPath);
}
catch (Exception)
{ }
}
File.WriteAllText(allCommunicatorsConnectionStringPath, strJson, Encoding.UTF8);
return true;
}
catch { return false; }
}
///
/// 创建对象实例
///
///
/// 命名空间.类型名
///
public static T CreateInstance(string fullName)
{
Type o = Type.GetType(fullName);
dynamic obj = Activator.CreateInstance(o, true);
return (T)obj;//类型转换并返回
}
int lastMenuIndex = 0;
private void uiNavBar1_MenuItemClick(string itemText, int menuIndex, int pageIndex)
{
switch (lastMenuIndex)
{
//第一个节点是相机
//上一个节点是相机的话需要取消显示回调
case 1:
for (int i = CamerasPageIndex + 1; ; i++)
{
//根据页面索引获取页面
object page1 = GetPage(i);
if (page1 == null)
break;
if (page1 is CameraPage)
{
((CameraPage)page1).Unsubscribe();
((CameraPage)page1).StopContinueGrabbing();
}
}
break;
default:
break;
}
switch (menuIndex)
{
//第一个节点是相机
//当前选择的节点是相机的话需要重新加载显示回调
case 1:
//根据页面索引获取页面
object page1 = GetPage(pageIndex);
if (page1 == null)
break;
if (page1 is CameraPage)
((CameraPage)page1).Subscribe();
break;
//第五个节点是切换语言
case 5:
UIStyle style = (UIStyle)pageIndex;
if (pageIndex < UIStyle.Colorful.Value())
StyleManager.Style = style;
else
uiNavMenu1.SelectPage(pageIndex);
break;
default:
uiNavMenu1.SelectPage(pageIndex);
break;
}
lastMenuIndex = menuIndex;
}
int lastPageIndex = 0;
private void uiNavMenu1_MenuItemClick(TreeNode node, NavMenuItem item, int pageIndex)
{
//上一个节点是相机的话需要取消显示回调
if (lastPageIndex >= 2000 && lastPageIndex < 3000)
{
//根据页面索引获取页面
object page1 = GetPage(lastPageIndex);
if (page1 == null)
return;
if (page1 is CameraPage)
{
((CameraPage)page1).Unsubscribe();
((CameraPage)page1).StopContinueGrabbing();
}
}
//上一个节点是相机的话需要取消显示回调
if (lastPageIndex >= 3000 && lastPageIndex < 4000)
{
//根据页面索引获取页面
object page1 = GetPage(lastPageIndex);
if (page1 == null)
return;
if (page1 is ProcessPage)
{
((ProcessPage)page1).Unsubscribe();
}
}
//当前选择的节点是相机的话需要重新加载显示回调
if (pageIndex >= 2000 && pageIndex < 3000)
{
//根据页面索引获取页面
object page1 = GetPage(pageIndex);
if (page1 == null)
return;
if (page1 is CameraPage)
((CameraPage)page1).Subscribe();
}
lastPageIndex = pageIndex;
}
private void Form1_PageSelected(object sender, UIPageEventArgs e)
{
if (e.Page != null)
Console.WriteLine(e.Page.Text);
}
private void 关于ToolStripMenuItem1_Click(object sender, EventArgs e)
{
UIMessageBox.Show(Version, "关于", Style, UIMessageBoxButtons.OK, false);
}
private void 关于ToolStripMenuItem_Click(object sender, EventArgs e)
{
Process.Start("https://gitee.com/yhuse/SunnyUI");
}
private void Form1_HotKeyEventHandler(object sender, HotKeyEventArgs e)
{
if (e.hotKey.ModifierKey == Sunny.UI.ModifierKeys.Shift && e.hotKey.Key == Keys.F8)
{
this.ShowInfoTip("您按下了全局系统热键 Shift+F8");
}
}
private void Form1_ReceiveParams(object sender, UIPageParamsArgs e)
{
Text = e.Value.ToString();
SendParamToPage(1001, "传值给页面");
}
private void timer1_Tick(object sender, EventArgs e)
{
uiPanel3.Text = DateTime.Now.ToString();
}
private void timer60_Tick(object sender, EventArgs e)
{
bLogin = false;
}
private void NZhCN_Click(object sender, EventArgs e)
{
UIStyles.CultureInfo = CultureInfos.zh_CN;
}
private void NZhTW_Click(object sender, EventArgs e)
{
UIStyles.CultureInfo = CultureInfos.zh_TW;
}
private void NEnUS_Click(object sender, EventArgs e)
{
UIStyles.CultureInfo = CultureInfos.en_US;
}
///
/// 重载多语翻译
///
public override void Translate()
{
//必须保留
base.Translate();
//读取翻译代码中的多语资源
CodeTranslator.Load(this);
//设置多语资源
//this.CloseAskString = CodeTranslator.Current.CloseAskString;
//this.uiNavMenu1.Nodes[0].Text = this.uiNavBar1.Nodes[0].Text = CodeTranslator.Current.Controls;
//this.uiNavMenu1.Nodes[1].Text = this.uiNavBar1.Nodes[1].Text = CodeTranslator.Current.Forms;
//this.uiNavMenu1.Nodes[2].Text = this.uiNavBar1.Nodes[2].Text = CodeTranslator.Current.Charts;
//this.uiNavMenu1.Nodes[3].Text = this.uiNavBar1.Nodes[3].Text = CodeTranslator.Current.Industrial;
//this.uiNavBar1.Nodes[4].Text = CodeTranslator.Current.Theme;
//this.uiNavMenu1.Nodes[4].Text = CodeTranslator.Current.Symbols;
//this.uiNavMenu1.Nodes[5].Text = CodeTranslator.Current.Colorful;
this.uiNavBar1.Invalidate();
this.uiNavMenu1.Invalidate();
}
private class CodeTranslator : IniCodeTranslator
{
public string CloseAskString { get; set; } = "您确认要退出程序吗?";
public string Controls { get; set; } = "相机";
public string Forms { get; set; } = "窗体";
public string Charts { get; set; } = "图表";
public string Industrial { get; set; } = "工控";
public string Theme { get; set; } = "主题";
public string Symbols { get; set; } = "字体图标";
public string Colorful { get; set; } = "多彩主题";
}
bool bLogin = false;
private void uiAvatar1_DoubleClick(object sender, EventArgs e)
{
LoginForm loginForm = new LoginForm();
loginForm.ShowDialog();
bLogin = loginForm.IsLogin;
}
private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
{
foreach (ICamera camera in dicCameras.Values)
{
camera.Dispose();
}
SaveAllCommunicator();
foreach (BaseCommunicator communicator in dicCommunicator.Values)
{
//communicator.Dispose();
communicator.Disconnect();
}
}
}
}