From 2a6b8de3ee1ed419bbe54213dcb8428d2c436a69 Mon Sep 17 00:00:00 2001
From: LAPTOP-SNT8I5JK\Boounion <Chenluhua@qq.com>
Date: 星期一, 13 一月 2025 08:56:24 +0800
Subject: [PATCH] 1.PLC调机程序,警告和其它完善;

---
 SourceCode/Bond/BoounionPLC/PLC.cpp                     |  198 ++++++++++++
 SourceCode/Bond/BoounionPLC/BoounionPLC.rc              |    0 
 SourceCode/Bond/BoounionPLC/Model.cpp                   |   75 ++++
 SourceCode/Bond/BoounionPLC/Common.h                    |   58 +++
 SourceCode/Bond/BoounionPLC/PLC.h                       |   21 +
 SourceCode/Bond/BoounionPLC/ToolUnits.cpp               |   47 ++
 SourceCode/Bond/BoounionPLC/PlcView.cpp                 |   24 +
 SourceCode/Bond/BoounionPLC/Resource.h                  |    0 
 SourceCode/Bond/BoounionPLC/Configuration.cpp           |  132 ++++++++
 SourceCode/Bond/BoounionPLC/Configuration.h             |   22 +
 SourceCode/Bond/BoounionPLC/stdafx.h                    |   22 +
 SourceCode/Bond/BoounionPLC/ToolUnits.h                 |    1 
 SourceCode/Bond/BoounionPLC/CPageLogcat.cpp             |   10 
 /dev/null                                               |   75 ----
 SourceCode/Bond/BoounionPLC/BoounionPLCDlg.cpp          |   98 ++++-
 SourceCode/Bond/BoounionPLC/BoounionPLCDlg.h            |    4 
 SourceCode/Bond/BoounionPLC/PlcView.h                   |    1 
 SourceCode/Bond/BoounionPLC/BoounionPLC.vcxproj.filters |   66 +++
 SourceCode/Bond/BoounionPLC/Model.h                     |    6 
 SourceCode/Bond/BoounionPLC/AlarmMonitor.cpp            |    2 
 SourceCode/Bond/BoounionPLC/CPageLogcat.h               |    1 
 SourceCode/Bond/BoounionPLC/BoounionPLC.vcxproj         |   28 +
 SourceCode/Bond/BoounionPLC/PagePlcList.cpp             |   12 
 23 files changed, 773 insertions(+), 130 deletions(-)

diff --git a/SourceCode/Bond/BoounionPLC/AlarmMonitor.cpp b/SourceCode/Bond/BoounionPLC/AlarmMonitor.cpp
index 999e0cb..66f7ed4 100644
--- a/SourceCode/Bond/BoounionPLC/AlarmMonitor.cpp
+++ b/SourceCode/Bond/BoounionPLC/AlarmMonitor.cpp
@@ -236,11 +236,13 @@
 void CAlarmMonitor::addAlarmToHistoryRecord(CAlarm* pAlarm)
 {
 	// 加入数据库
+	/*
 	AlarmManager::getInstance().addAlarm(
 		std::to_string(pAlarm->getId()).c_str(),
 		getAlarmText(pAlarm->getId()),
 		CToolUnits::timeToString2(pAlarm->getOnTime()).c_str(),
 		CToolUnits::timeToString2(pAlarm->getOffTime()).c_str());
+		*/
 }
 
 BOOL CAlarmMonitor::addAlarming(CAlarm* pAlarm)
diff --git a/SourceCode/Bond/BoounionPLC/BoounionPLC.rc b/SourceCode/Bond/BoounionPLC/BoounionPLC.rc
index e996965..f97ba4a 100644
--- a/SourceCode/Bond/BoounionPLC/BoounionPLC.rc
+++ b/SourceCode/Bond/BoounionPLC/BoounionPLC.rc
Binary files differ
diff --git a/SourceCode/Bond/BoounionPLC/BoounionPLC.vcxproj b/SourceCode/Bond/BoounionPLC/BoounionPLC.vcxproj
index 7b7068a..c4d1ecc 100644
--- a/SourceCode/Bond/BoounionPLC/BoounionPLC.vcxproj
+++ b/SourceCode/Bond/BoounionPLC/BoounionPLC.vcxproj
@@ -116,7 +116,7 @@
       <Optimization>Disabled</Optimization>
       <PreprocessorDefinitions>_WINDOWS;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <SDLCheck>true</SDLCheck>
-      <AdditionalIncludeDirectories>.;.\DBManager;..\DatabaseSDK\include</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>.;.\DBManager;.\FileManager;..\DatabaseSDK\include;..\BLControlsSDK\include;..\BLControlsSDK\GridControl</AdditionalIncludeDirectories>
     </ClCompile>
     <Link>
       <SubSystem>Windows</SubSystem>
@@ -169,7 +169,7 @@
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <PreprocessorDefinitions>_WINDOWS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <SDLCheck>true</SDLCheck>
-      <AdditionalIncludeDirectories>.;.\DBManager;..\DatabaseSDK\include</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>.;.\DBManager;.\FileManager;..\DatabaseSDK\include;..\BLControlsSDK\include;..\BLControlsSDK\GridControl</AdditionalIncludeDirectories>
     </ClCompile>
     <Link>
       <SubSystem>Windows</SubSystem>
@@ -197,9 +197,12 @@
     <ClInclude Include="AlarmMonitor.h" />
     <ClInclude Include="AlarmPopupDlg.h" />
     <ClInclude Include="ApredTreeCtrl.h" />
+    <ClInclude Include="AxisDetailSettingsDlg.h" />
+    <ClInclude Include="AxisSettingsDlg.h" />
     <ClInclude Include="BlButton.h" />
     <ClInclude Include="BoounionPLC.h" />
     <ClInclude Include="BoounionPLCDlg.h" />
+    <ClInclude Include="CBaseDlg.h" />
     <ClInclude Include="CBaseView.h" />
     <ClInclude Include="CMainContainer.h" />
     <ClInclude Include="Common.h" />
@@ -208,10 +211,15 @@
     <ClInclude Include="Context.h" />
     <ClInclude Include="CPageLogcat.h" />
     <ClInclude Include="DBManager\AlarmManager.h" />
-    <ClInclude Include="DBManager\AxisManager.h" />
     <ClInclude Include="DBManager\SystemLogManager.h" />
     <ClInclude Include="DBManager\UserManager.h" />
+    <ClInclude Include="FileManager\AxisManager.h" />
+    <ClInclude Include="FileManager\IOManager.h" />
+    <ClInclude Include="FileManager\pugiconfig.hpp" />
+    <ClInclude Include="FileManager\pugixml.hpp" />
+    <ClInclude Include="InputDialog.h" />
     <ClInclude Include="Intent.h" />
+    <ClInclude Include="IOMonitoringDlg.h" />
     <ClInclude Include="Log.h" />
     <ClInclude Include="LogEdit.h" />
     <ClInclude Include="McBool.h" />
@@ -222,6 +230,7 @@
     <ClInclude Include="PagePlcList.h" />
     <ClInclude Include="PLC.h" />
     <ClInclude Include="PlcView.h" />
+    <ClInclude Include="RegexEdit.h" />
     <ClInclude Include="Resource.h" />
     <ClInclude Include="stdafx.h" />
     <ClInclude Include="targetver.h" />
@@ -235,9 +244,12 @@
     <ClCompile Include="AlarmMonitor.cpp" />
     <ClCompile Include="AlarmPopupDlg.cpp" />
     <ClCompile Include="ApredTreeCtrl.cpp" />
+    <ClCompile Include="AxisDetailSettingsDlg.cpp" />
+    <ClCompile Include="AxisSettingsDlg.cpp" />
     <ClCompile Include="BlButton.cpp" />
     <ClCompile Include="BoounionPLC.cpp" />
     <ClCompile Include="BoounionPLCDlg.cpp" />
+    <ClCompile Include="CBaseDlg.cpp" />
     <ClCompile Include="CBaseView.cpp" />
     <ClCompile Include="CMainContainer.cpp" />
     <ClCompile Include="Component.cpp" />
@@ -247,10 +259,17 @@
     <ClCompile Include="DBManager\AlarmManager.cpp">
       <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Use</PrecompiledHeader>
     </ClCompile>
-    <ClCompile Include="DBManager\AxisManager.cpp" />
     <ClCompile Include="DBManager\SystemLogManager.cpp" />
     <ClCompile Include="DBManager\UserManager.cpp" />
+    <ClCompile Include="FileManager\AxisManager.cpp" />
+    <ClCompile Include="FileManager\IOManager.cpp" />
+    <ClCompile Include="FileManager\pugixml.cpp">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
+    </ClCompile>
+    <ClCompile Include="InputDialog.cpp" />
     <ClCompile Include="Intent.cpp" />
+    <ClCompile Include="IOMonitoringDlg.cpp" />
     <ClCompile Include="Log.cpp" />
     <ClCompile Include="LogEdit.cpp" />
     <ClCompile Include="McBool.cpp" />
@@ -261,6 +280,7 @@
     <ClCompile Include="PagePlcList.cpp" />
     <ClCompile Include="PLC.cpp" />
     <ClCompile Include="PlcView.cpp" />
+    <ClCompile Include="RegexEdit.cpp" />
     <ClCompile Include="stdafx.cpp">
       <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
       <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
diff --git a/SourceCode/Bond/BoounionPLC/BoounionPLC.vcxproj.filters b/SourceCode/Bond/BoounionPLC/BoounionPLC.vcxproj.filters
index 0a58c07..d3f05ab 100644
--- a/SourceCode/Bond/BoounionPLC/BoounionPLC.vcxproj.filters
+++ b/SourceCode/Bond/BoounionPLC/BoounionPLC.vcxproj.filters
@@ -16,6 +16,9 @@
     <Filter Include="DBManager">
       <UniqueIdentifier>{c5603403-bc3a-451f-b300-c56d9fe09307}</UniqueIdentifier>
     </Filter>
+    <Filter Include="FileManager">
+      <UniqueIdentifier>{d7763e1c-46cf-48f9-b0da-001138287bcd}</UniqueIdentifier>
+    </Filter>
   </ItemGroup>
   <ItemGroup>
     <Text Include="ReadMe.txt" />
@@ -114,9 +117,6 @@
     <ClInclude Include="DBManager\AlarmManager.h">
       <Filter>DBManager</Filter>
     </ClInclude>
-    <ClInclude Include="DBManager\AxisManager.h">
-      <Filter>DBManager</Filter>
-    </ClInclude>
     <ClInclude Include="DBManager\SystemLogManager.h">
       <Filter>DBManager</Filter>
     </ClInclude>
@@ -127,6 +127,36 @@
       <Filter>澶存枃浠�</Filter>
     </ClInclude>
     <ClInclude Include="LogEdit.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="FileManager\IOManager.h">
+      <Filter>FileManager</Filter>
+    </ClInclude>
+    <ClInclude Include="FileManager\pugiconfig.hpp">
+      <Filter>FileManager</Filter>
+    </ClInclude>
+    <ClInclude Include="FileManager\pugixml.hpp">
+      <Filter>FileManager</Filter>
+    </ClInclude>
+    <ClInclude Include="InputDialog.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="IOMonitoringDlg.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="FileManager\AxisManager.h">
+      <Filter>FileManager</Filter>
+    </ClInclude>
+    <ClInclude Include="AxisDetailSettingsDlg.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="AxisSettingsDlg.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="CBaseDlg.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="RegexEdit.h">
       <Filter>澶存枃浠�</Filter>
     </ClInclude>
   </ItemGroup>
@@ -215,9 +245,6 @@
     <ClCompile Include="DBManager\AlarmManager.cpp">
       <Filter>DBManager</Filter>
     </ClCompile>
-    <ClCompile Include="DBManager\AxisManager.cpp">
-      <Filter>DBManager</Filter>
-    </ClCompile>
     <ClCompile Include="DBManager\SystemLogManager.cpp">
       <Filter>DBManager</Filter>
     </ClCompile>
@@ -230,6 +257,33 @@
     <ClCompile Include="LogEdit.cpp">
       <Filter>婧愭枃浠�</Filter>
     </ClCompile>
+    <ClCompile Include="FileManager\IOManager.cpp">
+      <Filter>FileManager</Filter>
+    </ClCompile>
+    <ClCompile Include="FileManager\pugixml.cpp">
+      <Filter>FileManager</Filter>
+    </ClCompile>
+    <ClCompile Include="InputDialog.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+    <ClCompile Include="IOMonitoringDlg.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+    <ClCompile Include="FileManager\AxisManager.cpp">
+      <Filter>FileManager</Filter>
+    </ClCompile>
+    <ClCompile Include="AxisDetailSettingsDlg.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+    <ClCompile Include="AxisSettingsDlg.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+    <ClCompile Include="CBaseDlg.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+    <ClCompile Include="RegexEdit.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="BoounionPLC.rc">
diff --git a/SourceCode/Bond/BoounionPLC/BoounionPLCDlg.cpp b/SourceCode/Bond/BoounionPLC/BoounionPLCDlg.cpp
index d31d1c0..3da6b35 100644
--- a/SourceCode/Bond/BoounionPLC/BoounionPLCDlg.cpp
+++ b/SourceCode/Bond/BoounionPLC/BoounionPLCDlg.cpp
@@ -8,8 +8,14 @@
 #include "afxdialogex.h"
 #include "Common.h"
 #include "PlcView.h"
-#include "AlarmMonitor.h"
 #include "Log.h"
+#include "InputDialog.h"
+#include "AxisManager.h"
+#include "IOManager.h"
+
+// 测试
+#include "AxisSettingsDlg.h"
+#include "IOMonitoringDlg.h"
 
 
 #ifdef _DEBUG
@@ -113,27 +119,39 @@
 			if (RX_CODE_SELECT_PLC == code) {
 				CPLC* pPlc;
 				if (pAny->getPtrValue("ptr", (void*&)pPlc)) {
-					ASSERT(m_pMainContainer != nullptr);
-					if (m_pActiveView == nullptr) {
-						m_pActiveView = (CPlcView*)CreatePlcView(pPlc);
+					if (pPlc != nullptr) {
+						ASSERT(m_pMainContainer != nullptr);
+						if (m_pActiveView == nullptr) {
+							m_pActiveView = (CPlcView*)CreatePlcView(pPlc);
+						}
+						ASSERT(m_pActiveView);
+						if (m_pActiveView->GetContext() != (void*)pPlc) {
+							m_pActiveView->SetWindowText(pPlc->getName().c_str());
+							m_pActiveView->SetContext(pPlc);
+							m_pActiveView->SendMessage(WM_NCPAINT, 0, 0);
+						}
+					} else {
+						CloseView(m_pActiveView);
 					}
-					ASSERT(m_pActiveView);
-					if (m_pActiveView->GetContext() != (void*)pPlc) {
-						m_pActiveView->SetWindowText(pPlc->getName().c_str());
-						m_pActiveView->SetContext(pPlc);
-						m_pActiveView->SendMessage(WM_NCPAINT, 0, 0);
-					}
+
+					theApp.m_model.setCurrentPlc(pPlc);
 				}
 			}
 			else if (code == RX_CODE_ALARM_ON) {
-				AlarmOn();
-				// CAlarmMonitor* pComponent = (CAlarmMonitor*)theApp.m_model.getBonder().GetComponent(ALARM_MONITOR);
-				// m_pTopToolbar->GetBtn(IDC_BUTTON_ALARM)->EnableWindow(pComponent->isAlarming());
+				CPLC* pPlc;
+				if (pAny->getPtrValue("ptr", (void*&)pPlc) && pPlc == theApp.m_model.getCurrentPlc()) {
+					AlarmOn(pPlc);
+					CAlarmMonitor* pComponent = (CAlarmMonitor*)pPlc->getComponent(ALARM_MONITOR);
+					m_pTopToolbar->GetBtn(IDC_BUTTON_ALARM)->EnableWindow(pComponent->isAlarming());
+				}
 			}
 			else if (code == RX_CODE_ALARM_OFF) {
-				AlarmOff();
-				// CAlarmMonitor* pComponent = (CAlarmMonitor*)theApp.m_model.getBonder().GetComponent(ALARM_MONITOR);
-				// m_pTopToolbar->GetBtn(IDC_BUTTON_ALARM)->EnableWindow(pComponent->isAlarming());
+				CPLC* pPlc;
+				if (pAny->getPtrValue("ptr", (void*&)pPlc) && pPlc == theApp.m_model.getCurrentPlc()) {
+					AlarmOff(pPlc);
+					CAlarmMonitor* pComponent = (CAlarmMonitor*)pPlc->getComponent(ALARM_MONITOR);
+					m_pTopToolbar->GetBtn(IDC_BUTTON_ALARM)->EnableWindow(pComponent->isAlarming());
+				}
 			}
 			pAny->release();
 		}, [&]() -> void {
@@ -481,20 +499,42 @@
 {
 	int id = (int)lParam;
 	if (id == IDC_BUTTON_ADD) {
-		static int i = 0;
-		char szName[256];
-		sprintf_s(szName, 256, "PLC%d", ++i);
-		theApp.m_model.addPlc(szName, "192.168.1.188", 1001);
+		CInputDialog inputDialog(_T("新建设备"), _T("请输入设备名称:"));
+		if (inputDialog.DoModal() != IDOK) {
+			AfxMessageBox(_T("取消验证!"));
+			return 0;
+		}
+
+		CString strName;
+		strName = inputDialog.GetInputText();
+		if (!strName.IsEmpty()) {
+			theApp.m_model.addPlc((LPTSTR)(LPCTSTR)strName, "192.168.1.188", 1001);
+
+			// 新建轴文件
+			AxisManager axisManager;
+			axisManager.SaveAxis((LPTSTR)(LPCTSTR)strName);
+
+			// 新建IO文件
+			IOManager ioManager;
+			ioManager.SaveToFile((LPTSTR)(LPCTSTR)strName);
+		}
 	}
 	else if (id == IDC_BUTTON_DELETE) {
-		static int i = 0;
-		i += 1;
-		char szName[256];
-		sprintf_s(szName, 256, "PLC%d", i);
-		theApp.m_model.removePlc(szName);
+		CPLC* pPlc = theApp.m_model.getCurrentPlc();
+		if (pPlc != nullptr) {
+			theApp.m_model.removePlc(pPlc->getName().c_str());
+		}
 	}
 	else if (id == IDC_BUTTON_SETTINGS) {
+		// 测试 IO模块
+		CPLC* pPLC = theApp.m_model.getCurrentPlc();
+		if (pPLC != nullptr) {
+			//CIOMonitoringDlg dlg;
+			//dlg.DoModal();
 
+			CAxisSettingsDlg dlg;
+			dlg.DoModal();
+		}
 	}
 	else if (id == IDC_BUTTON_OPERATOR) {
 		/*
@@ -611,22 +651,22 @@
 	m_pMainContainer->Resize();
 }
 
-void CBoounionPLCDlg::AlarmOn()
+void CBoounionPLCDlg::AlarmOn(CPLC* pPlc)
 {
 	if (m_pAlarmWnd == nullptr) {
 		m_pAlarmWnd = new CAlarmPopupDlg();
-		//m_pAlarmWnd->SetPLC(theApp.m_model.getBonder().getPLC("PLC(1)"));
+		m_pAlarmWnd->SetPLC(pPlc);
 		m_pAlarmWnd->Create(IDD_DIALOG_POPUP_ALARM, this);
 		m_pAlarmWnd->CenterWindow();
 	}
 	m_pAlarmWnd->AlarmOn();
 }
 
-void CBoounionPLCDlg::AlarmOff()
+void CBoounionPLCDlg::AlarmOff(CPLC* pPlc)
 {
 	if (m_pAlarmWnd == nullptr) {
 		m_pAlarmWnd = new CAlarmPopupDlg();
-		//m_pAlarmWnd->SetPLC(theApp.m_model.getBonder().getPLC("PLC(1)"));
+		m_pAlarmWnd->SetPLC(pPlc);
 		m_pAlarmWnd->Create(IDD_DIALOG_POPUP_ALARM, this);
 		m_pAlarmWnd->CenterWindow();
 	}
diff --git a/SourceCode/Bond/BoounionPLC/BoounionPLCDlg.h b/SourceCode/Bond/BoounionPLC/BoounionPLCDlg.h
index b159c87..c94fd54 100644
--- a/SourceCode/Bond/BoounionPLC/BoounionPLCDlg.h
+++ b/SourceCode/Bond/BoounionPLC/BoounionPLCDlg.h
@@ -23,8 +23,8 @@
 	void Resize();
 	CBaseView* CreatePlcView(CPLC* pPlc);
 	void CloseView(CBaseView* pView);
-	void AlarmOn();
-	void AlarmOff();
+	void AlarmOn(CPLC* pPlc);
+	void AlarmOff(CPLC* pPlc);
 
 private:
 	COLORREF m_crBkgnd;
diff --git a/SourceCode/Bond/BoounionPLC/CPageLogcat.cpp b/SourceCode/Bond/BoounionPLC/CPageLogcat.cpp
index 9781053..d3b0560 100644
--- a/SourceCode/Bond/BoounionPLC/CPageLogcat.cpp
+++ b/SourceCode/Bond/BoounionPLC/CPageLogcat.cpp
@@ -302,3 +302,13 @@
 	m_bIncludeRegex = pCheckBox->GetCheck();
 	theApp.m_model.m_configuration.setLogcatIncludeRegex(m_bIncludeRegex);
 }
+
+
+BOOL CPageLogcat::PreTranslateMessage(MSG* pMsg)
+{
+	if (pMsg->wParam == VK_RETURN || pMsg->wParam == VK_ESCAPE) {
+		return TRUE;
+	}
+
+	return CDialogEx::PreTranslateMessage(pMsg);
+}
diff --git a/SourceCode/Bond/BoounionPLC/CPageLogcat.h b/SourceCode/Bond/BoounionPLC/CPageLogcat.h
index 78eae19..072aa02 100644
--- a/SourceCode/Bond/BoounionPLC/CPageLogcat.h
+++ b/SourceCode/Bond/BoounionPLC/CPageLogcat.h
@@ -53,4 +53,5 @@
 	afx_msg void OnButtonIncludeMenuClicked(NMHDR* pNMHDR, LRESULT* pResult);
 	afx_msg void OnEnChangeEditInclude();
 	afx_msg void OnBnClickedCheckRegex();
+	virtual BOOL PreTranslateMessage(MSG* pMsg);
 };
diff --git a/SourceCode/Bond/BoounionPLC/Common.h b/SourceCode/Bond/BoounionPLC/Common.h
index bbd8e73..700cfb6 100644
--- a/SourceCode/Bond/BoounionPLC/Common.h
+++ b/SourceCode/Bond/BoounionPLC/Common.h
@@ -31,10 +31,12 @@
 #define PLC_VIEW_BACKGROUND				RGB(252, 252, 255)
 #define LOGCAT_BACKGROUND_COLOR			RGB(252, 252, 255)
 
+/* PLC页面颜色定义 */
+
 /* PLCVIEW按钮 */
-#define BTN_PLCVIEW_FRAME_NORMAL	RGB(88, 88, 88)
-#define BTN_PLCVIEW_FRAME_HOVER		RGB(88, 88, 88)
-#define BTN_PLCVIEW_FRAME_PRESS		RGB(88, 88, 88)
+#define BTN_PLCVIEW_FRAME_NORMAL		RGB(88, 88, 88)
+#define BTN_PLCVIEW_FRAME_HOVER			RGB(88, 88, 88)
+#define BTN_PLCVIEW_FRAME_PRESS			RGB(88, 88, 88)
 #define BTN_PLCVIEW_OFF_BKGND_NORMAL	RGB(255, 127, 39)
 #define BTN_PLCVIEW_OFF_BKGND_HOVER		RGB(255, 157, 59)
 #define BTN_PLCVIEW_OFF_BKGND_PRESS		RGB(255, 100, 29)
@@ -42,6 +44,56 @@
 #define BTN_PLCVIEW_ON_BKGND_HOVER		RGB(150, 250, 150)
 #define BTN_PLCVIEW_ON_BKGND_PRESS		RGB(50, 150, 50)
 
+/* 轴设定页面颜色定义 */
+
+/* 5个按钮页, 按钮背景色,正常状态*/
+#define BTN_PAGE_FACE_NORMAL_COLOR		RGB(0, 168, 0)
+#define BTN_PAGE_FACE_SELECT_COLOR		RGB(0, 232, 0)
+#define BTN_PAGE_TEXT_NORMAL_COLOR		RGB(22, 22, 22)
+#define BTN_PAGE_TEXT_SELECT_COLOR		RGB(22, 22, 22)
+
+/* JOG+, JOG-*/
+#define BTN_JOG_FRAME_NORMAL			RGB(88, 88, 88)
+#define BTN_JOG_FRAME_HOVER				RGB(88, 88, 88)
+#define BTN_JOG_FRAME_PRESS				RGB(88, 88, 88)
+#define BTN_JOG_BKGND_NORMAL			RGB(0, 232, 0)
+#define BTN_JOG_BKGND_HOVER				RGB(0, 222, 0)
+#define BTN_JOG_BKGND_PRESS				RGB(0, 168, 0)
+
+/* Sev按钮 */
+#define BTN_SEV_FRAME_NORMAL			RGB(88, 88, 88)
+#define BTN_SEV_FRAME_HOVER				RGB(88, 88, 88)
+#define BTN_SEV_FRAME_PRESS				RGB(88, 88, 88)
+#define BTN_SEV_BKGND_NORMAL			RGB(0, 232, 0)
+#define BTN_SEV_BKGND_HOVER				RGB(0, 222, 0)
+#define BTN_SEV_BKGND_PRESS				RGB(222, 0, 0)
+
+/* Stop按钮 */
+#define BTN_STOP_FRAME_NORMAL			RGB(88, 88, 88)
+#define BTN_STOP_FRAME_HOVER			RGB(88, 88, 88)
+#define BTN_STOP_FRAME_PRESS			RGB(88, 88, 88)
+#define BTN_STOP_BKGND_NORMAL			RGB(0, 168, 0)
+#define BTN_STOP_BKGND_HOVER			RGB(0, 138, 0)
+#define BTN_STOP_BKGND_PRESS			RGB(222, 0, 0)
+
+/* OPR 按钮 */
+#define BTN_OPR_FRAME_NORMAL			RGB(88, 88, 88)
+#define BTN_OPR_FRAME_HOVER				RGB(88, 88, 88)
+#define BTN_OPR_FRAME_PRESS				RGB(88, 88, 88)
+#define BTN_OPR_BKGND_NORMAL			RGB(222, 222, 222)
+#define BTN_OPR_BKGND_HOVER				RGB(208, 208, 222)
+#define BTN_OPR_BKGND_PRESS				RGB(0, 232, 0)
+
+/* 定位按钮 */
+#define BTN_POINT_FRAME_NORMAL			RGB(88, 88, 88)
+#define BTN_POINT_FRAME_HOVER			RGB(88, 88, 88)
+#define BTN_POINT_FRAME_PRESS			RGB(88, 88, 88)
+#define BTN_POINT_BKGND_NORMAL			RGB(222, 222, 222)
+#define BTN_POINT_BKGND_HOVER			RGB(208, 208, 222)
+#define BTN_POINT_BKGND_PRESS			RGB(0, 232, 0)
+
+/* 报警页面颜色定义 */
+
 /* 解除警告 按钮 */
 #define BTN_ALARM_OFF_FRAME_NORMAL		RGB(88, 88, 88)
 #define BTN_ALARM_OFF_FRAME_HOVER		RGB(88, 88, 88)
diff --git a/SourceCode/Bond/BoounionPLC/Configuration.cpp b/SourceCode/Bond/BoounionPLC/Configuration.cpp
index b8529b6..467daef 100644
--- a/SourceCode/Bond/BoounionPLC/Configuration.cpp
+++ b/SourceCode/Bond/BoounionPLC/Configuration.cpp
@@ -9,6 +9,7 @@
 CConfiguration::CConfiguration(const char* pszFilepath)
 {
 	m_strFilepath = pszFilepath;
+    loadPLCListFromFile();
 }
 
 CConfiguration::~CConfiguration()
@@ -18,6 +19,7 @@
 void CConfiguration::setFilepath(const char* pszFilepath)
 {
 	m_strFilepath = pszFilepath;
+    loadPLCListFromFile();
 }
 
 void CConfiguration::getUnitId(CString& strUnitId)
@@ -103,3 +105,133 @@
 		std::to_string(second).c_str(), m_strFilepath);
 }
 
+// ================================== PLC 配置操作 ==================================
+// 添加 PLC
+bool CConfiguration::addPLC(const CString& strName, const CString& strIp, UINT nPort)
+{
+    // 检查是否重复
+    auto it = std::find_if(m_plcList.begin(), m_plcList.end(),
+        [&strName](const PlcInfo& plc) { return plc.strName == strName; });
+
+    if (it != m_plcList.end()) {
+        return false;
+    }
+
+    // 添加 PLC
+    PlcInfo plc;
+    plc.strName = strName;
+    plc.strIp = strIp;
+    plc.nPort = nPort;
+
+    m_plcList.push_back(plc);
+    savePLCListToFile();
+    return true;
+}
+
+// 删除 PLC
+bool CConfiguration::removePLC(const CString& strName)
+{
+    auto it = std::find_if(m_plcList.begin(), m_plcList.end(),
+        [&strName](const PlcInfo& plc) { return plc.strName == strName; });
+
+    if (it != m_plcList.end()) {
+        m_plcList.erase(it);
+        savePLCListToFile();
+        return true;
+    }
+    return false;
+}
+
+// 更新 PLC
+bool CConfiguration::updatePLC(const CString& strOldName, const CString& strNewName, const CString& strNewIp, UINT nNewPort)
+{
+    auto it = std::find_if(m_plcList.begin(), m_plcList.end(),
+        [&strOldName](const PlcInfo& plc) { return plc.strName == strOldName; });
+
+    if (it != m_plcList.end()) {
+        it->strName = strNewName;
+        it->strIp = strNewIp;
+        it->nPort = nNewPort;
+        savePLCListToFile();
+        return true;
+    }
+    return false;
+}
+
+// 根据名称获取 PLC 信息
+bool CConfiguration::getPLCByName(const CString& strName, CString& strIp, UINT& nPort)
+{
+    auto it = std::find_if(m_plcList.begin(), m_plcList.end(),
+        [&strName](const PlcInfo& plc) { return plc.strName == strName; });
+
+    if (it != m_plcList.end()) {
+        strIp = it->strIp;
+        nPort = it->nPort;
+        return true;
+    }
+    return false;
+}
+
+// 获取 PLC 列表的数量
+int CConfiguration::getPLCListCount()
+{
+    return (int)m_plcList.size();
+}
+
+// 获取所有的 PLC 信息
+void CConfiguration::getAllPLCInfo(std::vector<PlcInfo>& plcList)
+{
+    plcList.resize(m_plcList.size());
+    plcList.assign(m_plcList.begin(), m_plcList.end());
+}
+
+// 从文件加载 PLC 列表
+void CConfiguration::loadPLCListFromFile()
+{
+    m_plcList.clear();
+
+    // 读取 PLC 数量
+    int nPLCCount = GetPrivateProfileInt("PLCs", "PLCCount", 0, m_strFilepath);
+
+    char szSection[256], szTemp[256];
+    for (int i = 0; i < nPLCCount; i++) {
+        sprintf_s(szSection, 256, "PLC%d", i + 1);
+        GetPrivateProfileString("PLCs", szSection, _T(""), szTemp, 256, m_strFilepath);
+        if (szTemp[0] != '\0') {
+            CString strInfo(szTemp);
+            // 格式是 Name,IP,Port
+            int nPos1 = strInfo.Find(_T(','));
+            int nPos2 = strInfo.Find(_T(','), nPos1 + 1);
+
+            if (nPos1 != -1 && nPos2 != -1) {
+                PlcInfo plcInfo;
+                plcInfo.strName = strInfo.Left(nPos1);
+                plcInfo.strIp = strInfo.Mid(nPos1 + 1, nPos2 - nPos1 - 1);
+                plcInfo.nPort = _ttoi(strInfo.Mid(nPos2 + 1));
+
+                m_plcList.push_back(plcInfo);
+            }
+        }
+    }
+}
+
+// 保存 PLC 列表到文件
+void CConfiguration::savePLCListToFile()
+{
+    // 清空文件中原来的 PLC 配置数据
+    WritePrivateProfileString("PLCs", NULL, NULL, m_strFilepath);
+
+    // 保存 PLC 数量
+    int nPLCCount = (int)m_plcList.size();
+    WritePrivateProfileString("PLCs", "PLCCount", std::to_string(nPLCCount).c_str(), m_strFilepath);
+
+	// 重新写入数据
+    for (int i = 0; i < nPLCCount; i++) {
+        char szSection[256];
+        sprintf_s(szSection, 256, "PLC%d", i + 1);
+        CString strInfo;
+        strInfo.Format(_T("%s,%s,%d"), m_plcList[i].strName, m_plcList[i].strIp, m_plcList[i].nPort);
+        WritePrivateProfileString("PLCs", szSection, strInfo, m_strFilepath);
+    }
+}
+
diff --git a/SourceCode/Bond/BoounionPLC/Configuration.h b/SourceCode/Bond/BoounionPLC/Configuration.h
index 95d00e2..ad3b6a9 100644
--- a/SourceCode/Bond/BoounionPLC/Configuration.h
+++ b/SourceCode/Bond/BoounionPLC/Configuration.h
@@ -1,6 +1,14 @@
 #pragma once
 #include <vector>
 #include <string>
+#include <algorithm>
+
+// PLC信息
+struct PlcInfo {
+	CString strName;  // PLC 名称
+	CString strIp;    // IP 地址
+	UINT nPort;       // 端口号
+};
 
 class CConfiguration
 {
@@ -25,7 +33,21 @@
 	void setP2RemoteEqReconnectInterval(int second);
 	int getP2RemoteEqReconnectInterval();
 
+public:
+	// PLC配置操作
+	bool addPLC(const CString& strName, const CString& strIp, UINT nPort);
+	bool removePLC(const CString& strName);
+	bool updatePLC(const CString& strOldName, const CString& strNewName, const CString& strNewIp, UINT nNewPort);
+	bool getPLCByName(const CString& strName, CString& strIp, UINT& nPort);
+	void getAllPLCInfo(std::vector<PlcInfo>& plcList);
+	int getPLCListCount();
+
+private:
+	void loadPLCListFromFile();
+	void savePLCListToFile();
+
 private:
 	CString m_strFilepath;
+	std::vector<PlcInfo> m_plcList;
 };
 
diff --git a/SourceCode/Bond/BoounionPLC/DBManager/AxisManager.cpp b/SourceCode/Bond/BoounionPLC/DBManager/AxisManager.cpp
deleted file mode 100644
index e3e1ae5..0000000
--- a/SourceCode/Bond/BoounionPLC/DBManager/AxisManager.cpp
+++ /dev/null
@@ -1,246 +0,0 @@
-#include "stdafx.h"
-#include "AxisManager.h"
-#include <sstream>
-#include <stdexcept>
-#include <mutex>
-
-// 静态成员初始化
-std::mutex AxisManager::m_mutex;
-
-// 获取单例实例
-AxisManager& AxisManager::getInstance() {
-    static AxisManager instance;
-    return instance;
-}
-
-AxisManager::AxisManager() : m_pDB(nullptr) {}
-
-AxisManager::~AxisManager() {
-    m_pDB = nullptr;
-}
-
-// 设置数据库连接
-void AxisManager::setDatabase(BL::Database* db) {
-    std::lock_guard<std::mutex> lock(m_mutex);
-    m_pDB = db;
-}
-
-// 初始化轴表和定位点表
-bool AxisManager::initializeTables() {
-    if (!m_pDB) {
-        throw std::runtime_error("Database connection is not set.");
-    }
-
-    const std::string createAxesTableQuery = R"(
-        CREATE TABLE IF NOT EXISTS axes (
-            axis_id INTEGER PRIMARY KEY,
-            axis_no TEXT NOT NULL,
-            description TEXT NOT NULL,
-            start_address TEXT,
-            jog_distance REAL,
-            manual_speed REAL,
-            max_manual_speed REAL,
-            min_manual_speed REAL,
-            auto_speed REAL,
-            max_auto_speed REAL,
-            min_auto_speed REAL,
-            acceleration_time REAL,
-            deceleration_time REAL
-        )
-    )";
-
-    const std::string createPositionsTableQuery = R"(
-        CREATE TABLE IF NOT EXISTS positions (
-            position_id INTEGER PRIMARY KEY AUTOINCREMENT,
-            axis_id INTEGER NOT NULL,
-            description TEXT,
-            position_value REAL,
-            plc_address TEXT,
-            FOREIGN KEY (axis_id) REFERENCES axes(axis_id)
-        )
-    )";
-
-    return m_pDB->executeQuery(createAxesTableQuery) && m_pDB->executeQuery(createPositionsTableQuery);
-}
-
-// 初始化默认数据
-bool AxisManager::initializeDefaultData() {
-    if (!m_pDB) {
-        throw std::runtime_error("Database connection is not set.");
-    }
-
-    for (int axisId = 1; axisId <= 12; ++axisId) {
-        std::ostringstream axisQuery;
-        axisQuery << "INSERT OR IGNORE INTO axes (axis_id, axis_no, description, start_address, jog_distance, manual_speed, "
-            << "max_manual_speed, min_manual_speed, auto_speed, max_auto_speed, min_auto_speed, acceleration_time, deceleration_time) "
-            << "VALUES (" << axisId << ", 'M" << axisId * 10 << "', '轴 " << axisId << "', 'D" << (5090 + axisId * 2) << "', "
-            << "0.5, 10.0, 20.0, 5.0, 15.0, 25.0, 10.0, 0.2, 0.3)";
-        m_pDB->executeQuery(axisQuery.str());
-    }
-
-    for (int axisId = 1; axisId <= 12; ++axisId) {
-        for (int positionIndex = 1; positionIndex <= 25; ++positionIndex) {
-            std::ostringstream positionQuery;
-            positionQuery << "INSERT OR IGNORE INTO positions (axis_id, description, position_value, plc_address) "
-                << "VALUES (" << axisId << ", '定位点 " << positionIndex << "', " << (positionIndex * 10.0) << ", "
-                << "'D" << (5240 + positionIndex * 2) << "')";
-            m_pDB->executeQuery(positionQuery.str());
-        }
-    }
-
-    return true;
-}
-
-// 添加或更新轴信息
-bool AxisManager::saveAxis(int axisId, const std::string& axisNo, const std::string& description,
-    const std::string& startAddress, double jogDistance, double manualSpeed,
-    double maxManualSpeed, double minManualSpeed, double autoSpeed,
-    double maxAutoSpeed, double minAutoSpeed, double accelerationTime,
-    double decelerationTime) {
-    if (!m_pDB) {
-        throw std::runtime_error("Database connection is not set.");
-    }
-
-    std::ostringstream query;
-    query << "INSERT INTO axes (axis_id, axis_no, description, start_address, jog_distance, manual_speed, "
-        << "max_manual_speed, min_manual_speed, auto_speed, max_auto_speed, min_auto_speed, acceleration_time, deceleration_time) "
-        << "VALUES (" << axisId << ", '" << axisNo << "', '" << description << "', '" << startAddress << "', "
-        << jogDistance << ", " << manualSpeed << ", " << maxManualSpeed << ", " << minManualSpeed << ", " << autoSpeed
-        << ", " << maxAutoSpeed << ", " << minAutoSpeed << ", " << accelerationTime << ", " << decelerationTime << ") "
-        << "ON CONFLICT(axis_id) DO UPDATE SET "
-        << "axis_no=excluded.axis_no, description=excluded.description, start_address=excluded.start_address, "
-        << "jog_distance=excluded.jog_distance, manual_speed=excluded.manual_speed, max_manual_speed=excluded.max_manual_speed, "
-        << "min_manual_speed=excluded.min_manual_speed, auto_speed=excluded.auto_speed, max_auto_speed=excluded.max_auto_speed, "
-        << "min_auto_speed=excluded.min_auto_speed, acceleration_time=excluded.acceleration_time, deceleration_time=excluded.deceleration_time";
-
-    std::lock_guard<std::mutex> lock(m_mutex);
-    return m_pDB->executeQuery(query.str());
-}
-
-// 获取单个轴信息
-std::vector<std::string> AxisManager::getAxis(int axisId) {
-    if (!m_pDB) {
-        throw std::runtime_error("Database connection is not set.");
-    }
-
-    std::ostringstream query;
-    query << "SELECT * FROM axes WHERE axis_id = " << axisId;
-
-    auto result = m_pDB->fetchResults(query.str());
-    return !result.empty() ? result[0] : std::vector<std::string>();
-}
-
-// 获取所有轴信息
-std::vector<std::vector<std::string>> AxisManager::getAllAxes() {
-    if (!m_pDB) {
-        throw std::runtime_error("Database connection is not set.");
-    }
-
-    return m_pDB->fetchResults("SELECT * FROM axes ORDER BY axis_id");
-}
-
-// 删除指定轴
-bool AxisManager::deleteAxis(int axisId) {
-    if (!m_pDB) {
-        throw std::runtime_error("Database connection is not set.");
-    }
-
-    std::ostringstream query;
-    query << "DELETE FROM axes WHERE axis_id = " << axisId;
-
-    std::lock_guard<std::mutex> lock(m_mutex);
-    return m_pDB->executeQuery(query.str());
-}
-
-// 添加或更新定位点
-bool AxisManager::savePosition(int axisId, const std::string& description, double positionValue, const std::string& plcAddress) {
-    if (!m_pDB) {
-        throw std::runtime_error("Database connection is not set.");
-    }
-
-    std::ostringstream query;
-    query << "INSERT INTO positions (axis_id, description, position_value, plc_address) VALUES ("
-        << axisId << ", '" << description << "', " << positionValue << ", '" << plcAddress << "') "
-        << "ON CONFLICT(axis_id) DO UPDATE SET "
-        << "description=excluded.description, position_value=excluded.position_value, plc_address=excluded.plc_address";
-
-    std::lock_guard<std::mutex> lock(m_mutex);
-    return m_pDB->executeQuery(query.str());
-}
-
-// 获取轴的所有定位点
-std::vector<std::vector<std::string>> AxisManager::getPositions(int axisId, int pageNumber, int pageSize) {
-    if (!m_pDB) {
-        throw std::runtime_error("Database connection is not set.");
-    }
-
-    int offset = (pageNumber - 1) * pageSize;
-    std::ostringstream query;
-    query << "SELECT * FROM positions WHERE axis_id = " << axisId << " LIMIT " << pageSize << " OFFSET " << offset;
-
-    return m_pDB->fetchResults(query.str());
-}
-
-// 获取定位点总数
-int AxisManager::getTotalPositionCount(int axisId) {
-    if (!m_pDB) {
-        throw std::runtime_error("Database connection is not set.");
-    }
-
-    std::ostringstream query;
-    query << "SELECT COUNT(*) FROM positions WHERE axis_id = " << axisId;
-
-    auto result = m_pDB->fetchResults(query.str());
-    return (!result.empty() && !result[0].empty()) ? std::stoi(result[0][0]) : 0;
-}
-
-// 删除指定定位点
-bool AxisManager::deletePosition(int positionId) {
-    if (!m_pDB) {
-        throw std::runtime_error("Database connection is not set.");
-    }
-
-    std::ostringstream query;
-    query << "DELETE FROM positions WHERE position_id = " << positionId;
-
-    std::lock_guard<std::mutex> lock(m_mutex);
-    return m_pDB->executeQuery(query.str());
-}
-
-// 获取所有的轴ID
-std::vector<int> AxisManager::getUsedAxisIds() {
-    if (!m_pDB) {
-        throw std::runtime_error("Database connection is not set.");
-    }
-
-    std::vector<int> usedAxisIds;
-    std::string query = "SELECT axis_id FROM axes ORDER BY axis_id";
-    auto results = m_pDB->fetchResults(query);
-
-    for (const auto& row : results) {
-        if (!row.empty()) {
-            usedAxisIds.push_back(std::stoi(row[0]));
-        }
-    }
-
-    return usedAxisIds;
-}
-
-// 获取所有轴的轴NO
-std::vector<std::string> AxisManager::getAllAxisNumbers() {
-    if (!m_pDB) {
-        throw std::runtime_error("Database connection is not set.");
-    }
-
-    std::vector<std::string> axisNumbers;
-    std::string query = "SELECT axis_no FROM axes ORDER BY axis_id";
-    auto results = m_pDB->fetchResults(query);
-
-    for (const auto& row : results) {
-        if (!row.empty()) {
-            axisNumbers.push_back(row[0]);
-        }
-    }
-
-    return axisNumbers;
-}
diff --git a/SourceCode/Bond/BoounionPLC/DBManager/AxisManager.h b/SourceCode/Bond/BoounionPLC/DBManager/AxisManager.h
deleted file mode 100644
index b0d65ca..0000000
--- a/SourceCode/Bond/BoounionPLC/DBManager/AxisManager.h
+++ /dev/null
@@ -1,75 +0,0 @@
-#ifndef AXIS_MANAGER_H
-#define AXIS_MANAGER_H
-
-#include <string>
-#include <vector>
-#include <mutex>
-#include "Database.h"
-
-// 轴管理类
-class AxisManager {
-public:
-    // 获取单例实例
-    static AxisManager& getInstance();
-
-    // 设置数据库连接
-    void setDatabase(BL::Database* db);
-
-    // 初始化轴表和定位点表
-    bool initializeTables();
-
-    // 初始化默认数据
-    bool initializeDefaultData();
-
-    // 添加或更新轴信息
-    bool saveAxis(int axisId, const std::string& axisNo, const std::string& description,
-        const std::string& startAddress, double jogDistance, double manualSpeed,
-        double maxManualSpeed, double minManualSpeed, double autoSpeed,
-        double maxAutoSpeed, double minAutoSpeed, double accelerationTime,
-        double decelerationTime);
-
-    // 获取单个轴信息
-    std::vector<std::string> getAxis(int axisId);
-
-    // 获取所有轴信息
-    std::vector<std::vector<std::string>> getAllAxes();
-
-    // 删除指定轴
-    bool deleteAxis(int axisId);
-
-    // 添加或更新定位点
-    bool savePosition(int axisId, const std::string& description, double positionValue,
-        const std::string& plcAddress);
-
-    // 获取轴的所有定位点
-    std::vector<std::vector<std::string>> getPositions(int axisId, int pageNumber, int pageSize);
-
-    // 获取定位点总数
-    int getTotalPositionCount(int axisId);
-
-    // 删除指定定位点
-    bool deletePosition(int positionId);
-
-    // 获取所有的轴ID
-    std::vector<int> getUsedAxisIds();
-
-    // 获取所有轴的轴NO
-    std::vector<std::string> getAllAxisNumbers();
-
-private:
-    // 私有构造函数和析构函数
-    AxisManager();
-    ~AxisManager();
-
-    // 禁止拷贝和赋值
-    AxisManager(const AxisManager&) = delete;
-    AxisManager& operator=(const AxisManager&) = delete;
-
-    // 数据库连接
-    BL::Database* m_pDB;
-
-    // 线程安全锁
-    static std::mutex m_mutex;
-};
-
-#endif // AXIS_MANAGER_H
\ No newline at end of file
diff --git a/SourceCode/Bond/BoounionPLC/Model.cpp b/SourceCode/Bond/BoounionPLC/Model.cpp
index d89bf61..59587a7 100644
--- a/SourceCode/Bond/BoounionPLC/Model.cpp
+++ b/SourceCode/Bond/BoounionPLC/Model.cpp
@@ -2,6 +2,9 @@
 #include "Model.h"
 #include "Log.h"
 #include "Common.h"
+#include "ToolUnits.h"
+
+// 常量
 
 
 CModel* g_pModel = NULL;
@@ -72,10 +75,12 @@
 	g_pModel = this;
 
 
-	// 模拟从文档或数据库加载PLC列表
-	addPlc("Test1", "127.0.0.1", 1001);
-	addPlc("Test2", "127.0.0.1", 1002);
-
+	// 获取所有PLC信息
+	std::vector<PlcInfo> plcList;
+	m_configuration.getAllPLCInfo(plcList);
+	for (const auto& plc : plcList) {
+		addPlc(plc.strName, plc.strIp, plc.nPort);
+	}
 
 	return 0;
 }
@@ -308,6 +313,13 @@
 			}
 		}
 	}
+
+
+	// 读取产能信息
+	CPLC* pPlc = getCurrentPlc();
+	if (pPlc != nullptr) {
+		pPlc->readPLCDataRegularly();
+	}
 }
 
 std::map<std::string, CPLC*>& CModel::getPlcMap()
@@ -319,9 +331,39 @@
 {
 	auto iter = m_mapPlc.find(pszName);
 	if (iter != m_mapPlc.end()) return -1;
+	CString strPlcDir;
+	strPlcDir.Format(_T("%s\\Plcs\\%s"), (LPTSTR)(LPCTSTR)m_strWorkDir, pszName);
 	CPLC* pPLC = new CPLC(pszName, pszIp, port);
+	pPLC->setWorkDir((LPTSTR)(LPCTSTR)strPlcDir);
+	PLCListener listener;
+	listener.onStateChanged = [&](void* pFrom, int state) -> void {
+		LOGD("PLC状态改变,%d", state);
+	};
+	listener.onMonitorData = [&](void* pFrom, int id) -> void {
+		LOGD("PLConMonitorData,%d", id);
+	};
+	listener.onAlarm = [&](void* pFrom, CAlarm* pAlarm, int flag) -> void {
+		LOGE("onAlarm,%d %s", pAlarm->getId(), flag != 0 ? "ON" : "Off");
+		if (flag == 1) {
+			pAlarm->addRef();
+			notifyObjAndPtr(RX_CODE_ALARM_ON, pAlarm, pFrom);
+			pAlarm->release();
+		}
+		else {
+			pAlarm->addRef();
+			notifyObjAndPtr(RX_CODE_ALARM_OFF, pAlarm, pFrom);
+			pAlarm->release();
+		}
+
+	};
+	pPLC->setListener(listener);
 	pPLC->init();
 	m_mapPlc[pszName] = pPLC;
+
+	CString strDir;
+	strDir.Format(_T("%s\\PLCs\\%s"), (LPTSTR)(LPCTSTR)m_strWorkDir, (LPTSTR)(LPCTSTR)pszName);
+	CToolUnits::createDir(strDir);
+	m_configuration.addPLC(pszName, pszIp, port);
 
 	notifyPtr(RX_CODE_ADD_PLC, pPLC);
 	return 0;
@@ -332,8 +374,33 @@
 	auto iter = m_mapPlc.find(pszName);
 	if (iter == m_mapPlc.end()) return -1;
 
+	CString strDir;
+	strDir.Format(_T("%s\\PLCs\\%s"), (LPTSTR)(LPCTSTR)m_strWorkDir, (LPTSTR)(LPCTSTR)pszName);
+	CToolUnits::deleteDir(strDir);
+	m_configuration.removePLC(pszName);
+
 	notifyPtr(RX_CODE_REMOVE_PLC, iter->second);
 	delete iter->second;
 	m_mapPlc.erase(iter);
+
 	return 0;
 }
+
+void CModel::setCurrentPlc(CPLC* pPlc)
+{
+	if (pPlc != nullptr) {
+		m_strCurrPlc = pPlc->getName();
+	} else {
+		m_strCurrPlc = "";
+	}
+}
+
+CPLC* CModel::getCurrentPlc()
+{
+	auto item = m_mapPlc.find(m_strCurrPlc);
+	if (item != m_mapPlc.end()) {
+		return item->second;
+	}
+
+	return nullptr;
+}
\ No newline at end of file
diff --git a/SourceCode/Bond/BoounionPLC/Model.h b/SourceCode/Bond/BoounionPLC/Model.h
index b02b2de..48a52cb 100644
--- a/SourceCode/Bond/BoounionPLC/Model.h
+++ b/SourceCode/Bond/BoounionPLC/Model.h
@@ -20,6 +20,10 @@
 	int addPlc(const char* pszName, const char* pszIp, const unsigned int port);
 	int removePlc(const char* pszName);
 
+	// 设置/获取当前PLC
+	void setCurrentPlc(CPLC* pPlc);
+	CPLC* getCurrentPlc();
+
 public:
 	int notify(int code);
 	int notifyPtr(int code, void* ptr = NULL);
@@ -37,12 +41,12 @@
 public:
 	CConfiguration m_configuration;
 
-
 private:
 	IObservable* m_pObservable;
 	IObservableEmitter* m_pObservableEmitter;
 	CString m_strWorkDir;
 	std::map<std::string, CPLC*> m_mapPlc;
+	std::string m_strCurrPlc;
 
 private:
 	int m_nTimerID;
diff --git a/SourceCode/Bond/BoounionPLC/PLC.cpp b/SourceCode/Bond/BoounionPLC/PLC.cpp
index 526073b..9e4e637 100644
--- a/SourceCode/Bond/BoounionPLC/PLC.cpp
+++ b/SourceCode/Bond/BoounionPLC/PLC.cpp
@@ -1,7 +1,10 @@
 #include "stdafx.h"
 #include "PLC.h"
 #include "Log.h"
+#include "ToolUnits.h"
 
+
+#define ADDR_NIGHT_SHIFT_CAPACTITY		1627
 
 void CALLBACK TimerFileProc(UINT uID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2)
 {
@@ -31,6 +34,9 @@
 	m_nTimerId = 0;
 	m_hTimeEvent = nullptr;
 	m_bMute = false;
+	m_pPlcData = new char[4096];
+	m_nVelocityRatio = 0;
+	InitializeCriticalSection(&m_criticalSection);
 }
 
 CPLC::CPLC(const char* pszName, const char* pszIp, const unsigned int port)
@@ -42,6 +48,7 @@
 	m_state = PLCSTATE::READY;
 	m_listener.onStateChanged = nullptr;
 	m_listener.onMonitorData = nullptr;
+	m_listener.onAlarm = nullptr;
 	m_nUnHeartBeat = 0;
 	m_hTimeEvent = nullptr;
 	m_hMcMonitorStop = nullptr;
@@ -49,10 +56,32 @@
 	m_mcMonitorThrdaddr = 0;
 	m_nTimerId = 0;
 	m_hTimeEvent = nullptr;
+	m_pPlcData = new char[4096];
+	m_nVelocityRatio = 0;
+	m_dTactTime = 0.0;
+	m_nDayShiftCapacity = 0;
+	m_nNightShiftCapacity = 0;
+	for (int i = 0; i < 7; i++) {
+		m_bBlBtnsStates[i] = false;
+	}
+
+	InitializeCriticalSection(&m_criticalSection);
 }
 
 CPLC::~CPLC()
 {
+	if (m_pPlcData != nullptr) {
+		delete[] m_pPlcData;
+		m_pPlcData = nullptr;
+	}
+	DeleteCriticalSection(&m_criticalSection);
+}
+
+void CPLC::setListener(PLCListener& listener)
+{
+	m_listener.onStateChanged = listener.onStateChanged;
+	m_listener.onMonitorData = listener.onMonitorData;
+	m_listener.onAlarm = listener.onAlarm;
 }
 
 void CPLC::setWorkDir(const char* pszDir)
@@ -82,7 +111,32 @@
 
 CAlarmMonitor* CPLC::getAlarmMonitor()
 {
-	return (CAlarmMonitor*)getComponent("PLC(1)");
+	return (CAlarmMonitor*)getComponent("警告信息");
+}
+
+int CPLC::addMonitor(int id, int beginAddr, int endAddr, MC::SOFT_COMPONENT softComponent, char* pszRecvBuffer)
+{
+	// 检查是否有重复的
+	Lock();
+	for (auto& m : m_monitors) {
+		if (m.id == id) {
+			Unlock();
+			return -1;
+		}
+	}
+
+	MONITOR m;
+	memset(&m, 0, sizeof(MONITOR));
+	m.id = id;
+	m.beginAddr = beginAddr;
+	m.readLen = (endAddr - beginAddr + 1) * 2;
+	m.softComponent = softComponent;
+	m.szRecvBuffer = pszRecvBuffer;
+	m.hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
+	m_monitors.push_back(m);
+
+	Unlock();
+	return 0;
 }
 
 void CPLC::init()
@@ -127,11 +181,12 @@
 		m_pChannel->setChannelListener(&m_mcChannellistener);
 		m_pChannel->setActionInterval(m_nActionInterval);
 	}
+	addMonitor(MONITOR_ID_ALARM, 10001, 10064, MC::SOFT_COMPONENT::M, &m_pPlcData[600]);
 
 
 	// 警告监控
 	CString strAlarmFile;
-	strAlarmFile.Format(_T("%s\\%s\\AlarmList.txt"), m_strWorkDir.c_str(), m_strName.c_str());
+	strAlarmFile.Format(_T("%s\\AlarmList.txt"), m_strWorkDir.c_str());
 	CAlarmMonitor* pAlarmMonitor = new CAlarmMonitor();
 	pAlarmMonitor->setName("警告信息");
 	pAlarmMonitor->setDescription("警告信息监控");
@@ -284,9 +339,24 @@
 	WaitForSingleObject(monitor.hEvent, INFINITE);
 	ResetEvent(monitor.hEvent);
 	if (bReadOk) {
-		ASSERT(m_listener.onMonitorData);
+		onMonitorData(monitor);
+	}
+}
+
+int CPLC::onMonitorData(MONITOR& monitor)
+{
+	// 转发到警告模块处理解释数据
+	if (monitor.id == MONITOR_ID_ALARM) {
+		for (auto c : m_components) {
+			c->onData(monitor.id, monitor.szRecvBuffer, monitor.readLen);
+		}
+	}
+
+	if (m_listener.onMonitorData) {
 		m_listener.onMonitorData(this, monitor.id);
 	}
+
+	return 0;
 }
 
 int CPLC::readWord(MC::SOFT_COMPONENT softComponent, unsigned int addr,
@@ -368,3 +438,125 @@
 	}
 }
 
+void CPLC::readPLCDataRegularly()
+{
+	if (!isConnected()) return;
+
+	{
+		auto funOnReadData = [this](IMcChannel* pChannel, int addr, char* pData, unsigned int nDataSize, int flag) -> void {
+			if (nDataSize == 2 && flag == 0) {
+				int nVelocityRatio = CToolUnits::toInt16(&pData[0]);
+				if (nVelocityRatio != m_nVelocityRatio) {
+					m_nVelocityRatio = nVelocityRatio;
+					//notifyInt(RX_CODE_VELOCITY_RATIO, m_nVelocityRatio);
+				}
+			}
+		};
+		readData(MC::D, 530, 2, funOnReadData);
+	}
+
+	{
+		auto funOnReadData = [this](IMcChannel* pChannel, int addr, char* pData, unsigned int nDataSize, int flag) -> void {
+			if (nDataSize == 2 && flag == 0) {
+				double dTactTime = (double)CToolUnits::toInt16(&pData[0]);
+				if (dTactTime != m_dTactTime) {
+					m_dTactTime = dTactTime;
+					// notifyDouble(RX_CODE_TACT_TIME, m_dTactTime);
+				}
+			}
+		};
+		readData(MC::ZR, 1500, 2, funOnReadData);
+	}
+
+	{
+		auto funOnReadData = [this](IMcChannel* pChannel, int addr, char* pData, unsigned int nDataSize, int flag) -> void {
+			if (nDataSize == (ADDR_NIGHT_SHIFT_CAPACTITY - 1612 + 1) * 2 && flag == 0) {
+				int nDayShiftCapacity = CToolUnits::toInt16(&pData[0]);
+				int nNightShiftCapacity = CToolUnits::toInt16(&pData[(ADDR_NIGHT_SHIFT_CAPACTITY - 1612) * 2]);
+				if (nDayShiftCapacity != m_nDayShiftCapacity) {
+					m_nDayShiftCapacity = nDayShiftCapacity;
+					// notifyInt(RX_CODE_DAY_SHIFT_CAPACTITY, nDayShiftCapacity);
+				}
+				if (nNightShiftCapacity != m_nNightShiftCapacity) {
+					m_nNightShiftCapacity = nNightShiftCapacity;
+					// notifyInt(RX_CODE_NIGHT_SHIFT_CAPACTITY, nNightShiftCapacity);
+				}
+
+			}
+		};
+		readData(MC::ZR, 1612, (ADDR_NIGHT_SHIFT_CAPACTITY - 1612 + 1) * 2, funOnReadData);
+	}
+
+	{
+		int nStartAddress = 1000;
+		int nEndAddress = 1200;
+		int nReadSize = (nEndAddress - nStartAddress + 1) * 2;
+		auto funOnReadData = [this, nStartAddress, nReadSize](IMcChannel* pChannel, int addr, char* pData, unsigned int nDataSize, int flag) -> void {
+			if (nDataSize == nReadSize && flag == 0) {
+				bool bRun = CToolUnits::toInt16(&pData[(1103 - nStartAddress) * 2]) != 0;		// 启动
+				bool bAuto = CToolUnits::toInt16(&pData[(1100 - nStartAddress) * 2]) != 0;		// 自动
+				bool bPuase = CToolUnits::toInt16(&pData[(1104 - nStartAddress) * 2]) != 0;		// 暂停
+				bool bManual = CToolUnits::toInt16(&pData[(1100 - nStartAddress) * 2]) != 0;	// 手动
+				bool bBeep = CToolUnits::toInt16(&pData[(1003 - nStartAddress) * 2]) != 0;		// 静音
+				bool bResetting = CToolUnits::toInt16(&pData[(1150 - nStartAddress) * 2]) != 0; // 复位
+				bool bStop = CToolUnits::toInt16(&pData[(1114 - nStartAddress) * 2]) != 0;		// 停止
+
+				if (m_bBlBtnsStates[0] != bRun) {
+					m_bBlBtnsStates[0] = bRun;
+					// notifyInt(RX_CODE_ACTIVATE, bRun);
+				}
+
+				if (m_bBlBtnsStates[1] != bAuto) {
+					m_bBlBtnsStates[1] = bAuto;
+					// notifyInt(RX_CODE_AUTO, bAuto);
+				}
+
+				if (m_bBlBtnsStates[2] != bPuase) {
+					m_bBlBtnsStates[2] = bPuase;
+					// notifyInt(RX_CODE_PUASE, bPuase);
+				}
+
+				if (m_bBlBtnsStates[3] != bManual) {
+					m_bBlBtnsStates[3] = bManual;
+					// notifyInt(RX_CODE_MANUAL, bManual);
+				}
+
+				if (m_bBlBtnsStates[4] != bBeep) {
+					m_bBlBtnsStates[4] = bBeep;
+					// notifyInt(RX_CODE_BEEP, bBeep);
+				}
+
+				if (m_bBlBtnsStates[5] != bResetting) {
+					m_bBlBtnsStates[5] = bResetting;
+					// notifyInt(RX_CODE_RESETTING, bResetting);
+				}
+
+				if (m_bBlBtnsStates[6] != bStop) {
+					m_bBlBtnsStates[6] = bStop;
+					// notifyInt(RX_CODE_STOP, bStop);
+				}
+			}
+		};
+		readData(MC::M, nStartAddress, nReadSize, funOnReadData);
+	}
+}
+
+int CPLC::getVelocityRatio()
+{
+	return m_nVelocityRatio;
+}
+
+double CPLC::getTackTime()
+{
+	return m_dTactTime;
+}
+
+int CPLC::getDayShiftCapacity()
+{
+	return m_nDayShiftCapacity;
+}
+
+int CPLC::getNightShiftCapacity()
+{
+	return m_nNightShiftCapacity;
+}
diff --git a/SourceCode/Bond/BoounionPLC/PLC.h b/SourceCode/Bond/BoounionPLC/PLC.h
index 2bfc39e..e69e54c 100644
--- a/SourceCode/Bond/BoounionPLC/PLC.h
+++ b/SourceCode/Bond/BoounionPLC/PLC.h
@@ -5,6 +5,8 @@
 #pragma comment(lib,"winmm")
 
 
+#define ALARM_MONITOR		_T("警告信息")
+
 typedef std::function<void(void* pFrom, int)> ONPLCSTATECHANGED;
 typedef std::function<void(void* pFrom, int)> ONPLCMONITORDATA;
 typedef std::function<void(void* pFrom, CAlarm*, int)> ONALARM;
@@ -42,6 +44,7 @@
 	~CPLC();
 
 public:
+	void setListener(PLCListener& listener);
 	void setWorkDir(const char* pszDir);
 	void init();
 	void term();
@@ -66,15 +69,24 @@
 	int writeDWord(MC::SOFT_COMPONENT softComponent, unsigned int addr, int value, ONWRITE funOnWrite);
 	int writeBit(MC::SOFT_COMPONENT softComponent, unsigned int addr, BOOL bValue, ONWRITE funOnWrite);
 	int writeData(MC::SOFT_COMPONENT softComponent, unsigned int addr, const char* pszData, unsigned int length, ONWRITE funOnWrite);
+	void readPLCDataRegularly();
 
+public:
+	int getVelocityRatio();
+	double getTackTime();
+	int getDayShiftCapacity();
+	int getNightShiftCapacity();
 
 public:
 	HANDLE m_hTimeEvent;
 
 private:
+	inline void Lock() { EnterCriticalSection(&m_criticalSection); }
+	inline void Unlock() { LeaveCriticalSection(&m_criticalSection); }
 	void setState(PLCSTATE state);
 	void monitorReadData(MONITOR& monitor);
 	CString& dataToHexString(const char* pData, const int size, CString& strOut);
+	int onMonitorData(MONITOR& monitor);
 
 private:
 	std::string m_strWorkDir;
@@ -87,13 +99,22 @@
 	unsigned int m_nActionInterval;
 	unsigned int m_nUnHeartBeat;
 	std::vector<CComponent*> m_components;
+	char* m_pPlcData;
 
 private:
+	CRITICAL_SECTION m_criticalSection;
 	std::vector<MONITOR> m_monitors;
 	HANDLE m_hMcMonitorStop;
 	HANDLE m_hMcMonitorThreadHandle;
 	unsigned m_mcMonitorThrdaddr;
 	MMRESULT m_nTimerId;
 	bool m_bMute;
+
+private:
+	int m_nVelocityRatio;		// 速度比
+	double m_dTactTime;			// 周期时间
+	int m_nDayShiftCapacity;	// 白班产能
+	int m_nNightShiftCapacity;	// 夜班产能
+	bool m_bBlBtnsStates[7];	// PLC View按钮状态
 };
 
diff --git a/SourceCode/Bond/BoounionPLC/PagePlcList.cpp b/SourceCode/Bond/BoounionPLC/PagePlcList.cpp
index ef6ab8b..f5203c8 100644
--- a/SourceCode/Bond/BoounionPLC/PagePlcList.cpp
+++ b/SourceCode/Bond/BoounionPLC/PagePlcList.cpp
@@ -72,6 +72,14 @@
 					BOOL bNoPLC = m_treeCtrl.GetChildItem(nullptr) == nullptr;
 					m_treeCtrl.ShowWindow(bNoPLC ? SW_HIDE : SW_SHOW);
 					GetDlgItem(IDC_LABEL_NO_PLC)->ShowWindow(bNoPLC ? SW_SHOW : SW_HIDE);
+
+					// 更新节点
+					HTREEITEM hSelectedItem = m_treeCtrl.GetSelectedItem();
+					CPLC* pSelectedPlc = nullptr;
+					if (hSelectedItem != NULL) {
+						pSelectedPlc = (CPLC*)m_treeCtrl.GetItemData(hSelectedItem);
+					}
+					theApp.m_model.notifyPtr(RX_CODE_SELECT_PLC, pSelectedPlc);
 				}
 			}
 
@@ -196,13 +204,13 @@
 
 HTREEITEM CPagePlcList::FindItem(CPLC* pPlc)
 {
-
 	HTREEITEM item = m_treeCtrl.GetChildItem(nullptr);
 	while (item != nullptr) {
 		if (m_treeCtrl.GetItemData(item) == (DWORD_PTR)pPlc) {
 			return item;
 		}
-		item = m_treeCtrl.GetNextSiblingItem(item);
+
+		item = m_treeCtrl.GetNextItem(item, TVGN_NEXT);
 	}
 
 	return nullptr;
diff --git a/SourceCode/Bond/BoounionPLC/PlcView.cpp b/SourceCode/Bond/BoounionPLC/PlcView.cpp
index 9d0926e..1b69175 100644
--- a/SourceCode/Bond/BoounionPLC/PlcView.cpp
+++ b/SourceCode/Bond/BoounionPLC/PlcView.cpp
@@ -45,6 +45,7 @@
 	ON_BN_CLICKED(IDC_BUTTON_SOUND_OFF, &CPlcView::OnBnClickedButtonSoundOff)
 	ON_BN_CLICKED(IDC_BUTTON_RESETTING, &CPlcView::OnBnClickedButtonResetting)
 	ON_BN_CLICKED(IDC_BUTTON_STOP, &CPlcView::OnBnClickedButtonStop)
+	ON_WM_TIMER()
 END_MESSAGE_MAP()
 
 // CComponentData1Dlg 消息处理程序
@@ -275,6 +276,9 @@
 	SetDlgItemText(IDC_EDIT_DAY_SHIFT_CAPACITY, _T("0"));
 	SetDlgItemText(IDC_EDIT_NIGHT_SHIFT_CAPACITY, _T("0"));
 
+
+	SetTimer(1, 1000, nullptr);
+
 	return TRUE;  // return TRUE unless you set the focus to a control
 				  // 异常: OCX 属性页应返回 FALSE
 }
@@ -360,4 +364,22 @@
 {
 	// TODO: 在此添加控件通知处理程序代码
 	HandleOperation(OperationType::STOP);
-}
\ No newline at end of file
+}
+
+void CPlcView::OnTimer(UINT_PTR nIDEvent)
+{
+	if (1 == nIDEvent) {
+		ASSERT(m_pContext);
+		CPLC* pPlc = ((CPLC*)m_pContext);
+
+		CString strText;
+		strText.Format(_T("%d %s"), pPlc->getVelocityRatio(), _T("%"));
+		GetDlgItem(IDC_EDIT_VELOCITY_RATIO)->SetWindowText(strText);
+		strText.Format(_T("%.2f"), pPlc->getTackTime() * 0.01);
+		GetDlgItem(IDC_EDIT_TACT_TIME)->SetWindowText(strText);
+		SetDlgItemInt(IDC_EDIT_DAY_SHIFT_CAPACITY, pPlc->getDayShiftCapacity());
+		SetDlgItemInt(IDC_EDIT_NIGHT_SHIFT_CAPACITY, pPlc->getNightShiftCapacity());
+	}
+
+	CBaseView::OnTimer(nIDEvent);
+}
diff --git a/SourceCode/Bond/BoounionPLC/PlcView.h b/SourceCode/Bond/BoounionPLC/PlcView.h
index bcebc87..1b63539 100644
--- a/SourceCode/Bond/BoounionPLC/PlcView.h
+++ b/SourceCode/Bond/BoounionPLC/PlcView.h
@@ -76,5 +76,6 @@
 	afx_msg void OnBnClickedButtonSoundOff();
 	afx_msg void OnBnClickedButtonResetting();
 	afx_msg void OnBnClickedButtonStop();
+	afx_msg void OnTimer(UINT_PTR nIDEvent);
 };
 
diff --git a/SourceCode/Bond/BoounionPLC/Resource.h b/SourceCode/Bond/BoounionPLC/Resource.h
index 951baec..aa5f648 100644
--- a/SourceCode/Bond/BoounionPLC/Resource.h
+++ b/SourceCode/Bond/BoounionPLC/Resource.h
Binary files differ
diff --git a/SourceCode/Bond/BoounionPLC/ToolUnits.cpp b/SourceCode/Bond/BoounionPLC/ToolUnits.cpp
index 664f802..d657a79 100644
--- a/SourceCode/Bond/BoounionPLC/ToolUnits.cpp
+++ b/SourceCode/Bond/BoounionPLC/ToolUnits.cpp
@@ -98,6 +98,53 @@
 	CreateDirectory(strDir, NULL);
 }
 
+void CToolUnits::deleteDir(const char* pszDir)
+{
+	WIN32_FIND_DATA findFileData;
+	HANDLE hFind = INVALID_HANDLE_VALUE;
+
+	// 拼接上 "\\*",表示目录下的所有文件和文件夹
+	std::string dirPath = pszDir;
+	dirPath.append("\\*");
+
+	// 打开目录,查找第一个文件
+	hFind = FindFirstFile(dirPath.c_str(), &findFileData);
+
+	if (hFind == INVALID_HANDLE_VALUE) {
+		return;
+	}
+
+	do {
+		const std::string fileName = findFileData.cFileName;
+		if (fileName == "." || fileName == "..") {
+			continue;
+		}
+
+		std::string fullPath = pszDir;
+		fullPath.append("\\").append(fileName);
+
+		if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+			deleteDir(fullPath.c_str());
+		}
+		else {
+			DWORD fileAttributes = GetFileAttributes(fullPath.c_str());
+			if (fileAttributes != INVALID_FILE_ATTRIBUTES) {
+				if (fileAttributes & FILE_ATTRIBUTE_READONLY) {
+					SetFileAttributes(fullPath.c_str(), fileAttributes & ~FILE_ATTRIBUTE_READONLY);
+				}
+			}
+
+			if (!DeleteFile(fullPath.c_str())) {
+				return;
+			}
+		}
+	} while (FindNextFile(hFind, &findFileData) != 0);
+
+	FindClose(hFind);
+
+	RemoveDirectory(pszDir);
+}
+
 CString& CToolUnits::floatToString1(float value, CString& strOut)
 {
 	strOut.Format(_T("%.1f"), value);
diff --git a/SourceCode/Bond/BoounionPLC/ToolUnits.h b/SourceCode/Bond/BoounionPLC/ToolUnits.h
index 9e8fdfb..afb7a22 100644
--- a/SourceCode/Bond/BoounionPLC/ToolUnits.h
+++ b/SourceCode/Bond/BoounionPLC/ToolUnits.h
@@ -16,6 +16,7 @@
 	static CString& floatToString3(float value, CString& strOut);
 	static ULONGLONG getTimestamp();
 	static void createDir(const char* pszDir);
+	static void deleteDir(const char* pszDir);
 	static BOOL copyTextToClipboard(CWnd* pWnd, const CString& strText);
 	static std::string getCurrentExePath();
 	static bool isFile(const std::string& path);
diff --git a/SourceCode/Bond/BoounionPLC/stdafx.h b/SourceCode/Bond/BoounionPLC/stdafx.h
index 3d75ce0..400123b 100644
--- a/SourceCode/Bond/BoounionPLC/stdafx.h
+++ b/SourceCode/Bond/BoounionPLC/stdafx.h
@@ -34,6 +34,24 @@
 #include <afxcontrolbars.h>     // 功能区和控件条的 MFC 支持
 
 
+// 控件样式
+static UINT g_nGridFixCellColor = RGB(144, 200, 246);
+static UINT g_nGridFixFontColor = RGB(0, 0, 0);
+static UINT g_nGridCellColor = RGB(255, 255, 224);
+static UINT g_nGridCellColor_NonSelect = RGB(150, 150, 150);
+static UINT g_nGridCellReadyColor = RGB(255, 255, 0);
+static UINT g_nGridCellOnColor = RGB(255, 69, 0);
+static UINT g_nGridCellOffColor = RGB(128, 191, 255);
+static UINT g_nPropertyGridFixCellColor = RGB(150, 150, 150);
+static UINT g_nPropertyGridFixFontColor = RGB(0, 0, 0);
+static UINT g_nSequenceOffColor = RGB(0, 0, 0);
+static UINT g_nSequenceOnColor = RGB(0, 180, 0);
+static UINT g_nSequenceErrorColor = RGB(255, 0, 0);
+static UINT g_nSequenceWarningColor = RGB(255, 255, 0);
+static UINT g_nSequenceReadyColor = RGB(0, 0, 255);
+static UINT g_nSequenceRunningColor = RGB(0, 255, 255);
+static UINT g_nSequencePauseColor = RGB(255, 0, 255);
+static UINT g_nSequenceStopColor = RGB(128, 128, 128);
 
 
 #include "..\RxWindows1.0\include\RxWindowsLib.h"
@@ -48,14 +66,18 @@
 #if defined(_WIN64)
 #if defined(_DEBUG)
 #pragma comment(lib, "..\\DatabaseSDK\\lib\\x64\\Debug\\DatabaseEx.lib")
+#pragma comment(lib, "..\\BLControlsSDK\\lib\\x64\\Debug\\BLControlsD.lib")
 #else
 #pragma comment(lib, "..\\DatabaseSDK\\lib\\x64\\Release\\DatabaseEx.lib")
+#pragma comment(lib, "..\\BLControlsSDK\\lib\\x64\\Release\\BLControls.lib")
 #endif
 #else
 #if defined(_DEBUG)
 #pragma comment(lib, "..\\DatabaseSDK\\lib\\Win32\\Debug\\DatabaseEx.lib")
+#pragma comment(lib, "..\\BLControlsSDK\\lib\\Win32\\Debug\\BLControlsD.lib")
 #else
 #pragma comment(lib, "..\\DatabaseSDK\\lib\\Win32\\Release\\DatabaseEx.lib")
+#pragma comment(lib, "..\\BLControlsSDK\\lib\\Win32\\Release\\BLControls.lib")
 #endif
 #endif
 

--
Gitblit v1.9.3