From 6ef4ced299197b0a8480734d3fda9e32b38e7a9a Mon Sep 17 00:00:00 2001
From: C3204 <zhengyabo@lanpucloud.cn>
Date: 星期二, 23 十二月 2025 13:38:28 +0800
Subject: [PATCH] 添加兴启新增的HR相机类等项目文件,并更新2DCameraForm。

---
 LB_SmartVision/ProcessRun/ProcessRunBll.cs               |   25 
 LB_SmartVision/VisionForm.cs                             |  454 ++++++++++++++++++++++
 LB_VisionProcesses/Forms/GlobalVarForm.Designer.cs       |   28 
 LB_SmartVision/Forms/Pages/ProcessPage/ProcessControl.cs |    2 
 LB_SmartVisionCommon/UserData.cs                         |    4 
 LB_SmartVision/log4net.config                            |  107 +++++
 LB_VisionProcesses/Cameras/2DCameraForm.Designer.cs      |  346 ++++++++--------
 LB_SmartVision/VisionForm.Designer.cs                    |    3 
 LB_SmartVision/LB_SmartVision.csproj                     |    1 
 LB_VisionProcesses/Cameras/2DCameraForm.cs               |  225 ++++++++--
 10 files changed, 937 insertions(+), 258 deletions(-)

diff --git a/LB_SmartVision/Forms/Pages/ProcessPage/ProcessControl.cs b/LB_SmartVision/Forms/Pages/ProcessPage/ProcessControl.cs
index 43158ae..3e3f7f4 100644
--- a/LB_SmartVision/Forms/Pages/ProcessPage/ProcessControl.cs
+++ b/LB_SmartVision/Forms/Pages/ProcessPage/ProcessControl.cs
@@ -101,7 +101,7 @@
                 return false;
             }
 
-            if (isCircleRuning || ProcessRunBll.bPruning)
+            if (isCircleRuning || ProcessRunBll.bRuning)
                 ProcessRunBll.LogInfo($"{ProcessRunBll.Name}姝e湪杩愯", LogInfoType.ERROR);
 
             ProcessRunBll.Run();
diff --git a/LB_SmartVision/LB_SmartVision.csproj b/LB_SmartVision/LB_SmartVision.csproj
index 416a4e6..9232540 100644
--- a/LB_SmartVision/LB_SmartVision.csproj
+++ b/LB_SmartVision/LB_SmartVision.csproj
@@ -14,6 +14,7 @@
   </ItemGroup>
 
   <ItemGroup>
+    <ProjectReference Include="..\LB_SmartVisionLoginUI\LB_SmartVisionLoginUI.csproj" />
     <ProjectReference Include="..\LB_VisionControl\LB_VisionControl.csproj" />
     <ProjectReference Include="..\LB_VisionFlowNode\LB_VisionFlowNode.csproj" />
     <ProjectReference Include="..\LB_VisionProcesses\LB_VisionProcesses.csproj" />
diff --git a/LB_SmartVision/ProcessRun/ProcessRunBll.cs b/LB_SmartVision/ProcessRun/ProcessRunBll.cs
index 0555a01..ddd7a6c 100644
--- a/LB_SmartVision/ProcessRun/ProcessRunBll.cs
+++ b/LB_SmartVision/ProcessRun/ProcessRunBll.cs
@@ -27,7 +27,9 @@
             foreach (var item in IProcess.dicProcesses)
             {
                 if (NodeName.StartsWith(item.Key))
+                {
                     return item.Value.ToString();
+                }
             }
 
             return string.Empty;
@@ -41,7 +43,7 @@
         /// <summary>
         /// 杩愯鏍囪
         /// </summary>
-        public bool bPruning
+        public bool bRuning
         {
             set
             {
@@ -903,9 +905,8 @@
         /// <returns></returns>
         public bool Run()
         {
-            bPruning = true;
+            bRuning = true;
             bCompleted = false;
-
             DateTime StartTime = DateTime.Now;
             try
             {
@@ -921,30 +922,34 @@
                 Result = false;
                 Msg = string.Format("杩愯鍙戦�佷簡鎰忓{0}", ex.Message.Trim());
             }
-
             RunTime = (DateTime.Now - StartTime).TotalMilliseconds;
-
-            bPruning = false;
+            bRuning = false;
             bCompleted = true;
-
             if (Result)
             {
                 total_OK++;
                 Msg = "杩愯鎴愬姛";
             }
             else
+            {
                 total_NG++;
-
+            }
             if (IProcess.dicGlobalVars.ContainsKey($"{Name}.Result"))
+            {
                 IProcess.dicGlobalVars[$"{Name}.Result"] = Result;
+            }
             else
+            {
                 IProcess.dicGlobalVars.TryAdd($"{Name}.Result", Result);
-
+            }
             if (IProcess.dicGlobalVars.ContainsKey($"{Name}.Msg"))
+            {
                 IProcess.dicGlobalVars[$"{Name}.Msg"] = Msg;
+            }
             else
+            {
                 IProcess.dicGlobalVars.TryAdd($"{Name}.Msg", Msg);
-
+            }
             // 鎵嬪姩瑙﹀彂鍨冨溇鍥炴敹
             GC.Collect();
             return Result;
diff --git a/LB_SmartVision/VisionForm.Designer.cs b/LB_SmartVision/VisionForm.Designer.cs
index 218c68b..ef9e25a 100644
--- a/LB_SmartVision/VisionForm.Designer.cs
+++ b/LB_SmartVision/VisionForm.Designer.cs
@@ -189,6 +189,7 @@
             btn_Login.TabIndex = 3;
             btn_Login.Text = "鐢ㄦ埛鐧诲綍";
             btn_Login.TextAlignment = StringAlignment.Center;
+            btn_Login.Click += btn_Login_Click;
             // 
             // btn_GlobalVar
             // 
@@ -209,6 +210,7 @@
             btn_GlobalVar.TabIndex = 4;
             btn_GlobalVar.Text = "鍏ㄥ眬鍙橀噺";
             btn_GlobalVar.TextAlignment = StringAlignment.Center;
+            btn_GlobalVar.Click += btn_GlobalVar_Click;
             // 
             // com_ProductName
             // 
@@ -222,6 +224,7 @@
             com_ProductName.Name = "com_ProductName";
             com_ProductName.Size = new Size(152, 26);
             com_ProductName.TabIndex = 5;
+            com_ProductName.SelectedValueChanged += com_ProductName_SelectedValueChanged;
             // 
             // materialTabSelector
             // 
diff --git a/LB_SmartVision/VisionForm.cs b/LB_SmartVision/VisionForm.cs
index 7d8803e..b014f34 100644
--- a/LB_SmartVision/VisionForm.cs
+++ b/LB_SmartVision/VisionForm.cs
@@ -1,4 +1,5 @@
 锘縰sing HalconDotNet;
+using LB_SmartVision.Forms;
 using LB_SmartVision.Forms.Pages;
 using LB_SmartVision.Forms.Pages.CameraPage;
 using LB_SmartVision.Forms.Pages.CommunicatorPage;
@@ -9,10 +10,15 @@
 using LB_SmartVision.Forms.Pages.UserManagementPage;
 using LB_SmartVision.ProcessRun;
 using LB_SmartVision.Tool;
+using LB_SmartVisionCommon;
+using LB_SmartVisionLoginUI;
 using LB_VisionProcesses;
 using LB_VisionProcesses.Cameras;
+using LB_VisionProcesses.Cameras.HRCameras;
 using LB_VisionProcesses.Communicators;
 using LB_VisionProcesses.Communicators.TCom;
+using LB_VisionProcesses.Forms;
+using log4net.Config;
 using Newtonsoft.Json;
 using Newtonsoft.Json.Serialization;
 using Sunny.UI;
@@ -229,9 +235,78 @@
 
         }
 
-        private void LogInfo(string arg1, LogInfoType type)
+        private void LogInfo(string strLog, LogInfoType infoType)
         {
+            if (string.IsNullOrEmpty(strLog))
+            {
+                return;
+            }
+            string strInfo = DateTime.Now.ToString("[yyyy:MM:HH:mm:ss:fff] ");
+            strInfo += strLog;
+            if (infoType != LogInfoType.NOSHOW)
+            {
+                // 濡傛灉褰撳墠涓嶆槸 UI 绾跨▼锛屽垯閫氳繃 Invoke 灏嗘搷浣滆皟搴﹀埌 UI 绾跨▼
+                if (this.rich_Info.InvokeRequired)
+                {
+                    this.rich_Info.BeginInvoke(new Action<string>((msg) =>
+                    {
+                        if (this.rich_Info.Lines.Length > 1000)
+                        {
+                            this.rich_Info.Clear();
+                        }
+                        switch (infoType)
+                        {
+                            case LogInfoType.INFO:
+                                this.rich_Info.SelectionColor = Color.Wheat;
+                                break;
+                            case LogInfoType.WARN:
+                                this.rich_Info.SelectionColor = Color.LightGoldenrodYellow;
+                                break;
+                            case LogInfoType.PASS:
+                                this.rich_Info.SelectionColor = Color.Green;
+                                break;
+                            case LogInfoType.ERROR:
+                                this.rich_Info.SelectionColor = Color.Red;
+                                break;
+                        }
 
+                        // 鏇存柊 UI 鎺т欢锛屾瘮濡傛樉绀烘帴鏀跺埌鐨勬秷鎭�
+                        this.rich_Info.AppendText(strInfo);
+                        this.rich_Info.AppendText("\r\n");
+                        this.rich_Info.SelectionStart = this.rich_Info.Text.Length;
+                        this.rich_Info.ScrollToCaret();
+                    }), strInfo);
+                }
+                else
+                {
+
+                    if (this.rich_Info.Lines.Length > 1000)
+                        this.rich_Info.Clear();
+
+                    // 濡傛灉宸茬粡鍦� UI 绾跨▼涓婏紝鐩存帴鏇存柊 UI
+                    switch (infoType)
+                    {
+                        case LogInfoType.INFO:
+                            this.rich_Info.SelectionColor = Color.Wheat;
+                            break;
+                        case LogInfoType.WARN:
+                            this.rich_Info.SelectionColor = Color.Yellow;
+                            break;
+                        case LogInfoType.PASS:
+                            this.rich_Info.SelectionColor = Color.Green;
+                            break;
+                        case LogInfoType.ERROR:
+                            this.rich_Info.SelectionColor = Color.Red;
+                            break;
+                    }
+
+                    this.rich_Info.AppendText(strInfo);
+                    this.rich_Info.AppendText("\r\n");
+                    this.rich_Info.SelectionStart = this.rich_Info.Text.Length;
+                    this.rich_Info.ScrollToCaret();
+                }
+            }
+            AsyncLogHelper.Info(strLog);
         }
 
         public static bool SaveAllLayout()
@@ -406,9 +481,36 @@
             }
             catch { return false; }
         }
+        private void EnsureDirectory(string path)
+        {
+            // 濡傛灉鏄浉瀵硅矾寰勶紝杞崲涓虹粷瀵硅矾寰�
+            string fullPath = Path.IsPathRooted(path) ? path : Path.GetFullPath(path);
+
+            if (!Directory.Exists(fullPath))
+            {
+                Directory.CreateDirectory(fullPath);
+                LogInfo($"鉁� 鐩綍鍒涘缓: {fullPath}", LogInfoType.INFO);
+            }
+            else
+            {
+                LogInfo($"鈩癸笍 鐩綍宸插瓨鍦�: {fullPath}", LogInfoType.INFO);
+            }
+        }
 
         private void VisionForm_Load(object sender, EventArgs e)
         {
+            XmlConfigurator.Configure(new System.IO.FileInfo("log4net.config"));
+            string[] paths = {
+            @"鐢熶骇鏃ュ織\Run_Log",
+            @"鐢熶骇鏃ュ織\Debug_Log",
+            @"鐢熶骇鏃ュ織\Error_Log",
+            @"鐢熶骇鏃ュ織\Fatal",
+            @"鐢熶骇鏃ュ織\Warn",
+            };
+            foreach (string path in paths)
+            {
+                EnsureDirectory(path);
+            }
             if (!LB_SmartVision.Tool.Tool.ReadStringConfig("鏁版嵁搴撳悕绉�", out string DateBaseName))
             {
                 DateBaseName = "浜у搧0";
@@ -526,7 +628,7 @@
                 switch (brand)
                 {
                     case CameraBrand.HRCamera:
-                        //camera = new HRCamera();
+                        camera = new HRCamera();
                         break;
                     case CameraBrand.LBCamera:
                         //camera = new LBCamera();
@@ -957,7 +1059,6 @@
 
                 File.WriteAllText(GlobalVar.allLayoutPath, strJson, Encoding.UTF8);
                 LogInfo($"鍏ㄥ眬甯冨眬淇濆瓨鎴愬姛", LogInfoType.INFO);
-
                 return true;
             }
             catch { return false; }
@@ -970,6 +1071,7 @@
                 if (!File.Exists(allLayoutPath))
                 {
                     Debug.WriteLine("鏂囦欢涓嶅瓨鍦ㄥ垱寤虹┖鏂囦欢");
+                    AsyncLogHelper.Info("鏂囦欢涓嶅瓨鍦ㄥ垱寤虹┖鏂囦欢");
                     // 鑾峰彇涓嶅甫鏂囦欢鍚嶇殑鐩綍璺緞
                     string directoryPath = Path.GetDirectoryName(allLayoutPath);
                     SaveAllLayout();
@@ -993,5 +1095,351 @@
             }
             catch { return false; }
         }
+
+        private void btn_GlobalVar_Click(object sender, EventArgs e)
+        {
+            GlobalVarForm globalVarForm = new GlobalVarForm(GlobalVar.allProcessVarsPath);
+            globalVarForm.ShowDialog();
+        }
+
+        private void btn_Login_Click(object sender, EventArgs e)
+        {
+            //this.Hide();
+            //MainWindow.InstanceLoginandConfirmation().ShowDialog();
+            //if (!MainWindow.InstanceLoginandConfirmation().isQuit && MainWindow.InstanceLoginandConfirmation().correctUser)
+            //{
+            //    MainWindow.InstanceLoginandConfirmation().closeLoginFrm();
+            //    if (UserManager.Instance.CurrentUser.EmployeePermission == UserPermission.Operator)
+            //    {
+            //        //鎿嶄綔鍛樻潈闄愮晫闈�
+            //    }
+            //    else if (UserManager.Instance.CurrentUser.EmployeePermission == UserPermission.Engineer)
+            //    {
+            //        //鎶�鏈憳鏉冮檺鐣岄潰
+            //    }
+            //    else if (UserManager.Instance.CurrentUser.EmployeePermission == UserPermission.Administrator)
+            //    {
+            //        //绠$悊鍛樻潈闄愮晫闈�
+            //    }
+            //    this.Show();
+            //}
+        }
+
+        private void com_ProductName_SelectedValueChanged(object sender, EventArgs e)
+        {
+            if (com_ProductName.SelectedItem == null || com_ProductName.SelectedItem?.ToString() == GlobalVar.strProductName)
+            {
+                return;
+            }
+            if (com_ProductName.SelectedItem?.ToString() == "鏂板")
+            {
+                using (CreateProductForm createDatabaseForm = new CreateProductForm())
+                {
+                    createDatabaseForm.ShowDialog();
+                }
+            }
+            else
+            {
+                //鍙樻洿鍓嶄繚瀛樼幇鏈夐厤缃�
+                SaveAllSetting();
+                LogInfo($"浜у搧浠巤GlobalVar.strProductName}鍒囨崲{com_ProductName.SelectedItem?.ToString()}", LogInfoType.WARN);
+                //Tool.WriteConfig("鏁版嵁搴撳悕绉�", com_ProductName.SelectedItem?.ToString());
+                GlobalVar.strProductName = com_ProductName.SelectedItem?.ToString();
+                foreach (BaseCamera camera in GlobalVar.dicCameras.Values)
+                {
+                    camera.Dispose();
+                }
+                GlobalVar.dicCameras.Clear();
+                foreach (BaseCommunicator communicator in GlobalVar.dicCommunicators.Values)
+                {
+                    communicator.TriggerRunMessageReceived -= TriggerRunMessageReceived;
+                    communicator.Disconnect();
+                }
+                GlobalVar.dicCommunicators.Clear();
+                //淇濆瓨瀹岀幇鏈夐厤缃悗鏂紑鎵�鏈変簨浠�
+                foreach (var Process in GlobalVar.dicProcesses.Values)
+                {
+                    Process.LogInfo -= LogInfo;
+                }
+                GlobalVar.dicProcesses.Clear();
+                //閲嶆柊鍔犺浇閰嶇疆
+                this.VisionForm_Load(sender, e);
+            }
+        }
+        private void TriggerRunMessageReceived(string name, string msg)
+        {
+            if (msg == null || msg.Trim('\0', '\r', '\n', ' ', '\uFEFF') == "" || string.IsNullOrEmpty(msg))
+            {
+                return;
+            }
+            LogInfo(string.Format("閫氳[{0}]鎺ユ敹鍒扮殑娑堟伅\"{1}\"", name, msg), LogInfoType.INFO);
+            var matchedItems = GlobalVar.dicProcessSetting
+                .Where(item =>
+                {
+                    var value = item.Value;
+                    var triggerComm = value["瑙﹀彂閫氳"];
+                    var triggerChar = value["瑙﹀彂瀛楃"];
+
+                    return triggerComm != null && triggerComm.Equals(name) &&
+                           (string.IsNullOrEmpty(triggerChar?.ToString()) ||
+                            msg.StartsWith(triggerChar.ToString()));
+                })
+                .ToList(); // 閬垮厤閲嶅瀛楀吀璁块棶鍜岃绠辨搷浣�
+            if (matchedItems.Count <= 0)
+            {
+                return;
+            }
+            if (!ckb_AllowRun.Checked)
+            {
+                LogInfo(string.Format($"妫�鏌ュ埌鍙瑙﹀彂鐨勬祦绋�,褰撳墠涓嶄负杩愯妯″紡!"), LogInfoType.ERROR);
+                return;
+            }
+            GlobalVar.dicProcesses.Values.AsParallel().ForAll(v => v.bCompleted = false);
+            LogInfo(string.Format($"妫�鏌ュ埌鍙瑙﹀彂鐨勬祦绋�,娓呯┖鎵�鏈夋祦绋嬭繍琛屽畬鎴愭爣璁颁綅!"), LogInfoType.INFO);
+            Parallel.ForEach(matchedItems, item =>
+            {
+                string ProcessName = item.Value["娴佺▼鍚�"];
+                LogInfo($"娴佺▼[{ProcessName}]寮�濮嬭繍琛�", LogInfoType.INFO);
+                if (!GlobalVar.dicProcesses.ContainsKey(ProcessName))
+                {
+                    LogInfo(string.Format("娴佺▼[{0}]涓嶅瓨鍦�,璇锋鏌ユ祦绋嬭缃�", ProcessName), LogInfoType.ERROR);
+                    return;
+                }
+                ProcessRunBll RunBll = GlobalVar.dicProcesses[ProcessName];
+                if (RunBll == null || RunBll.bRuning)
+                {
+                    LogInfo(string.Format("娴佺▼[{0}]涓婃鏈繍琛屽畬鎴�,瑙﹀彂澶辫触", ProcessName)
+                        , LogInfoType.ERROR);
+                    return;
+                }
+                try
+                {
+                    bool result = false;
+                    string msg = string.Empty;
+                    int times = Convert.ToInt32(item.Value["閲嶆祴娆℃暟"].ToString());
+                    string ConnecResult = item.Value["鍏宠仈缁撴灉"];
+                    if (times < 0)
+                    {
+                        result = GlobalVar.dicProcesses[ProcessName].Run();
+                        msg = GlobalVar.dicProcesses[ProcessName].Msg;
+                        if (!(string.IsNullOrEmpty(ConnecResult) || ConnecResult.Trim() == "鏈叧鑱�"))
+                        {
+                            GlobalVar.dicProcesses[ProcessName].GetBooleanOutput(ConnecResult, out result);
+                            GlobalVar.dicProcesses[ProcessName].Result = result;
+                        }
+                        if (!result)
+                        {
+                            LogInfo($"娴佺▼[{ProcessName}]琚己鍒惰繍琛屾垚鍔�", LogInfoType.WARN);
+                            GlobalVar.dicProcesses[ProcessName].Result = true;
+                            result = true;
+                        }
+                    }
+                    else
+                    {
+                        while (times >= 0)
+                        {
+                            result = RunBll.Run();
+                            msg = RunBll.Msg;
+                            if (!(string.IsNullOrEmpty(ConnecResult) || ConnecResult.Trim() == "鏈叧鑱�"))
+                            {
+                                RunBll.GetBooleanOutput(ConnecResult, out result);
+                                RunBll.Result = result;
+                            }
+                            if (result)
+                            {
+                                break;
+                            }
+                            else if (!result && times > 0)
+                            {
+                                LogInfo(string.Format("娴佺▼[{0}]杩愯澶辫触閲嶆柊娴嬭瘯,鍓╀綑娆℃暟[{1}]", ProcessName, times), LogInfoType.WARN);
+                            }
+                            times--;
+                        }
+                    }
+                    string ConnectProcess = item.Value["鍏宠仈娴佺▼"];
+                    if (!(ConnectProcess == null || string.IsNullOrEmpty(ConnectProcess) || ConnectProcess.Trim() == ""))
+                    {
+                        //鐢ㄩ�楀彿鎴栬�呭垎鍙峰幓闂撮殧鍏宠仈娴佺▼
+                        string[] arrConnectProcess;
+                        if (ConnectProcess.Split(';').Length >= ConnectProcess.Split(',').Length)
+                        {
+                            arrConnectProcess = ConnectProcess.Split(';');
+                        }
+                        else
+                        {
+                            arrConnectProcess = ConnectProcess.Split(',');
+                        }
+                        foreach (string strConnectProcess in arrConnectProcess)
+                        {
+                            if (GlobalVar.dicProcesses.ContainsKey(strConnectProcess))
+                            {
+                                ProcessRunBll ConnectRunBll = GlobalVar.dicProcesses[strConnectProcess];
+                                int waitTime = 10;
+                                DateTime startTime = DateTime.Now;
+                                while ((DateTime.Now - startTime).TotalSeconds < waitTime
+                                && (ConnectRunBll.bRuning || !ConnectRunBll.bCompleted))
+                                {
+                                    LogInfo(string.Format("鍏宠仈娴佺▼[{0}]鏈繍琛屽畬鎴�,鍓╀綑绛夊緟[{1}]s", strConnectProcess, (waitTime - ((DateTime.Now - startTime).TotalSeconds)))
+                                        , LogInfoType.NOSHOW);
+                                    Thread.Sleep(1000);
+                                    continue;
+                                }
+                                if (ConnectRunBll.bRuning || !ConnectRunBll.bCompleted)
+                                {
+                                    GlobalVar.dicProcesses[ProcessName].Msg = string.Format("娴佺▼[{0}]鏈繍琛屽畬鎴�", ProcessName);
+                                    LogInfo(string.Format("鍏宠仈娴佺▼[{0}]鏈繍琛屽畬鎴�", strConnectProcess), LogInfoType.ERROR);
+                                    result = false;
+                                    break;
+                                }
+                                else if (!ConnectRunBll.bRuning && ConnectRunBll.bCompleted)
+                                {
+                                    LogInfo(string.Format("鍏宠仈娴佺▼[{0}]杩愯瀹屾垚", strConnectProcess), LogInfoType.INFO);
+                                }
+                                result &= ConnectRunBll.Result;
+                                if (!ConnectRunBll.Result)
+                                {
+                                    LogInfo($"娴佺▼[{ProcessName}]鐨勫叧鑱旀祦绋媅{strConnectProcess}]杩愯澶辫触", LogInfoType.ERROR);
+                                    msg = $"鍏宠仈娴佺▼[{strConnectProcess}]杩愯澶辫触";
+                                }
+                            }
+                        }
+                    }
+                    LogInfo(result ? $"娴佺▼[{ProcessName}]杩愯鎴愬姛" : $"娴佺▼[{ProcessName}]杩愯澶辫触,鍘熷洜鏄瘂msg}", result ? LogInfoType.PASS : LogInfoType.ERROR);
+                    string SendComName = result ? item.Value["鎴愬姛閫氳"] : item.Value["澶辫触閫氳"];
+                    string SendMsg = result ? item.Value["鎴愬姛瀛楃"] : item.Value["澶辫触瀛楃"];
+                    if (GlobalVar.dicCommunicators.ContainsKey(SendComName) && (!string.IsNullOrEmpty(SendMsg) || SendMsg.Trim() != ""))
+                    {
+                        GlobalVar.dicCommunicators[SendComName].SendMessage(SendMsg);
+                        LogInfo(string.Format("鍙戦�佺粰[{0}]浜嗘秷鎭痋"{1}\"", SendComName, SendMsg), LogInfoType.INFO);
+                    }
+                }
+                catch (Exception ex)
+                {
+                    LogInfo(string.Format("娴佺▼[{0}]杩愯鍙戠敓浜嗘剰澶�,鍘熷洜鏄�:{1}", ProcessName, ex.Message + $"銆恵ex.StackTrace}銆�"), LogInfoType.ERROR);
+                    RunBll.Result = false;
+                    RunBll.Msg = $"[鎰忓]{ex.Message}";
+                }
+                finally
+                {
+                    #region 浠嶳unSettingPage鍜孡ayout涓幏鍙栨槸鍚︿繚瀛樺浘鐗�
+                    string strImageType = "jpeg";
+                    bool bSaveRunImage = false;
+                    bool bSaveResultImage = false;
+                    long lImageQuality = 100L;
+                    //ckbSaveRunImage
+                    if (GlobalVar.ControlStates.TryGetValue("ckbSaveRunImage_CheckBox", out object oSaveRunImage))
+                    {
+                        if (oSaveRunImage != null && oSaveRunImage is bool)
+                        {
+                            bSaveRunImage = (bool)oSaveRunImage;
+                        }
+                    }
+                    //ckbSaveResultImage
+                    if (GlobalVar.ControlStates.TryGetValue("ckbSaveResultImage_CheckBox", out object oSaveResultImage))
+                    {
+                        if (oSaveResultImage != null && oSaveResultImage is bool)
+                        {
+                            bSaveResultImage = (bool)oSaveResultImage;
+                        }
+                    }
+                    //txtImageQuality
+                    if (GlobalVar.ControlStates.TryGetValue("txtImageQuality_TextBox", out object oImageQuality))
+                    {
+                        if (oImageQuality != null && oImageQuality is string)
+                        {
+                            lImageQuality = Convert.ToInt64((string)oImageQuality);
+                        }
+                    }
+                    //cmbImageType
+                    if (GlobalVar.ControlStates.TryGetValue("cmbImageType_ComboBox", out object oImageType))
+                    {
+                        try
+                        {
+                            // 鍔ㄦ�佽В鏋怌omboBox鏁版嵁
+                            var json = JsonConvert.SerializeObject(oImageType);
+                            var comboData = JsonConvert.DeserializeAnonymousType(json, new
+                            {
+                                Items = new List<object>(),
+                                SelectedIndex = 0
+                            });
+
+                            if (comboData != null && comboData.Items.Count > 0)
+                            {
+                                strImageType = comboData.Items[comboData.SelectedIndex].ToString();
+                            }
+                        }
+                        catch { }
+                    }
+                    // 鐢熸垚鍥剧墖骞舵樉绀哄埌鎺т欢涓�
+                    HObject InputImage = null;
+                    HObject RecordImage = null;
+
+                    foreach (var layout in GlobalVar.dicLayout.Values
+                                .Where(layout => layout.ProcessName == ProcessName)
+                                .ToList())
+                    {
+                        string title = layout.Title;
+                        string strImagePath = layout.SaveImageDir;
+                        if (!AllProcessesPage.dicProcessControls.ContainsKey(title))
+                        {
+                            continue;
+                        }
+                        RunBll.GetImage(layout, out InputImage, out RecordImage);
+                        AllProcessesPage.dicProcessControls[title].ShowHoImage(RecordImage);
+                        if (!string.IsNullOrEmpty(layout.SaveImageDir))
+                        {
+                            string fileNameHead = layout.SaveImageHead;
+                            string result = Regex.Replace(fileNameHead, @"\{[^}]+\}", match =>
+                            {
+                                // 鍘婚櫎{}鍙繚鐣欐嫭鍙峰唴鐨勫唴瀹�
+                                string content = match.Value;
+                                content = content.Trim('{', '}'); // 鍘婚櫎棣栧熬鐨剓}
+
+                                RunBll.GetStringOutput(content, out string str);
+                                return str;
+                            });
+                            string fileName = $"{result}-[{DateTime.Now.ToString("HH.mm.ss.ffff")}]";
+                            // 浣跨敤姝e垯琛ㄨ揪寮忔浛鎹㈡墍鏈夐潪娉曞瓧绗�
+                            string invalidChars = Regex.Escape(new string(Path.GetInvalidFileNameChars()));
+                            string pattern = $"[{invalidChars}]";
+                            fileName = Regex.Replace(fileName, pattern, "-");
+                            strImagePath = Regex.Replace(strImagePath, @"\{[^}]+\}", match =>
+                            {
+                                // 鍘婚櫎{}鍙繚鐣欐嫭鍙峰唴鐨勫唴瀹�
+                                string content = match.Value;
+                                content = content.Trim('{', '}'); // 鍘婚櫎棣栧熬鐨剓}
+                                RunBll.GetStringOutput(content, out string str);
+                                return str;
+                            });
+                            if (bSaveRunImage)
+                            {
+                                // 鏈�鍚庝竴绾х洰褰曞繀椤讳负骞存湀鏃�,浼氭牴鎹椂闂存潵鍒犻櫎鏃у浘鐗�
+                                string directoryPath = Path.Combine(strImagePath, $"{ProcessName}\\鍘熷浘\\{RunBll.Result}\\{DateTime.Now.ToString("yyyyMMdd")}\\");
+                                LB_SmartVision.Tool.Tool.AddRealImage(InputImage, directoryPath, fileName, strImageType, lImageQuality);
+                            }
+                            if (bSaveResultImage)
+                            {
+                                // 鏈�鍚庝竴绾х洰褰曞繀椤讳负骞存湀鏃�,浼氭牴鎹椂闂存潵鍒犻櫎鏃у浘鐗�
+                                string directoryPath = Path.Combine(strImagePath, $"{ProcessName}\\鎴浘\\{RunBll.Result}\\{DateTime.Now.ToString("yyyyMMdd")}\\");
+                                LB_SmartVision.Tool.Tool.AddRealImage(RecordImage, directoryPath, fileName, "jpg", 50L);
+                            }
+                        }
+                    }
+                    foreach (var csv in GlobalVar.dicCsvSetting.Values
+                                .Where(csv => csv.ProcessName == ProcessName)
+                                .ToList())
+                    {
+                        if (RunBll.GetCsv(csv
+                            , out List<string> DataTitle, out Dictionary<string, object> ResultData))
+                        {
+                            string filePath = Path.Combine(GlobalVar.strPathCsv, $"{ProcessName}.csv");
+                            LB_SmartVision.Tool.Tool.SaveData(filePath, DataTitle, ResultData);
+                        }
+                    }
+                    #endregion
+                }
+            });
+        }
     }
 }
+
diff --git a/LB_SmartVision/log4net.config b/LB_SmartVision/log4net.config
new file mode 100644
index 0000000..0c99c8f
--- /dev/null
+++ b/LB_SmartVision/log4net.config
@@ -0,0 +1,107 @@
+锘�<?xml version="1.0" encoding="utf-8" ?>
+<configuration>
+<configSections>
+	<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
+</configSections>
+<log4net>
+	<root>
+		<level value="ALL"/>
+		<!-- 娣诲姞鎵�鏈塧ppender寮曠敤 -->
+		<appender-ref ref="DebugLogger" />
+		<appender-ref ref="InfoLogger" />
+		<appender-ref ref="WarnLogger" />
+		<appender-ref ref="ErrorLogger" />
+		<appender-ref ref="FatalLogger" />
+	</root>
+	<appender name="DebugLogger" type="log4net.Appender.RollingFileAppender">
+		<file value="鐢熶骇鏃ュ織\Debug_Log\"/>
+		<appendToFile value="true" />
+		<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
+		<Encoding value="UTF-8" />
+		<maxSizeRollBackups value="-1"/>
+		<StaticLogFileName value="false"/>
+		<rollingStyle value="Date" />
+		<param name="datePattern" value="yyyy-MM/yyyy-MM-dd.'log'" />
+		<createDirs value="true" />
+		<filter type="log4net.Filter.LevelRangeFilter">
+			<levelMin value="DEBUG" />
+			<levelMax value="DEBUG" />
+		</filter>
+		<layout type="log4net.Layout.PatternLayout">
+			<param name="ConversionPattern" value="%date [%thread] %-5level %logger - %message%newline" />
+		</layout>
+	</appender>
+	<appender name="InfoLogger" type="log4net.Appender.RollingFileAppender">
+		<file value="鐢熶骇鏃ュ織\Run_Log\"/>
+		<appendToFile value="true" />
+		<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
+		<Encoding value="UTF-8" />
+		<maxSizeRollBackups value="-1"/>
+		<StaticLogFileName value="false"/>
+		<rollingStyle value="Date" />
+		<param name="datePattern" value="yyyy-MM/yyyy-MM-dd.'log'" />
+		<createDirs value="true" />
+		<filter type="log4net.Filter.LevelRangeFilter">
+			<levelMin value="INFO" />
+			<levelMax value="INFO" />
+		</filter>
+		<layout type="log4net.Layout.PatternLayout">
+			<param name="ConversionPattern" value="%date [%thread] %-5level %logger - %message%newline" />
+		</layout>
+	</appender>
+	<appender name="WarnLogger" type="log4net.Appender.RollingFileAppender">
+		<file value="鐢熶骇鏃ュ織\Warn\"/>
+		<appendToFile value="true" />
+		<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
+		<Encoding value="UTF-8" />
+		<maxSizeRollBackups value="10"/>
+		<StaticLogFileName value="false"/>
+		<rollingStyle value="Date" />
+		<param name="datePattern" value="yyyy-MM/yyyy-MM-dd.'log'" />
+		<createDirs value="true" />
+		<filter type="log4net.Filter.LevelRangeFilter">
+			<levelMin value="WARN" />
+			<levelMax value="WARN" />
+		</filter>
+		<layout type="log4net.Layout.PatternLayout">
+			<param name="ConversionPattern" value="%date [%thread] %-5level %logger - %message%newline" />
+		</layout>
+	</appender>
+	<appender name="ErrorLogger" type="log4net.Appender.RollingFileAppender">
+		<file value="鐢熶骇鏃ュ織\Error_Log\"/>
+		<appendToFile value="true" />
+		<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
+		<Encoding value="UTF-8" />
+		<maxSizeRollBackups value="-1"/>
+		<StaticLogFileName value="false"/>
+		<rollingStyle value="Date" />
+		<param name="datePattern" value="yyyy-MM/yyyy-MM-dd.'log'" />
+		<createDirs value="true" />
+		<filter type="log4net.Filter.LevelRangeFilter">
+			<levelMin value="ERROR" />
+			<levelMax value="ERROR" />
+		</filter>
+		<layout type="log4net.Layout.PatternLayout">
+			<param name="ConversionPattern" value="%date [%thread] %-5level %logger - %message%newline" />
+		</layout>
+	</appender>
+	<appender name="FatalLogger" type="log4net.Appender.RollingFileAppender">
+		<file value="鐢熶骇鏃ュ織\Fatal\"/>
+		<appendToFile value="true" />
+		<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
+		<Encoding value="UTF-8" />
+		<maxSizeRollBackups value="-1"/>
+		<StaticLogFileName value="false"/>
+		<rollingStyle value="Date" />
+		<param name="datePattern" value="yyyy-MM/yyyy-MM-dd.'log'" />
+		<createDirs value="true" />
+		<filter type="log4net.Filter.LevelRangeFilter">
+			<levelMin value="FATAL" />
+			<levelMax value="FATAL" />
+		</filter>
+		<layout type="log4net.Layout.PatternLayout">
+			<param name="ConversionPattern" value="%date [%thread] %-5level %logger - %message%newline" />
+		</layout>
+	</appender>
+</log4net>
+</configuration>
\ No newline at end of file
diff --git a/LB_SmartVisionCommon/UserData.cs b/LB_SmartVisionCommon/UserData.cs
index c89d9e3..4a09bcf 100644
--- a/LB_SmartVisionCommon/UserData.cs
+++ b/LB_SmartVisionCommon/UserData.cs
@@ -74,6 +74,10 @@
         /// </summary>
         Operator,
         /// <summary>
+        /// UserPermission锛欵ngineer
+        /// </summary>
+        Engineer,
+        /// <summary>
         /// UserPermission锛欰dministrator
         /// </summary>
         Administrator
diff --git a/LB_VisionProcesses/Cameras/2DCameraForm.Designer.cs b/LB_VisionProcesses/Cameras/2DCameraForm.Designer.cs
index 1252b8a..ce2e332 100644
--- a/LB_VisionProcesses/Cameras/2DCameraForm.Designer.cs
+++ b/LB_VisionProcesses/Cameras/2DCameraForm.Designer.cs
@@ -29,15 +29,15 @@
         private void InitializeComponent()
         {
             System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(CameraForm));
-            cmb_Brand = new ComboBox();
-            cmb_SN = new ComboBox();
+            cmbBrand = new ComboBox();
+            cmbSN = new ComboBox();
             label1 = new Label();
             label2 = new Label();
-            btn_StartGrab = new Button();
-            btn_CloseGrab = new Button();
-            btn_GrabOnce = new Button();
-            btn_Open = new Button();
-            btn_Close = new Button();
+            btnStartGrab = new Button();
+            btnCloseGrab = new Button();
+            btnGrabOnce = new Button();
+            btnOpen = new Button();
+            btnClose = new Button();
             label5 = new Label();
             lblPicCount = new Label();
             txtGain = new TextBox();
@@ -54,9 +54,9 @@
             tableLayoutPanel3 = new TableLayoutPanel();
             tableLayoutPanel4 = new TableLayoutPanel();
             tableLayoutPanel5 = new TableLayoutPanel();
-            btn_Edit = new Button();
+            btnEdit = new Button();
             tableLayoutPanel6 = new TableLayoutPanel();
-            btn_SaveImage = new Button();
+            btnSaveImage = new Button();
             tableLayoutPanel7 = new TableLayoutPanel();
             tableLayoutPanel8 = new TableLayoutPanel();
             tableLayoutPanel1 = new TableLayoutPanel();
@@ -70,8 +70,8 @@
             cmbImagesPath = new ComboBox();
             tableLayoutPanel9 = new TableLayoutPanel();
             ckbLocalTest = new CheckBox();
-            btn_AddImages = new Button();
-            btn_LocalGrab = new Button();
+            btnAddImages = new Button();
+            btnLocalGrab = new Button();
             tableLayoutPanel10 = new TableLayoutPanel();
             label6 = new Label();
             txtTimeout = new TextBox();
@@ -100,25 +100,25 @@
             panel_2DCameraForm.SuspendLayout();
             SuspendLayout();
             // 
-            // cmb_Brand
+            // cmbBrand
             // 
-            cmb_Brand.Dock = DockStyle.Fill;
-            cmb_Brand.FormattingEnabled = true;
-            cmb_Brand.Location = new Point(53, 3);
-            cmb_Brand.Name = "cmb_Brand";
-            cmb_Brand.Size = new Size(297, 25);
-            cmb_Brand.TabIndex = 0;
+            cmbBrand.Dock = DockStyle.Fill;
+            cmbBrand.FormattingEnabled = true;
+            cmbBrand.Location = new Point(53, 3);
+            cmbBrand.Name = "cmbBrand";
+            cmbBrand.Size = new Size(296, 25);
+            cmbBrand.TabIndex = 0;
             // 
-            // cmb_SN
+            // cmbSN
             // 
-            cmb_SN.Dock = DockStyle.Fill;
-            cmb_SN.FormattingEnabled = true;
-            cmb_SN.Location = new Point(53, 3);
-            cmb_SN.Name = "cmb_SN";
-            cmb_SN.Size = new Size(297, 25);
-            cmb_SN.TabIndex = 1;
-            cmb_SN.SelectedIndexChanged += cmbSN_SelectedIndexChanged;
-            cmb_SN.MouseDown += cmbSN_MouseDown;
+            cmbSN.Dock = DockStyle.Fill;
+            cmbSN.FormattingEnabled = true;
+            cmbSN.Location = new Point(53, 3);
+            cmbSN.Name = "cmbSN";
+            cmbSN.Size = new Size(296, 25);
+            cmbSN.TabIndex = 1;
+            cmbSN.SelectedIndexChanged += cmbSN_SelectedIndexChanged;
+            cmbSN.MouseDown += cmbSN_MouseDown;
             // 
             // label1
             // 
@@ -142,65 +142,65 @@
             label2.Text = "SN";
             label2.TextAlign = ContentAlignment.MiddleCenter;
             // 
-            // btn_StartGrab
+            // btnStartGrab
             // 
-            btn_StartGrab.Dock = DockStyle.Fill;
-            btn_StartGrab.ForeColor = SystemColors.ControlText;
-            btn_StartGrab.Location = new Point(91, 3);
-            btn_StartGrab.Name = "btn_StartGrab";
-            btn_StartGrab.Size = new Size(82, 28);
-            btn_StartGrab.TabIndex = 5;
-            btn_StartGrab.Text = "杩炵画閲囬泦";
-            btn_StartGrab.UseVisualStyleBackColor = true;
-            btn_StartGrab.Click += btn_StartGrab_Click;
+            btnStartGrab.Dock = DockStyle.Fill;
+            btnStartGrab.ForeColor = SystemColors.ControlText;
+            btnStartGrab.Location = new Point(91, 3);
+            btnStartGrab.Name = "btnStartGrab";
+            btnStartGrab.Size = new Size(82, 28);
+            btnStartGrab.TabIndex = 5;
+            btnStartGrab.Text = "杩炵画閲囬泦";
+            btnStartGrab.UseVisualStyleBackColor = true;
+            btnStartGrab.Click += btnStartGrab_Click;
             // 
-            // btn_CloseGrab
+            // btnCloseGrab
             // 
-            btn_CloseGrab.Dock = DockStyle.Fill;
-            btn_CloseGrab.ForeColor = SystemColors.Desktop;
-            btn_CloseGrab.Location = new Point(179, 3);
-            btn_CloseGrab.Name = "btn_CloseGrab";
-            btn_CloseGrab.Size = new Size(82, 28);
-            btn_CloseGrab.TabIndex = 6;
-            btn_CloseGrab.Text = "鍏抽棴閲囬泦";
-            btn_CloseGrab.UseVisualStyleBackColor = true;
-            btn_CloseGrab.Click += btn_CloseGrab_Click;
+            btnCloseGrab.Dock = DockStyle.Fill;
+            btnCloseGrab.ForeColor = SystemColors.Desktop;
+            btnCloseGrab.Location = new Point(179, 3);
+            btnCloseGrab.Name = "btnCloseGrab";
+            btnCloseGrab.Size = new Size(82, 28);
+            btnCloseGrab.TabIndex = 6;
+            btnCloseGrab.Text = "鍏抽棴閲囬泦";
+            btnCloseGrab.UseVisualStyleBackColor = true;
+            btnCloseGrab.Click += btnCloseGrab_Click;
             // 
-            // btn_GrabOnce
+            // btnGrabOnce
             // 
-            btn_GrabOnce.Dock = DockStyle.Fill;
-            btn_GrabOnce.ForeColor = SystemColors.ControlText;
-            btn_GrabOnce.Location = new Point(3, 3);
-            btn_GrabOnce.Name = "btn_GrabOnce";
-            btn_GrabOnce.Size = new Size(82, 28);
-            btn_GrabOnce.TabIndex = 7;
-            btn_GrabOnce.Text = "鍗曞紶閲囬泦";
-            btn_GrabOnce.UseVisualStyleBackColor = true;
-            btn_GrabOnce.Click += btn_GrabOnce_Click;
+            btnGrabOnce.Dock = DockStyle.Fill;
+            btnGrabOnce.ForeColor = SystemColors.ControlText;
+            btnGrabOnce.Location = new Point(3, 3);
+            btnGrabOnce.Name = "btnGrabOnce";
+            btnGrabOnce.Size = new Size(82, 28);
+            btnGrabOnce.TabIndex = 7;
+            btnGrabOnce.Text = "鍗曞紶閲囬泦";
+            btnGrabOnce.UseVisualStyleBackColor = true;
+            btnGrabOnce.Click += btnGrabOnce_Click;
             // 
-            // btn_Open
+            // btnOpen
             // 
-            btn_Open.Dock = DockStyle.Fill;
-            btn_Open.ForeColor = SystemColors.ControlText;
-            btn_Open.Location = new Point(3, 3);
-            btn_Open.Name = "btn_Open";
-            btn_Open.Size = new Size(82, 28);
-            btn_Open.TabIndex = 8;
-            btn_Open.Text = "鎵撳紑";
-            btn_Open.UseVisualStyleBackColor = true;
-            btn_Open.Click += btn_Open_Click;
+            btnOpen.Dock = DockStyle.Fill;
+            btnOpen.ForeColor = SystemColors.ControlText;
+            btnOpen.Location = new Point(3, 3);
+            btnOpen.Name = "btnOpen";
+            btnOpen.Size = new Size(82, 28);
+            btnOpen.TabIndex = 8;
+            btnOpen.Text = "鎵撳紑";
+            btnOpen.UseVisualStyleBackColor = true;
+            btnOpen.Click += btnOpen_Click;
             // 
-            // btn_Close
+            // btnClose
             // 
-            btn_Close.Dock = DockStyle.Fill;
-            btn_Close.ForeColor = SystemColors.ControlText;
-            btn_Close.Location = new Point(91, 3);
-            btn_Close.Name = "btn_Close";
-            btn_Close.Size = new Size(82, 28);
-            btn_Close.TabIndex = 9;
-            btn_Close.Text = "鍏抽棴";
-            btn_Close.UseVisualStyleBackColor = true;
-            btn_Close.Click += btn_Close_Click;
+            btnClose.Dock = DockStyle.Fill;
+            btnClose.ForeColor = SystemColors.ControlText;
+            btnClose.Location = new Point(91, 3);
+            btnClose.Name = "btnClose";
+            btnClose.Size = new Size(82, 28);
+            btnClose.TabIndex = 9;
+            btnClose.Text = "鍏抽棴";
+            btnClose.UseVisualStyleBackColor = true;
+            btnClose.Click += btnClose_Click;
             // 
             // label5
             // 
@@ -219,7 +219,7 @@
             lblPicCount.Dock = DockStyle.Fill;
             lblPicCount.Location = new Point(123, 0);
             lblPicCount.Name = "lblPicCount";
-            lblPicCount.Size = new Size(227, 34);
+            lblPicCount.Size = new Size(226, 34);
             lblPicCount.TabIndex = 16;
             lblPicCount.Text = "0";
             lblPicCount.TextAlign = ContentAlignment.MiddleLeft;
@@ -229,18 +229,18 @@
             txtGain.Dock = DockStyle.Fill;
             txtGain.Location = new Point(53, 3);
             txtGain.Name = "txtGain";
-            txtGain.Size = new Size(297, 23);
+            txtGain.Size = new Size(296, 23);
             txtGain.TabIndex = 21;
-            txtGain.TextChanged += txt_Gain_TextChanged;
+            txtGain.TextChanged += txtGain_TextChanged;
             // 
             // txtExp
             // 
             txtExp.Dock = DockStyle.Fill;
             txtExp.Location = new Point(53, 3);
             txtExp.Name = "txtExp";
-            txtExp.Size = new Size(297, 23);
+            txtExp.Size = new Size(296, 23);
             txtExp.TabIndex = 20;
-            txtExp.TextChanged += txt_Exp_TextChanged;
+            txtExp.TextChanged += txtExp_TextChanged;
             // 
             // label4
             // 
@@ -272,7 +272,7 @@
             groupBox1.ForeColor = SystemColors.Control;
             groupBox1.Location = new Point(0, 0);
             groupBox1.Name = "groupBox1";
-            groupBox1.Size = new Size(486, 591);
+            groupBox1.Size = new Size(487, 591);
             groupBox1.TabIndex = 17;
             groupBox1.TabStop = false;
             groupBox1.Text = "瀹炴椂閲囬泦";
@@ -282,7 +282,7 @@
             panel_Picture.Dock = DockStyle.Fill;
             panel_Picture.Location = new Point(3, 19);
             panel_Picture.Name = "panel_Picture";
-            panel_Picture.Size = new Size(480, 569);
+            panel_Picture.Size = new Size(481, 569);
             panel_Picture.TabIndex = 0;
             // 
             // radioButtonSoft
@@ -291,7 +291,7 @@
             radioButtonSoft.Dock = DockStyle.Fill;
             radioButtonSoft.Location = new Point(3, 123);
             radioButtonSoft.Name = "radioButtonSoft";
-            radioButtonSoft.Size = new Size(353, 34);
+            radioButtonSoft.Size = new Size(352, 34);
             radioButtonSoft.TabIndex = 23;
             radioButtonSoft.TabStop = true;
             radioButtonSoft.Text = "杞Е鍙�";
@@ -304,7 +304,7 @@
             radioButtonHard.Dock = DockStyle.Fill;
             radioButtonHard.Location = new Point(3, 203);
             radioButtonHard.Name = "radioButtonHard";
-            radioButtonHard.Size = new Size(353, 34);
+            radioButtonHard.Size = new Size(352, 34);
             radioButtonHard.TabIndex = 24;
             radioButtonHard.TabStop = true;
             radioButtonHard.Text = "纭Е鍙�";
@@ -324,7 +324,7 @@
             // 
             splitContainer1.Panel2.Controls.Add(groupBox1);
             splitContainer1.Size = new Size(855, 591);
-            splitContainer1.SplitterDistance = 365;
+            splitContainer1.SplitterDistance = 364;
             splitContainer1.TabIndex = 19;
             // 
             // groupBox2
@@ -336,7 +336,7 @@
             groupBox2.Location = new Point(0, 0);
             groupBox2.MinimumSize = new Size(261, 61);
             groupBox2.Name = "groupBox2";
-            groupBox2.Size = new Size(365, 591);
+            groupBox2.Size = new Size(364, 591);
             groupBox2.TabIndex = 0;
             groupBox2.TabStop = false;
             groupBox2.Text = "鐩告満鍙傛暟";
@@ -378,7 +378,7 @@
             tableLayoutPanel2.RowStyles.Add(new RowStyle(SizeType.Percent, 7.143011F));
             tableLayoutPanel2.RowStyles.Add(new RowStyle(SizeType.Percent, 7.14086771F));
             tableLayoutPanel2.RowStyles.Add(new RowStyle(SizeType.Absolute, 20F));
-            tableLayoutPanel2.Size = new Size(359, 569);
+            tableLayoutPanel2.Size = new Size(358, 569);
             tableLayoutPanel2.TabIndex = 25;
             // 
             // tableLayoutPanel3
@@ -387,13 +387,13 @@
             tableLayoutPanel3.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 50F));
             tableLayoutPanel3.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
             tableLayoutPanel3.Controls.Add(label1, 0, 0);
-            tableLayoutPanel3.Controls.Add(cmb_Brand, 1, 0);
+            tableLayoutPanel3.Controls.Add(cmbBrand, 1, 0);
             tableLayoutPanel3.Dock = DockStyle.Fill;
             tableLayoutPanel3.Location = new Point(3, 3);
             tableLayoutPanel3.Name = "tableLayoutPanel3";
             tableLayoutPanel3.RowCount = 1;
             tableLayoutPanel3.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
-            tableLayoutPanel3.Size = new Size(353, 34);
+            tableLayoutPanel3.Size = new Size(352, 34);
             tableLayoutPanel3.TabIndex = 0;
             // 
             // tableLayoutPanel4
@@ -402,13 +402,13 @@
             tableLayoutPanel4.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 50F));
             tableLayoutPanel4.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
             tableLayoutPanel4.Controls.Add(label2, 0, 0);
-            tableLayoutPanel4.Controls.Add(cmb_SN, 1, 0);
+            tableLayoutPanel4.Controls.Add(cmbSN, 1, 0);
             tableLayoutPanel4.Dock = DockStyle.Fill;
             tableLayoutPanel4.Location = new Point(3, 43);
             tableLayoutPanel4.Name = "tableLayoutPanel4";
             tableLayoutPanel4.RowCount = 1;
             tableLayoutPanel4.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
-            tableLayoutPanel4.Size = new Size(353, 34);
+            tableLayoutPanel4.Size = new Size(352, 34);
             tableLayoutPanel4.TabIndex = 1;
             // 
             // tableLayoutPanel5
@@ -418,29 +418,29 @@
             tableLayoutPanel5.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 25F));
             tableLayoutPanel5.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 25F));
             tableLayoutPanel5.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 25F));
-            tableLayoutPanel5.Controls.Add(btn_Open, 0, 0);
-            tableLayoutPanel5.Controls.Add(btn_Close, 1, 0);
-            tableLayoutPanel5.Controls.Add(btn_Edit, 3, 0);
+            tableLayoutPanel5.Controls.Add(btnOpen, 0, 0);
+            tableLayoutPanel5.Controls.Add(btnClose, 1, 0);
+            tableLayoutPanel5.Controls.Add(btnEdit, 3, 0);
             tableLayoutPanel5.Dock = DockStyle.Fill;
             tableLayoutPanel5.Location = new Point(3, 83);
             tableLayoutPanel5.Name = "tableLayoutPanel5";
             tableLayoutPanel5.RowCount = 1;
             tableLayoutPanel5.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
-            tableLayoutPanel5.Size = new Size(353, 34);
+            tableLayoutPanel5.Size = new Size(352, 34);
             tableLayoutPanel5.TabIndex = 2;
             // 
-            // btn_Edit
+            // btnEdit
             // 
-            btn_Edit.Dock = DockStyle.Fill;
-            btn_Edit.Enabled = false;
-            btn_Edit.ForeColor = SystemColors.ControlText;
-            btn_Edit.Location = new Point(267, 3);
-            btn_Edit.Name = "btn_Edit";
-            btn_Edit.Size = new Size(83, 28);
-            btn_Edit.TabIndex = 10;
-            btn_Edit.Text = "缂栬緫";
-            btn_Edit.UseVisualStyleBackColor = true;
-            btn_Edit.Click += btn_Edit_Click;
+            btnEdit.Dock = DockStyle.Fill;
+            btnEdit.Enabled = false;
+            btnEdit.ForeColor = SystemColors.ControlText;
+            btnEdit.Location = new Point(267, 3);
+            btnEdit.Name = "btnEdit";
+            btnEdit.Size = new Size(82, 28);
+            btnEdit.TabIndex = 10;
+            btnEdit.Text = "缂栬緫";
+            btnEdit.UseVisualStyleBackColor = true;
+            btnEdit.Click += btnEdit_Click;
             // 
             // tableLayoutPanel6
             // 
@@ -449,30 +449,30 @@
             tableLayoutPanel6.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 25.0006275F));
             tableLayoutPanel6.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 25.0006237F));
             tableLayoutPanel6.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 24.9981289F));
-            tableLayoutPanel6.Controls.Add(btn_GrabOnce, 0, 0);
-            tableLayoutPanel6.Controls.Add(btn_StartGrab, 1, 0);
-            tableLayoutPanel6.Controls.Add(btn_CloseGrab, 2, 0);
-            tableLayoutPanel6.Controls.Add(btn_SaveImage, 3, 0);
+            tableLayoutPanel6.Controls.Add(btnGrabOnce, 0, 0);
+            tableLayoutPanel6.Controls.Add(btnStartGrab, 1, 0);
+            tableLayoutPanel6.Controls.Add(btnCloseGrab, 2, 0);
+            tableLayoutPanel6.Controls.Add(btnSaveImage, 3, 0);
             tableLayoutPanel6.Dock = DockStyle.Fill;
             tableLayoutPanel6.Location = new Point(3, 163);
             tableLayoutPanel6.Name = "tableLayoutPanel6";
             tableLayoutPanel6.RowCount = 1;
             tableLayoutPanel6.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
-            tableLayoutPanel6.Size = new Size(353, 34);
+            tableLayoutPanel6.Size = new Size(352, 34);
             tableLayoutPanel6.TabIndex = 24;
             // 
-            // btn_SaveImage
+            // btnSaveImage
             // 
-            btn_SaveImage.Dock = DockStyle.Fill;
-            btn_SaveImage.ForeColor = SystemColors.Desktop;
-            btn_SaveImage.Location = new Point(266, 2);
-            btn_SaveImage.Margin = new Padding(2);
-            btn_SaveImage.Name = "btn_SaveImage";
-            btn_SaveImage.Size = new Size(85, 30);
-            btn_SaveImage.TabIndex = 8;
-            btn_SaveImage.Text = "淇濆瓨鍥剧墖";
-            btn_SaveImage.UseVisualStyleBackColor = true;
-            btn_SaveImage.Click += btn_SaveImage_Click;
+            btnSaveImage.Dock = DockStyle.Fill;
+            btnSaveImage.ForeColor = SystemColors.Desktop;
+            btnSaveImage.Location = new Point(266, 2);
+            btnSaveImage.Margin = new Padding(2, 2, 2, 2);
+            btnSaveImage.Name = "btnSaveImage";
+            btnSaveImage.Size = new Size(84, 30);
+            btnSaveImage.TabIndex = 8;
+            btnSaveImage.Text = "淇濆瓨鍥剧墖";
+            btnSaveImage.UseVisualStyleBackColor = true;
+            btnSaveImage.Click += btnSaveImage_Click;
             // 
             // tableLayoutPanel7
             // 
@@ -486,7 +486,7 @@
             tableLayoutPanel7.Name = "tableLayoutPanel7";
             tableLayoutPanel7.RowCount = 1;
             tableLayoutPanel7.RowStyles.Add(new RowStyle(SizeType.Percent, 50F));
-            tableLayoutPanel7.Size = new Size(353, 34);
+            tableLayoutPanel7.Size = new Size(352, 34);
             tableLayoutPanel7.TabIndex = 25;
             // 
             // tableLayoutPanel8
@@ -501,7 +501,7 @@
             tableLayoutPanel8.Name = "tableLayoutPanel8";
             tableLayoutPanel8.RowCount = 1;
             tableLayoutPanel8.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
-            tableLayoutPanel8.Size = new Size(353, 34);
+            tableLayoutPanel8.Size = new Size(352, 34);
             tableLayoutPanel8.TabIndex = 26;
             // 
             // tableLayoutPanel1
@@ -518,20 +518,19 @@
             tableLayoutPanel1.Name = "tableLayoutPanel1";
             tableLayoutPanel1.RowCount = 1;
             tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
-            tableLayoutPanel1.Size = new Size(353, 34);
+            tableLayoutPanel1.Size = new Size(352, 34);
             tableLayoutPanel1.TabIndex = 29;
             // 
             // btnStartHard
             // 
             btnStartHard.Dock = DockStyle.Fill;
-            btnStartHard.ForeColor = SystemColors.InfoText;
             btnStartHard.Location = new Point(3, 3);
             btnStartHard.Name = "btnStartHard";
             btnStartHard.Size = new Size(64, 28);
             btnStartHard.TabIndex = 22;
             btnStartHard.Text = "绛夊緟瑙﹀彂";
             btnStartHard.UseVisualStyleBackColor = true;
-            btnStartHard.Click += btn_StartHard_Click;
+            btnStartHard.Click += btnStartHard_Click;
             // 
             // ckbUpParams
             // 
@@ -539,7 +538,7 @@
             ckbUpParams.Dock = DockStyle.Fill;
             ckbUpParams.Location = new Point(73, 3);
             ckbUpParams.Name = "ckbUpParams";
-            ckbUpParams.Size = new Size(135, 28);
+            ckbUpParams.Size = new Size(134, 28);
             ckbUpParams.TabIndex = 23;
             ckbUpParams.Text = "鏄惁姣忔鍐欏叆鍙傛暟";
             ckbUpParams.UseVisualStyleBackColor = true;
@@ -548,7 +547,7 @@
             // 
             ckbRegrab.AutoSize = true;
             ckbRegrab.Dock = DockStyle.Fill;
-            ckbRegrab.Location = new Point(214, 3);
+            ckbRegrab.Location = new Point(213, 3);
             ckbRegrab.Name = "ckbRegrab";
             ckbRegrab.Size = new Size(136, 28);
             ckbRegrab.TabIndex = 24;
@@ -567,7 +566,7 @@
             tableLayoutPanel12.Name = "tableLayoutPanel12";
             tableLayoutPanel12.RowCount = 1;
             tableLayoutPanel12.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
-            tableLayoutPanel12.Size = new Size(353, 43);
+            tableLayoutPanel12.Size = new Size(352, 43);
             tableLayoutPanel12.TabIndex = 31;
             // 
             // lblCapTime
@@ -576,7 +575,7 @@
             lblCapTime.Dock = DockStyle.Fill;
             lblCapTime.Location = new Point(123, 0);
             lblCapTime.Name = "lblCapTime";
-            lblCapTime.Size = new Size(227, 43);
+            lblCapTime.Size = new Size(226, 43);
             lblCapTime.TabIndex = 16;
             lblCapTime.Text = "0ms";
             lblCapTime.TextAlign = ContentAlignment.MiddleLeft;
@@ -604,7 +603,7 @@
             tableLayoutPanel11.Name = "tableLayoutPanel11";
             tableLayoutPanel11.RowCount = 1;
             tableLayoutPanel11.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
-            tableLayoutPanel11.Size = new Size(353, 34);
+            tableLayoutPanel11.Size = new Size(352, 34);
             tableLayoutPanel11.TabIndex = 30;
             // 
             // cmbImagesPath
@@ -615,7 +614,7 @@
             cmbImagesPath.FormattingEnabled = true;
             cmbImagesPath.Location = new Point(3, 443);
             cmbImagesPath.Name = "cmbImagesPath";
-            cmbImagesPath.Size = new Size(353, 25);
+            cmbImagesPath.Size = new Size(352, 25);
             cmbImagesPath.TabIndex = 0;
             cmbImagesPath.SelectedIndexChanged += cmbImagesPath_SelectedIndexChanged;
             cmbImagesPath.MouseHover += cmbImagesPath_MouseHover;
@@ -627,14 +626,14 @@
             tableLayoutPanel9.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 33.3333321F));
             tableLayoutPanel9.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 33.3333321F));
             tableLayoutPanel9.Controls.Add(ckbLocalTest, 0, 0);
-            tableLayoutPanel9.Controls.Add(btn_AddImages, 1, 0);
-            tableLayoutPanel9.Controls.Add(btn_LocalGrab, 2, 0);
+            tableLayoutPanel9.Controls.Add(btnAddImages, 1, 0);
+            tableLayoutPanel9.Controls.Add(btnLocalGrab, 2, 0);
             tableLayoutPanel9.Dock = DockStyle.Fill;
             tableLayoutPanel9.Location = new Point(3, 403);
             tableLayoutPanel9.Name = "tableLayoutPanel9";
             tableLayoutPanel9.RowCount = 1;
             tableLayoutPanel9.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
-            tableLayoutPanel9.Size = new Size(353, 34);
+            tableLayoutPanel9.Size = new Size(352, 34);
             tableLayoutPanel9.TabIndex = 27;
             // 
             // ckbLocalTest
@@ -648,29 +647,29 @@
             ckbLocalTest.Text = "鏈湴鍙栧浘";
             ckbLocalTest.UseVisualStyleBackColor = true;
             // 
-            // btn_AddImages
+            // btnAddImages
             // 
-            btn_AddImages.Dock = DockStyle.Fill;
-            btn_AddImages.ForeColor = SystemColors.Desktop;
-            btn_AddImages.Location = new Point(120, 3);
-            btn_AddImages.Name = "btn_AddImages";
-            btn_AddImages.Size = new Size(111, 28);
-            btn_AddImages.TabIndex = 1;
-            btn_AddImages.Text = "娣诲姞鍥剧墖";
-            btn_AddImages.UseVisualStyleBackColor = true;
-            btn_AddImages.Click += btn_AddImages_Click;
+            btnAddImages.Dock = DockStyle.Fill;
+            btnAddImages.ForeColor = SystemColors.Desktop;
+            btnAddImages.Location = new Point(120, 3);
+            btnAddImages.Name = "btnAddImages";
+            btnAddImages.Size = new Size(111, 28);
+            btnAddImages.TabIndex = 1;
+            btnAddImages.Text = "娣诲姞鍥剧墖";
+            btnAddImages.UseVisualStyleBackColor = true;
+            btnAddImages.Click += btnAddImages_Click;
             // 
-            // btn_LocalGrab
+            // btnLocalGrab
             // 
-            btn_LocalGrab.Dock = DockStyle.Fill;
-            btn_LocalGrab.ForeColor = SystemColors.Desktop;
-            btn_LocalGrab.Location = new Point(237, 3);
-            btn_LocalGrab.Name = "btn_LocalGrab";
-            btn_LocalGrab.Size = new Size(113, 28);
-            btn_LocalGrab.TabIndex = 2;
-            btn_LocalGrab.Text = "鏈湴鍙栧浘";
-            btn_LocalGrab.UseVisualStyleBackColor = true;
-            btn_LocalGrab.Click += btn_LocalGrab_Click;
+            btnLocalGrab.Dock = DockStyle.Fill;
+            btnLocalGrab.ForeColor = SystemColors.Desktop;
+            btnLocalGrab.Location = new Point(237, 3);
+            btnLocalGrab.Name = "btnLocalGrab";
+            btnLocalGrab.Size = new Size(112, 28);
+            btnLocalGrab.TabIndex = 2;
+            btnLocalGrab.Text = "鏈湴鍙栧浘";
+            btnLocalGrab.UseVisualStyleBackColor = true;
+            btnLocalGrab.Click += btnLocalGrab_Click;
             // 
             // tableLayoutPanel10
             // 
@@ -684,7 +683,7 @@
             tableLayoutPanel10.Name = "tableLayoutPanel10";
             tableLayoutPanel10.RowCount = 1;
             tableLayoutPanel10.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
-            tableLayoutPanel10.Size = new Size(353, 34);
+            tableLayoutPanel10.Size = new Size(352, 34);
             tableLayoutPanel10.TabIndex = 32;
             // 
             // label6
@@ -703,7 +702,7 @@
             txtTimeout.Dock = DockStyle.Fill;
             txtTimeout.Location = new Point(53, 3);
             txtTimeout.Name = "txtTimeout";
-            txtTimeout.Size = new Size(297, 23);
+            txtTimeout.Size = new Size(296, 23);
             txtTimeout.TabIndex = 1;
             // 
             // theme_2DCameraForm
@@ -725,6 +724,7 @@
             theme_2DCameraForm.StartPosition = FormStartPosition.WindowsDefaultLocation;
             theme_2DCameraForm.TabIndex = 20;
             theme_2DCameraForm.Text = "2D鐩告満璁剧疆鐣岄潰";
+            theme_2DCameraForm.Click += theme_2DCameraForm_Click;
             // 
             // controlBox1
             // 
@@ -736,7 +736,7 @@
             controlBox1.EnableMaximizeButton = false;
             controlBox1.EnableMinimizeButton = false;
             controlBox1.ForeColor = Color.FromArgb(155, 155, 155);
-            controlBox1.Location = new Point(785, 18);
+            controlBox1.Location = new Point(807, 15);
             controlBox1.MaximizeHoverColor = Color.FromArgb(74, 74, 74);
             controlBox1.MinimizeHoverColor = Color.FromArgb(63, 63, 65);
             controlBox1.Name = "controlBox1";
@@ -752,7 +752,7 @@
             panel_2DCameraForm.EdgeColor = Color.FromArgb(32, 41, 50);
             panel_2DCameraForm.Location = new Point(10, 70);
             panel_2DCameraForm.Name = "panel_2DCameraForm";
-            panel_2DCameraForm.Padding = new Padding(5);
+            panel_2DCameraForm.Padding = new Padding(5, 5, 5, 5);
             panel_2DCameraForm.Size = new Size(865, 601);
             panel_2DCameraForm.SmoothingType = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
             panel_2DCameraForm.TabIndex = 20;
@@ -807,15 +807,15 @@
 
         #endregion
 
-        private ComboBox cmb_Brand;
-        private ComboBox cmb_SN;
+        private ComboBox cmbBrand;
+        private ComboBox cmbSN;
         private Label label1;
         private Label label2;
-        private Button btn_StartGrab;
-        private Button btn_CloseGrab;
-        private Button btn_GrabOnce;
-        private Button btn_Open;
-        private Button btn_Close;
+        private Button btnStartGrab;
+        private Button btnCloseGrab;
+        private Button btnGrabOnce;
+        private Button btnOpen;
+        private Button btnClose;
         private TextBox txtGain;
         private TextBox txtExp;
         private Label label4;
@@ -844,11 +844,11 @@
         private TableLayoutPanel tableLayoutPanel12;
         private ComboBox cmbImagesPath;
         private CheckBox ckbLocalTest;
-        private Button btn_AddImages;
-        private Button btn_LocalGrab;
-        private Button btn_Edit;
+        private Button btnAddImages;
+        private Button btnLocalGrab;
+        private Button btnEdit;
         private CheckBox ckbUpParams;
-        private Button btn_SaveImage;
+        private Button btnSaveImage;
         private TableLayoutPanel tableLayoutPanel10;
         private Label label6;
         private TextBox txtTimeout;
diff --git a/LB_VisionProcesses/Cameras/2DCameraForm.cs b/LB_VisionProcesses/Cameras/2DCameraForm.cs
index 0d48c1f..361de9b 100644
--- a/LB_VisionProcesses/Cameras/2DCameraForm.cs
+++ b/LB_VisionProcesses/Cameras/2DCameraForm.cs
@@ -38,9 +38,9 @@
         {
             InitializeComponent();
             //浼犲叆鐩告満鍙ユ焺鍚庣鐢ㄨ繛鎺�/鏂紑鎸夐敭
-            this.btn_Open.Enabled = false;
-            this.btn_Close.Enabled = false;
-            this.cmb_Brand.Enabled = false;
+            //this.btnOpen.Enabled = false;
+            //this.btnClose.Enabled = false;
+            //this.cmbBrand.Enabled = false;
             this.panel_Picture.Controls.Clear();
 
             this.dicCameras = dicCameras;
@@ -48,7 +48,7 @@
             this.camConfig = camConfig;
 
             foreach (var CamSN in dicCameras.Keys)
-                cmb_SN.Items.Add(CamSN);
+                cmbSN.Items.Add(CamSN);
 
             Enum.TryParse(camConfig.Params.Inputs["瑙﹀彂鏂瑰紡"].ToString(), out TriggerSource TriggerSource);
 
@@ -96,17 +96,23 @@
             var brands = Enum.GetValues(typeof(CameraBrand)).Cast<CameraBrand>();
             foreach (var brand in brands)
             {
-                cmb_Brand.Items.Add(brand.ToString());
+                cmbBrand.Items.Add(brand.ToString());
             }
 
             //閫夋嫨Cam浼氳Е鍙慥alueChanged浜嬩欢锛屾病鏈夎緭鍏ョ浉鏈虹殑鎯呭喌涓嬮�夋嫨鍒�-1
             if (camConfig != null)
             {
                 string SN = camConfig.Params.Inputs["鐩告満SN"].ToString();
-                int Index = cmb_SN.FindString(SN);
+                int Index = cmbSN.FindString(SN);
 
-                cmb_SN.Text = SN;
-                cmb_SN.SelectedIndex = Index;
+                cmbSN.Text = SN;
+                cmbSN.SelectedIndex = Index;
+
+                // 濡傛灉娌℃壘鍒扮储寮曪紙鍙兘鏄柊澧炵殑锛夛紝鎵嬪姩瑙﹀彂涓�娆¢�昏緫浠ユ洿鏂癠I
+                if (Index == -1)
+                {
+                    cmbSN_SelectedIndexChanged(null, null);
+                }
 
                 ckbLocalTest.Checked = Convert.ToBoolean(camConfig.Params.Inputs["鏄惁鏈湴鍙栧浘"].ToString());
                 ckbUpParams.Checked = Convert.ToBoolean(camConfig.Params.Inputs["鏄惁姣忔鍐欏叆鍙傛暟"].ToString());
@@ -147,9 +153,9 @@
             if (dicCameras != null && dicCameras.Count > 0)
                 return;
 
-            cmb_SN.Items.Clear();
+            cmbSN.Items.Clear();
             // 灏濊瘯灏嗚緭鍏ュ瓧绗︿覆杞崲涓烘灇涓惧��
-            if (Enum.TryParse(cmb_Brand.Text, true, out CameraBrand brand))
+            if (Enum.TryParse(cmbBrand.Text, true, out CameraBrand brand))
             {
                 // 浣跨敤 switch 璇彞鏉ュ垽鏂灇涓惧��
                 switch (brand)
@@ -167,8 +173,8 @@
 
                 foreach (var item in camera.GetListEnum())
                 {
-                    if (!cmb_SN.Items.Contains(item))
-                        cmb_SN.Items.Add(item);
+                    if (!cmbSN.Items.Contains(item))
+                        cmbSN.Items.Add(item);
                 }
             }
             else
@@ -179,7 +185,7 @@
 
         private void cmbSN_SelectedIndexChanged(object sender, EventArgs e)
         {
-            btn_Edit.Enabled = false;
+            btnEdit.Enabled = false;
             //camConfig涓嶄负绌猴紙杈撳叆鏈夌浉鏈猴級锛屾洿鏀圭浉鏈洪�夋嫨闇�瑕侀噸鏂板姞杞藉埛鍥句簨浠�
             if (camConfig != null && camera != null)
             {
@@ -192,25 +198,37 @@
                 camera.Dispose();
             }
 
-            if (dicCameras != null && dicCameras.Count > 0 && dicCameras.ContainsKey(cmb_SN.Text))
-                camera = dicCameras[cmb_SN.Text];
+            if (dicCameras != null && dicCameras.Count > 0 && dicCameras.ContainsKey(cmbSN.Text))
+                camera = dicCameras[cmbSN.Text];
 
             //璇存槑鐩告満宸茬粡鍒濆鍖栨垚鍔�
-            if (camera != null && camera.isGrabbing)
+            if (camera != null)
             {
-                camera.ImageGrabbed -= GetImageBllComplete;
-                camera.ImageGrabbed += GetImageBllComplete;
+                int Index = cmbBrand.FindString(camera.Brand.ToString());
+                if (Index >= 0)
+                {
+                    cmbBrand.Text = camera.Brand.ToString();
+                    cmbBrand.SelectedIndex = Index;
+                }
 
-                int Index = cmb_Brand.FindString(camera.Brand.ToString()); ;
-                cmb_Brand.Text = camera.Brand.ToString();
-                cmb_Brand.SelectedIndex = Index;
+                if (camera.isGrabbing)
+                {
+                    camera.ImageGrabbed -= GetImageBllComplete;
+                    camera.ImageGrabbed += GetImageBllComplete;
+                    this.btnEdit.Enabled = true;
+                }
+                // 濡傛灉鐩告満瀛樺湪浜庡瓧鍏镐腑锛岃鏄庢槸宸茶繛鎺ョ殑璁惧锛屽厑璁哥紪杈�
+                else if (dicCameras != null && dicCameras.ContainsKey(camera.SN))
+                {
+                    this.btnEdit.Enabled = true;
+                }
             }
         }
 
-        private void btn_Open_Click(object sender, EventArgs e)
+        private void btnOpen_Click(object sender, EventArgs e)
         {
             // 灏濊瘯灏嗚緭鍏ュ瓧绗︿覆杞崲涓烘灇涓惧��
-            if (Enum.TryParse(cmb_Brand.Text, true, out CameraBrand brand))
+            if (Enum.TryParse(cmbBrand.Text, true, out CameraBrand brand))
             {
                 if (camera != null)
                 {
@@ -232,11 +250,12 @@
                         return;
                 }
 
-                if (cmb_SN.Items.Count > 0 && camera.InitDevice(cmb_SN.Text.ToString(), this.Handle))
+                if (cmbSN.Items.Count > 0 && camera.InitDevice(cmbSN.Text.ToString(), this.Handle))
                 {
                     camera.ImageGrabbed -= GetImageBllComplete;
                     camera.ImageGrabbed += GetImageBllComplete;
                     MessageBox.Show(camera.SN + "鎵撳紑鎴愬姛");
+                    this.btnEdit.Enabled = true;
                 }
             }
             else
@@ -266,11 +285,11 @@
             }
         }
 
-        private void btn_Close_Click(object sender, EventArgs e)
+        private void btnClose_Click(object sender, EventArgs e)
         {
             if (camera == null)
                 return;
-            this.btn_Edit.Enabled = false;
+            this.btnEdit.Enabled = false;
 
             if (camera.CloseDevice())
             {
@@ -279,10 +298,71 @@
             }
         }
 
-        private void btn_Edit_Click(object sender, EventArgs e)
+        private void btnEdit_Click(object sender, EventArgs e)
         {
             if (camera == null)
                 return;
+
+            using (Form editForm = new Form())
+            {
+                editForm.Text = "楂樼骇鍙傛暟璁剧疆 - " + camera.SN;
+                editForm.Size = new System.Drawing.Size(400, 500);
+                editForm.StartPosition = FormStartPosition.CenterParent;
+                editForm.FormBorderStyle = FormBorderStyle.SizableToolWindow;
+
+                PropertyGrid pg = new PropertyGrid();
+                pg.Dock = DockStyle.Fill;
+                pg.SelectedObject = new CameraAdvancedSettings(camera);
+
+                editForm.Controls.Add(pg);
+                editForm.ShowDialog();
+            }
+        }
+
+        /// <summary>
+        /// 鐩告満楂樼骇璁剧疆鍖呰绫�
+        /// </summary>
+        public class CameraAdvancedSettings
+        {
+            private BaseCamera _camera;
+            public CameraAdvancedSettings(BaseCamera camera)
+            {
+                _camera = camera;
+            }
+
+            [System.ComponentModel.Category("瑙﹀彂璁剧疆"), System.ComponentModel.Description("瑙﹀彂婧�")]
+            public TriggerSource TriggerSource
+            {
+                get { _camera.GetTriggerMode(out _, out TriggerSource s); return s; }
+                set { _camera.GetTriggerMode(out TriggerMode m, out _); _camera.SetTriggerMode(m, value); }
+            }
+
+            [System.ComponentModel.Category("瑙﹀彂璁剧疆"), System.ComponentModel.Description("瑙﹀彂鏋佹��")]
+            public TriggerPolarity TriggerPolarity
+            {
+                get { _camera.GetTriggerPolarity(out TriggerPolarity p); return p; }
+                set { _camera.SetTriggerPolarity(value); }
+            }
+
+            [System.ComponentModel.Category("瑙﹀彂璁剧疆"), System.ComponentModel.Description("瑙﹀彂寤舵椂(us)")]
+            public double TriggerDelay
+            {
+                get { _camera.GetTriggerDelay(out double d); return d; }
+                set { _camera.SetTriggerDelay(value); }
+            }
+
+            [System.ComponentModel.Category("瑙﹀彂璁剧疆"), System.ComponentModel.Description("瑙﹀彂婊ゆ尝(us)")]
+            public double TriggerFilter
+            {
+                get { _camera.GetTriggerFliter(out double f); return f; }
+                set { _camera.SetTriggerFliter(value); }
+            }
+
+            [System.ComponentModel.Category("鍥惧儚璁剧疆"), System.ComponentModel.Description("鑷姩鐧藉钩琛�")]
+            public void AutoBalanceWhite()
+            {
+                _camera.AutoBalanceWhite();
+            }
         }
 
         /// <summary>
@@ -324,7 +404,7 @@
         private Pen pen = new Pen(Color.Blue, 3f);
 
         private System.Drawing.Point[] stPointList = new System.Drawing.Point[4];
-        private void btn_GrabOnce_Click(object sender, EventArgs e)
+        private void btnGrabOnce_Click(object sender, EventArgs e)
         {
             DateTime StartTime = DateTime.Now;
             if (camera == null)
@@ -332,7 +412,7 @@
 
             Task.Factory.StartNew(() =>
             {
-                camera.GetCamConfig(out CameraConfig OriCamConfig);
+                //camera.GetCamConfig(out CameraConfig OriCamConfig);
 
                 camera.SetExpouseTime(Convert.ToDouble(txtExp.Text));
                 camera.SetGain(Convert.ToDouble(txtGain.Text));
@@ -348,11 +428,11 @@
                 }));
 
                 //澶嶅師鍘熼�氳鍙h缃�
-                camera.SetCamConfig(OriCamConfig);
+                //camera.SetCamConfig(OriCamConfig);
             });
         }
 
-        private void btn_StartHard_Click(object sender, EventArgs e)
+        private void btnStartHard_Click(object sender, EventArgs e)
         {
             if (camera == null)
                 return;
@@ -360,7 +440,7 @@
             total.Clear();
 
             // 灏濊瘯灏嗚緭鍏ュ瓧绗︿覆杞崲涓烘灇涓惧��
-            if (Enum.TryParse(cmb_Brand.Text, true, out CameraBrand brand))
+            if (Enum.TryParse(cmbBrand.Text, true, out CameraBrand brand))
             {
                 camera.StopGrabbing();
                 camera.StartWith_HardTriggerModel();
@@ -368,11 +448,11 @@
 
             startGrabtime = DateTime.Now;
 
-            cmb_SN.Enabled = false;
-            cmb_Brand.Enabled = false;
+            cmbSN.Enabled = false;
+            cmbBrand.Enabled = false;
         }
 
-        private void btn_StartGrab_Click(object sender, EventArgs e)
+        private void btnStartGrab_Click(object sender, EventArgs e)
         {
             if (camera == null)
                 return;
@@ -380,7 +460,7 @@
             total.Clear();
 
             // 灏濊瘯灏嗚緭鍏ュ瓧绗︿覆杞崲涓烘灇涓惧��
-            if (Enum.TryParse(cmb_Brand.Text, true, out CameraBrand brand))
+            if (Enum.TryParse(cmbBrand.Text, true, out CameraBrand brand))
             {
                 Task.Factory.StartNew(() =>
                 {
@@ -391,11 +471,11 @@
             }
 
             startGrabtime = DateTime.Now;
-            cmb_SN.Enabled = false;
-            cmb_Brand.Enabled = false;
+            cmbSN.Enabled = false;
+            cmbBrand.Enabled = false;
         }
 
-        private void btn_CloseGrab_Click(object sender, EventArgs e)
+        private void btnCloseGrab_Click(object sender, EventArgs e)
         {
             try
             {
@@ -403,7 +483,7 @@
                     return;
 
                 // 灏濊瘯灏嗚緭鍏ュ瓧绗︿覆杞崲涓烘灇涓惧��
-                if (Enum.TryParse(cmb_Brand.Text, true, out CameraBrand brand))
+                if (Enum.TryParse(cmbBrand.Text, true, out CameraBrand brand))
                 {
                     Task.Factory.StartNew(() =>
                     {
@@ -413,13 +493,13 @@
                     });
                 }
 
-                cmb_SN.Enabled = true;
-                cmb_Brand.Enabled = true;
+                cmbSN.Enabled = true;
+                cmbBrand.Enabled = true;
             }
             catch { }
         }
 
-        private void btn_LocalGrab_Click(object sender, EventArgs e)
+        private void btnLocalGrab_Click(object sender, EventArgs e)
         {
             try
             {
@@ -452,7 +532,7 @@
             catch { }
         }
 
-        private void txt_Exp_TextChanged(object sender, EventArgs e)
+        private void txtExp_TextChanged(object sender, EventArgs e)
         {
             if (camera == null)
                 return;
@@ -462,7 +542,7 @@
                 camera.SetExpouseTime(exp);
         }
 
-        private void txt_Gain_TextChanged(object sender, EventArgs e)
+        private void txtGain_TextChanged(object sender, EventArgs e)
         {
             if (camera == null)
                 return;
@@ -472,7 +552,7 @@
                 camera.SetGain(gain);
         }
 
-        private void btn_AddImages_Click(object sender, EventArgs e)
+        private void btnAddImages_Click(object sender, EventArgs e)
         {
             OpenFileDialog openFileDialog = new OpenFileDialog();
 
@@ -517,9 +597,25 @@
 
             if (res == DialogResult.Yes)  //淇濆瓨VPP
             {
-                camConfig.Params.Inputs.Add("鐩告満SN", cmb_SN.Text);
+                TriggerSource actualSource = TriggerSource.Line0;
+                TriggerPolarity polarity = TriggerPolarity.RisingEdge;
+                double delay = 0;
+                double filter = 0;
+
+                if (camera != null)
+                {
+                    camera.GetTriggerMode(out _, out actualSource);
+                    camera.GetTriggerPolarity(out polarity);
+                    camera.GetTriggerDelay(out delay);
+                    camera.GetTriggerFliter(out filter);
+                }
+
+                camConfig.Params.Inputs.Add("鐩告満SN", cmbSN.Text);
                 camConfig.Params.Inputs.Add("瑙﹀彂妯″紡", TriggerMode.On);
-                camConfig.Params.Inputs.Add("瑙﹀彂鏂瑰紡", radioButtonSoft.Checked ? TriggerSource.Software : TriggerSource.Line0);
+                camConfig.Params.Inputs.Add("瑙﹀彂鏂瑰紡", radioButtonSoft.Checked ? TriggerSource.Software : actualSource);
+                camConfig.Params.Inputs.Add("瑙﹀彂鏋佹��", polarity);
+                camConfig.Params.Inputs.Add("瑙﹀彂寤舵椂", delay);
+                camConfig.Params.Inputs.Add("瑙﹀彂娑堟姈", filter);
                 camConfig.Params.Inputs.Add("鏄惁鏈湴鍙栧浘", ckbLocalTest.Checked);
                 camConfig.Params.Inputs.Add("鏈湴鍙栧浘璺緞", cmbImagesPath.Items.Cast<string>().ToList());
                 camConfig.Params.Inputs.Add("鏄惁澶辫触閲嶆柊鍙栧浘", ckbRegrab.Checked);
@@ -548,10 +644,11 @@
                 camera.ImageGrabbed -= GetImageBllComplete;
                 camera.StopGrabbing();
 
+                camera.GetTriggerMode(out _, out TriggerSource actualSource);
                 if (radioButtonSoft.Checked)
                     camera.SetTriggerMode(TriggerMode.On, TriggerSource.Software);
                 else
-                    camera.SetTriggerMode(TriggerMode.On, TriggerSource.Line0);
+                    camera.SetTriggerMode(TriggerMode.On, actualSource);
 
                 camera.StartGrabbing();
             }
@@ -574,7 +671,7 @@
             };
         }
 
-        private void btn_SaveImage_Click(object sender, EventArgs e)
+        private void btnSaveImage_Click(object sender, EventArgs e)
         {
             if (Bitmap == null)
             {
@@ -614,17 +711,28 @@
 
         private void radioButtonSoft_CheckedChanged(object sender, EventArgs e)
         {
-            btn_GrabOnce.Enabled = radioButtonSoft.Checked;
-            btn_StartGrab.Enabled = radioButtonSoft.Checked;
-            btn_CloseGrab.Enabled = radioButtonSoft.Checked;
+            btnGrabOnce.Enabled = radioButtonSoft.Checked;
+            btnStartGrab.Enabled = radioButtonSoft.Checked;
+            btnCloseGrab.Enabled = radioButtonSoft.Checked;
             btnStartHard.Enabled = !radioButtonSoft.Checked;
 
             if (camera == null)
                 return;
+
+            camera.GetTriggerMode(out _, out TriggerSource currentSource);
+
             if (radioButtonSoft.Checked)
+            {
                 camera.SetTriggerMode(TriggerMode.On, TriggerSource.Software);
+            }
             else
-                camera.SetTriggerMode(TriggerMode.On, TriggerSource.Line0);
+            {
+                // 濡傛灉褰撳墠宸茬粡鏄‖浠惰Е鍙戞簮锛屽垯淇濇寔锛涘惁鍒欓粯璁ine0
+                if (currentSource == TriggerSource.Software)
+                    camera.SetTriggerMode(TriggerMode.On, TriggerSource.Line0);
+                else
+                    camera.SetTriggerMode(TriggerMode.On, currentSource);
+            }
         }
 
         System.Windows.Forms.ToolTip ToolTip = new System.Windows.Forms.ToolTip();
@@ -650,12 +758,17 @@
 
         private void controlBox_2DCameraForm_Click(object sender, EventArgs e)
         {
-            
+
         }
 
         private void dungeonControlBox_2DCameraForm_Click(object sender, EventArgs e)
         {
-           // this.Close();
+            // this.Close();
+        }
+
+        private void theme_2DCameraForm_Click(object sender, EventArgs e)
+        {
+
         }
     }
 }
diff --git a/LB_VisionProcesses/Forms/GlobalVarForm.Designer.cs b/LB_VisionProcesses/Forms/GlobalVarForm.Designer.cs
index 27631ef..9c8b465 100644
--- a/LB_VisionProcesses/Forms/GlobalVarForm.Designer.cs
+++ b/LB_VisionProcesses/Forms/GlobalVarForm.Designer.cs
@@ -37,7 +37,6 @@
             btn_Delete = new ReaLTaiizor.Controls.Button();
             btn_Add = new ReaLTaiizor.Controls.Button();
             theme_GlobalVarForm.SuspendLayout();
-            controlsPanel.SuspendLayout();
             tlp_GlobalVarForm.SuspendLayout();
             tlp_GlobalVarFormOperator.SuspendLayout();
             SuspendLayout();
@@ -45,8 +44,8 @@
             // theme_GlobalVarForm
             // 
             theme_GlobalVarForm.BackColor = Color.FromArgb(32, 41, 50);
+            theme_GlobalVarForm.Controls.Add(tlp_GlobalVarForm);
             theme_GlobalVarForm.Controls.Add(controlBox_GlobalVarForm);
-            theme_GlobalVarForm.Controls.Add(controlsPanel);
             theme_GlobalVarForm.Dock = DockStyle.Fill;
             theme_GlobalVarForm.Font = new Font("Microsoft Sans Serif", 9F);
             theme_GlobalVarForm.Image = (Image)resources.GetObject("theme_GlobalVarForm.Image");
@@ -71,7 +70,7 @@
             controlBox_GlobalVarForm.EnableMaximizeButton = false;
             controlBox_GlobalVarForm.EnableMinimizeButton = false;
             controlBox_GlobalVarForm.ForeColor = Color.FromArgb(155, 155, 155);
-            controlBox_GlobalVarForm.Location = new Point(700, 12);
+            controlBox_GlobalVarForm.Location = new Point(700, 18);
             controlBox_GlobalVarForm.MaximizeHoverColor = Color.FromArgb(74, 74, 74);
             controlBox_GlobalVarForm.MinimizeHoverColor = Color.FromArgb(63, 63, 65);
             controlBox_GlobalVarForm.Name = "controlBox_GlobalVarForm";
@@ -81,13 +80,12 @@
             // controlsPanel
             // 
             controlsPanel.BackColor = Color.FromArgb(39, 51, 63);
-            controlsPanel.Controls.Add(tlp_GlobalVarForm);
             controlsPanel.Dock = DockStyle.Fill;
             controlsPanel.EdgeColor = Color.FromArgb(32, 41, 50);
-            controlsPanel.Location = new Point(10, 70);
+            controlsPanel.Location = new Point(3, 3);
             controlsPanel.Name = "controlsPanel";
             controlsPanel.Padding = new Padding(5);
-            controlsPanel.Size = new Size(780, 521);
+            controlsPanel.Size = new Size(774, 455);
             controlsPanel.SmoothingType = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
             controlsPanel.TabIndex = 0;
             controlsPanel.Text = "panel1";
@@ -98,13 +96,14 @@
             tlp_GlobalVarForm.ColumnCount = 1;
             tlp_GlobalVarForm.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
             tlp_GlobalVarForm.Controls.Add(tlp_GlobalVarFormOperator, 0, 1);
+            tlp_GlobalVarForm.Controls.Add(controlsPanel, 0, 0);
             tlp_GlobalVarForm.Dock = DockStyle.Fill;
-            tlp_GlobalVarForm.Location = new Point(5, 5);
+            tlp_GlobalVarForm.Location = new Point(10, 70);
             tlp_GlobalVarForm.Name = "tlp_GlobalVarForm";
             tlp_GlobalVarForm.RowCount = 2;
             tlp_GlobalVarForm.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
             tlp_GlobalVarForm.RowStyles.Add(new RowStyle(SizeType.Absolute, 60F));
-            tlp_GlobalVarForm.Size = new Size(770, 511);
+            tlp_GlobalVarForm.Size = new Size(780, 521);
             tlp_GlobalVarForm.TabIndex = 0;
             tlp_GlobalVarForm.TagString = null;
             // 
@@ -120,11 +119,11 @@
             tlp_GlobalVarFormOperator.Controls.Add(btn_Delete, 4, 0);
             tlp_GlobalVarFormOperator.Controls.Add(btn_Add, 5, 0);
             tlp_GlobalVarFormOperator.Dock = DockStyle.Fill;
-            tlp_GlobalVarFormOperator.Location = new Point(3, 454);
+            tlp_GlobalVarFormOperator.Location = new Point(3, 464);
             tlp_GlobalVarFormOperator.Name = "tlp_GlobalVarFormOperator";
             tlp_GlobalVarFormOperator.RowCount = 1;
             tlp_GlobalVarFormOperator.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
-            tlp_GlobalVarFormOperator.Size = new Size(764, 54);
+            tlp_GlobalVarFormOperator.Size = new Size(774, 54);
             tlp_GlobalVarFormOperator.TabIndex = 0;
             tlp_GlobalVarFormOperator.TagString = null;
             // 
@@ -139,11 +138,11 @@
             btn_Delete.Image = null;
             btn_Delete.ImageAlign = ContentAlignment.MiddleLeft;
             btn_Delete.InactiveColor = Color.FromArgb(32, 34, 37);
-            btn_Delete.Location = new Point(511, 3);
+            btn_Delete.Location = new Point(516, 3);
             btn_Delete.Name = "btn_Delete";
             btn_Delete.PressedBorderColor = Color.FromArgb(165, 37, 37);
             btn_Delete.PressedColor = Color.FromArgb(165, 37, 37);
-            btn_Delete.Size = new Size(121, 48);
+            btn_Delete.Size = new Size(122, 48);
             btn_Delete.TabIndex = 0;
             btn_Delete.Text = "绉婚櫎";
             btn_Delete.TextAlignment = StringAlignment.Center;
@@ -160,11 +159,11 @@
             btn_Add.Image = null;
             btn_Add.ImageAlign = ContentAlignment.MiddleLeft;
             btn_Add.InactiveColor = Color.FromArgb(32, 34, 37);
-            btn_Add.Location = new Point(638, 3);
+            btn_Add.Location = new Point(644, 3);
             btn_Add.Name = "btn_Add";
             btn_Add.PressedBorderColor = Color.FromArgb(165, 37, 37);
             btn_Add.PressedColor = Color.FromArgb(165, 37, 37);
-            btn_Add.Size = new Size(123, 48);
+            btn_Add.Size = new Size(127, 48);
             btn_Add.TabIndex = 1;
             btn_Add.Text = "娣诲姞";
             btn_Add.TextAlignment = StringAlignment.Center;
@@ -184,7 +183,6 @@
             FormClosing += GlobalVarForm_FormClosing;
             Load += GlobalVarForm_Load;
             theme_GlobalVarForm.ResumeLayout(false);
-            controlsPanel.ResumeLayout(false);
             tlp_GlobalVarForm.ResumeLayout(false);
             tlp_GlobalVarFormOperator.ResumeLayout(false);
             ResumeLayout(false);

--
Gitblit v1.9.3