From 6d106eb1bb92dc235bcbda976ae232729bf52c7c Mon Sep 17 00:00:00 2001
From: LAPTOP-T815PCOQ\25526 <mr.liuyang@126.com>
Date: 星期一, 25 十一月 2024 13:46:15 +0800
Subject: [PATCH] 合并代码

---
 SourceCode/Bond/BondEq/BondEq.cpp               |    1 
 SourceCode/Bond/BondEq/CBonder.cpp              |  159 ++----------
 SourceCode/Bond/BondEq/Resource.h               |    0 
 SourceCode/Bond/BondEq/CPanelProject.cpp        |   11 
 SourceCode/Bond/BondEq/BondEq.rc                |    0 
 SourceCode/Bond/BondEq/BondEqDlg.cpp            |   12 
 SourceCode/Bond/x64/Debug/Config/BondEq.db      |    0 
 SourceCode/Bond/BondEq/BondEq.vcxproj           |    9 
 SourceCode/Bond/BondEq/Model.h                  |    6 
 SourceCode/Bond/BondEq/CPLC.cpp                 |    2 
 SourceCode/Bond/BondEq/ToolUnits.h              |    3 
 SourceCode/Bond/BondEq/View/AxisSettingsDlg.h   |   18 +
 SourceCode/Bond/BondEq/CBonder.h                |    3 
 SourceCode/Bond/BondEq/CPanelProject.h          |    2 
 SourceCode/Bond/BondEq/View/AxisSettingsDlg.cpp |  115 +++++++++
 SourceCode/Bond/BLControlsSDK/include/BLLabel.h |  102 +++----
 SourceCode/Bond/BondEq/ToolUnits.cpp            |   17 +
 SourceCode/Bond/BondEq/Model.cpp                |  198 ++++++++++++++++
 SourceCode/Bond/BondEq/Common.h                 |    8 
 19 files changed, 461 insertions(+), 205 deletions(-)

diff --git a/SourceCode/Bond/BLControlsSDK/include/BLLabel.h b/SourceCode/Bond/BLControlsSDK/include/BLLabel.h
index c0ef631..45bc4de 100644
--- a/SourceCode/Bond/BLControlsSDK/include/BLLabel.h
+++ b/SourceCode/Bond/BLControlsSDK/include/BLLabel.h
@@ -4,74 +4,66 @@
 #if _MSC_VER >= 1000
 #pragma once
 #endif // _MSC_VER >= 1000
-// Label.h : header file
-//
 
 /////////////////////////////////////////////////////////////////////////////
 // CBLLabel window
-enum FlashType {None, Text, Background };
+enum FlashType { None, Text, Background };
+enum TextAlign { AlignLeft, AlignCenter, AlignRight };
 
 class AFX_EXT_CLASS CBLLabel : public CStatic
 {
-// Construction
-public:
-	CBLLabel();
-	CBLLabel& SetBkColor(COLORREF crBkgnd);
-	CBLLabel& SetTextColor(COLORREF crText);
-	CBLLabel& SetText(const CString& strText);
-	CBLLabel& SetFontBold(BOOL bBold);
-	CBLLabel& SetFontName(const CString& strFont);
-	CBLLabel& SetFontUnderline(BOOL bSet);
-	CBLLabel& SetFontItalic(BOOL bSet);
-	CBLLabel& SetFontSize(int nSize);
-	CBLLabel& SetSunken(BOOL bSet);
-	CBLLabel& SetBorder(BOOL bSet);
-	CBLLabel& FlashText(BOOL bActivate);
-	CBLLabel& FlashBackground(BOOL bActivate);
-	CBLLabel& SetLink(BOOL bLink);
-	CBLLabel& SetLinkCursor(HCURSOR hCursor);
+    DECLARE_DYNCREATE(CBLLabel) // 鏀寔鍔ㄦ�佸垱寤�
 
-// Attributes
 public:
+    // 鏋勯�犱笌鏋愭瀯
+    CBLLabel();
+    virtual ~CBLLabel();
+
+    // 灞炴�ц缃帴鍙�
+    CBLLabel& SetBkColor(COLORREF crBkgnd);             // 璁剧疆鑳屾櫙棰滆壊
+    CBLLabel& SetTextColor(COLORREF crText);            // 璁剧疆鏂囨湰棰滆壊
+    CBLLabel& SetText(const CString& strText);          // 璁剧疆鏂囨湰鍐呭
+    CBLLabel& SetFontBold(BOOL bBold);                  // 璁剧疆瀛椾綋鍔犵矖
+    CBLLabel& SetFontName(const CString& strFont);      // 璁剧疆瀛椾綋鍚嶇О
+    CBLLabel& SetFontUnderline(BOOL bSet);              // 璁剧疆涓嬪垝绾�
+    CBLLabel& SetFontItalic(BOOL bSet);                 // 璁剧疆鏂滀綋
+    CBLLabel& SetFontSize(int nSize);                   // 璁剧疆瀛椾綋澶у皬
+    CBLLabel& SetAlignment(TextAlign alignment);        // 璁剧疆鏂囨湰瀵归綈鏂瑰紡
+    CBLLabel& SetDynamicFont(BOOL bDynamic);            // 璁剧疆鏄惁鍔ㄦ�佽皟鏁村瓧浣�
+    CBLLabel& FlashText(BOOL bActivate);                // 闂儊鏂囨湰
+    CBLLabel& FlashBackground(BOOL bActivate);          // 闂儊鑳屾櫙
+    CBLLabel& SetLink(BOOL bLink);                      // 璁剧疆鏄惁鍚敤瓒呴摼鎺�
+    CBLLabel& SetLinkCursor(HCURSOR hCursor);           // 璁剧疆瓒呴摼鎺ュ厜鏍�
+
 protected:
-	void ReconstructFont();
-	COLORREF	m_crText;
-	HBRUSH		m_hBrush;
-	HBRUSH		m_hwndBrush;
-	LOGFONT		m_lf;
-	CFont		m_font;
-	CString		m_strText;
-	BOOL		m_bState;
-	BOOL		m_bTimer;
-	BOOL		m_bLink;
-	FlashType	m_Type;
-	HCURSOR		m_hCursor;
-			// Operations
-public:
-// Overrides
-	// ClassWizard generated virtual function overrides
-	//{{AFX_VIRTUAL(CBLLabel)
-	//}}AFX_VIRTUAL
+    // 宸ュ叿鍑芥暟
+    void ReconstructFont();       // 閲嶆柊鏋勯�犲瓧浣�
+    void UpdateFontSize();        // 鍔ㄦ�佽皟鏁村瓧浣撳ぇ灏�
+    virtual void OnPaint();       // 鑷畾涔夌粯鍒舵枃鏈�
 
-// Implementation
-public:
-	virtual ~CBLLabel();
+    // 灞炴��
+    COLORREF m_crText;            // 鏂囨湰棰滆壊
+    COLORREF m_crBkColor;         // 鑳屾櫙棰滆壊
+    HBRUSH   m_hBrush;            // 鑳屾櫙鐢诲埛
+    LOGFONT  m_lf;                // 瀛椾綋淇℃伅
+    CFont    m_font;              // 瀛椾綋瀵硅薄
+    CString  m_strText;           // 鏂囨湰鍐呭
+    BOOL     m_bState;            // 鐘舵�侊紝鐢ㄤ簬闂儊
+    BOOL     m_bTimer;            // 瀹氭椂鍣ㄧ姸鎬�
+    BOOL     m_bLink;             // 鏄惁涓鸿秴閾炬帴
+    BOOL     m_bDynamicFont;      // 鏄惁鍔ㄦ�佽皟鏁村瓧浣撳ぇ灏�
+    TextAlign m_alignment;        // 鏂囨湰瀵归綈鏂瑰紡
+    FlashType m_Type;             // 闂儊绫诲瀷
+    HCURSOR  m_hCursor;           // 瓒呴摼鎺ュ厜鏍�
 
-	// Generated message map functions
 protected:
-	//{{AFX_MSG(CBLLabel)
-	afx_msg HBRUSH CtlColor(CDC* pDC, UINT nCtlColor);
-	afx_msg void OnTimer(UINT_PTR nIDEvent);
-	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
-	afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
-	//}}AFX_MSG
+    // MFC 娑堟伅鏄犲皠
+    virtual HBRUSH CtlColor(CDC* pDC, UINT nCtlColor);  // 鑳屾櫙鍜屾枃鏈鑹茶缃�
+    afx_msg void OnTimer(UINT_PTR nIDEvent);            // 瀹氭椂鍣ㄤ簨浠�
+    afx_msg void OnLButtonDown(UINT nFlags, CPoint point); // 榧犳爣鐐瑰嚮浜嬩欢
+    afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message); // 璁剧疆鍏夋爣浜嬩欢
 
-	DECLARE_MESSAGE_MAP()
+    DECLARE_MESSAGE_MAP()
 };
-
-/////////////////////////////////////////////////////////////////////////////
-
-//{{AFX_INSERT_LOCATION}}
-// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
 
 #endif // !defined(AFX_BLLABEL_H__A4EABEC5_2E8C_11D1_B79F_00805F9ECE10__INCLUDED_)
diff --git a/SourceCode/Bond/BondEq/BondEq.cpp b/SourceCode/Bond/BondEq/BondEq.cpp
index 7366fa1..6818a3d 100644
--- a/SourceCode/Bond/BondEq/BondEq.cpp
+++ b/SourceCode/Bond/BondEq/BondEq.cpp
@@ -152,6 +152,7 @@
 
 int CBondEqApp::ExitInstance()
 {
+	m_model.term();
 	BEQ_Term();
 	RX_Term();
 	MCL_Term();
diff --git a/SourceCode/Bond/BondEq/BondEq.rc b/SourceCode/Bond/BondEq/BondEq.rc
index d6fab05..6d09a5f 100644
--- a/SourceCode/Bond/BondEq/BondEq.rc
+++ b/SourceCode/Bond/BondEq/BondEq.rc
Binary files differ
diff --git a/SourceCode/Bond/BondEq/BondEq.vcxproj b/SourceCode/Bond/BondEq/BondEq.vcxproj
index 8c008d2..1cc2cf9 100644
--- a/SourceCode/Bond/BondEq/BondEq.vcxproj
+++ b/SourceCode/Bond/BondEq/BondEq.vcxproj
@@ -207,6 +207,7 @@
     <ClInclude Include="Context.h" />
     <ClInclude Include="CPanel.h" />
     <ClInclude Include="CParam.h" />
+    <ClInclude Include="CProjectPageComponents.h" />
     <ClInclude Include="CRemoteEqUnitView.h" />
     <ClInclude Include="CRemoteEqView.h" />
     <ClInclude Include="CHomeDialog.h" />
@@ -220,6 +221,7 @@
     <ClInclude Include="DBManager\UserManager.h" />
     <ClInclude Include="EQState.h" />
     <ClInclude Include="EQStateMonitor.h" />
+    <ClInclude Include="GB2860SQLite.h" />
     <ClInclude Include="HmTab.h" />
     <ClInclude Include="HmVerticalTab.h" />
     <ClInclude Include="HorizontalLine.h" />
@@ -239,6 +241,8 @@
     <ClInclude Include="SetPage1.h" />
     <ClInclude Include="SetPage2.h" />
     <ClInclude Include="SettingsDlg.h" />
+    <ClInclude Include="sqlite3.h" />
+    <ClInclude Include="sqlite3ext.h" />
     <ClInclude Include="stdafx.h" />
     <ClInclude Include="targetver.h" />
     <ClInclude Include="ToolUnits.h" />
@@ -267,6 +271,7 @@
     <ClCompile Include="Context.cpp" />
     <ClCompile Include="CPanel.cpp" />
     <ClCompile Include="CParam.cpp" />
+    <ClCompile Include="CProjectPageComponents.cpp" />
     <ClCompile Include="CRemoteEqUnitView.cpp" />
     <ClCompile Include="CRemoteEqView.cpp" />
     <ClCompile Include="CHomeDialog.cpp" />
@@ -279,6 +284,7 @@
     <ClCompile Include="DBManager\UserManager.cpp" />
     <ClCompile Include="EQState.cpp" />
     <ClCompile Include="EQStateMonitor.cpp" />
+    <ClCompile Include="GB2860SQLite.cpp" />
     <ClCompile Include="HmTab.cpp" />
     <ClCompile Include="HmVerticalTab.cpp" />
     <ClCompile Include="HorizontalLine.cpp" />
@@ -297,6 +303,9 @@
     <ClCompile Include="SetPage1.cpp" />
     <ClCompile Include="SetPage2.cpp" />
     <ClCompile Include="SettingsDlg.cpp" />
+    <ClCompile Include="sqlite3.c">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
+    </ClCompile>
     <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/BondEq/BondEqDlg.cpp b/SourceCode/Bond/BondEq/BondEqDlg.cpp
index 21722d8..c9a019f 100644
--- a/SourceCode/Bond/BondEq/BondEqDlg.cpp
+++ b/SourceCode/Bond/BondEq/BondEqDlg.cpp
@@ -9,13 +9,13 @@
 #include "Common.h"
 #include "CBonder.h"
 #include "SettingsDlg.h"
+#include "InputDialog.h"
 #include "LoginDlg.h"
 #include "ChangePasswordDlg.h"
-#include "InputDialog.h"
 #include "UserManagerDlg.h"
-
-// test
 #include "SystemLogManagerDlg.h"
+#include "AxisSettingsDlg.h"
+
 
 #ifdef _DEBUG
 #define new DEBUG_NEW
@@ -473,8 +473,14 @@
 
 void CBondEqDlg::OnMenuFileSettings()
 {
+	CAxisSettingsDlg axisDlg;
+	axisDlg.SetPLC(theApp.m_model.getBonder().getPLC("PLC(1)"));
+	axisDlg.DoModal();
+
+	/*
 	CSettingsDlg dlg;
 	dlg.DoModal();
+	*/
 }
 
 void CBondEqDlg::OnUpdateMenuFileSettings(CCmdUI* pCmdUI)
diff --git a/SourceCode/Bond/BondEq/CBonder.cpp b/SourceCode/Bond/BondEq/CBonder.cpp
index 9ed5f45..33ddc29 100644
--- a/SourceCode/Bond/BondEq/CBonder.cpp
+++ b/SourceCode/Bond/BondEq/CBonder.cpp
@@ -60,7 +60,6 @@
 {
 	m_listener.onStateChanged = listener.onStateChanged;
 	m_listener.onPlcStateChanged = listener.onPlcStateChanged;
-	m_listener.onCimStateChanged = listener.onCimStateChanged;
 	m_listener.onEfemStateChanged = listener.onEfemStateChanged;
 	m_listener.onRecvBroadcast = listener.onRecvBroadcast;
 }
@@ -68,6 +67,11 @@
 const std::vector<CComponent*>& CBonder::getComponents()
 {
 	return m_components;
+}
+
+CPLC* CBonder::getPLC(const char* pszName)
+{
+	return (CPLC*)GetComponent("PLC(1)");
 }
 
 int CBonder::save()
@@ -122,20 +126,12 @@
 {
 	// 机器状态
 	CEQStateMonitor* pEQStateMonitor1 = new CEQStateMonitor();
-	pEQStateMonitor1->setName("机器状态(A单元)");
-	pEQStateMonitor1->setDescription("A单机器状态");
+	pEQStateMonitor1->setName("机器状态");
+	pEQStateMonitor1->setDescription("机器状态");
 	pEQStateMonitor1->setIndex(0);
 	pEQStateMonitor1->setBeginAddr(4463 - 4400);
 	AddComponent(pEQStateMonitor1);
 	pEQStateMonitor1->init();
-
-	CEQStateMonitor* pEQStateMonitor2 = new CEQStateMonitor();
-	pEQStateMonitor2->setName("机器状态(B单元)");
-	pEQStateMonitor2->setDescription("B单机器状态");
-	pEQStateMonitor2->setIndex(1);
-	pEQStateMonitor2->setBeginAddr(4563 - 4500);
-	AddComponent(pEQStateMonitor2);
-	pEQStateMonitor2->init();
 
 
 	// 初始化各种组件
@@ -187,74 +183,39 @@
 	pPlc->setName("PLC(1)");
 	pPlc->setDescription("PLC");
 	pPlc->setIndex(0);
-	pPlc->init();
 	AddComponent(pPlc);
 
 
 	CDataMonitor1* pDataMonitor1 = new CDataMonitor1();
-	pDataMonitor1->setName("数据监控(A单元)");
-	pDataMonitor1->setDescription("A单元真空、压力和温度数据");
+	pDataMonitor1->setName("数据监控");
+	pDataMonitor1->setDescription("真空、压力和温度数据");
 	pDataMonitor1->setIndex(0);
 	pDataMonitor1->setResponseAddr(4425);
 	pDataMonitor1->enableAutoSendData(bAutoSendData);
 	AddComponent(pDataMonitor1);
 	pDataMonitor1->init();
 	
-	CDataMonitor1* pDataMonitor2 = new CDataMonitor1();
-	pDataMonitor2->setName("数据监控(B单元)");
-	pDataMonitor2->setDescription("B单元真空、压力和温度数据");
-	pDataMonitor2->setIndex(1);
-	pDataMonitor2->setResponseAddr(4525);
-	pDataMonitor2->enableAutoSendData(bAutoSendData);
-	AddComponent(pDataMonitor2);
-	pDataMonitor2->init();
-	
-
 
 	CString strAlarmFile;
 	strAlarmFile.Format(_T("%s\\AlarmList.txt"), m_strWorkDir.c_str());
 	CAlarmMonitor* pAlarmMonitor1 = new CAlarmMonitor();
-	pAlarmMonitor1->setName("警告信息(A单元)");
-	pAlarmMonitor1->setDescription("警告信息监控(A单元)");
+	pAlarmMonitor1->setName("警告信息");
+	pAlarmMonitor1->setDescription("警告信息监控");
 	pAlarmMonitor1->setBeginAddr(4461 - 4400);
 	pAlarmMonitor1->setIndex(0);
 	pAlarmMonitor1->readAlarmListFromFile((LPTSTR)(LPCTSTR)strAlarmFile);
 	AddComponent(pAlarmMonitor1);
 	pAlarmMonitor1->init();
 
-	CAlarmMonitor* pAlarmMonitor2 = new CAlarmMonitor();
-	pAlarmMonitor2->setName("警告信息(B单元)");
-	pAlarmMonitor2->setDescription("警告信息监控(B单元)");
-	pAlarmMonitor2->setBeginAddr(4561 - 4500);
-	pAlarmMonitor2->setIndex(1);
-	pAlarmMonitor2->readAlarmListFromFile((LPTSTR)(LPCTSTR)strAlarmFile);
-	AddComponent(pAlarmMonitor2);
-	pAlarmMonitor2->init();
 
 	// LoadMonitor
 	CLoadMonitor* pLoadMonitor1 = new CLoadMonitor();
-	pLoadMonitor1->setName("上下料(A单元)");
-	pLoadMonitor1->setDescription("上下料信号监控(A单元)");
+	pLoadMonitor1->setName("上下料");
+	pLoadMonitor1->setDescription("上下料信号监控");
 	pLoadMonitor1->setBeginAddr(4700);
 	pLoadMonitor1->setIndex(0);
 	AddComponent(pLoadMonitor1);
 	pLoadMonitor1->init();
-
-	CLoadMonitor* pLoadMonitor2 = new CLoadMonitor();
-	pLoadMonitor2->setName("上下料(B单元)");
-	pLoadMonitor2->setDescription("上下料信号监控(B单元)");
-	pLoadMonitor2->setBeginAddr(4700);
-	pLoadMonitor2->setIndex(1);
-	AddComponent(pLoadMonitor2);
-	pLoadMonitor2->init();
-
-	CLoadMonitor* pLoadMonitor3 = new CLoadMonitor();
-	pLoadMonitor3->setName("上下料(冷却箱)");
-	pLoadMonitor3->setDescription("上下料信号监控(冷却箱)");
-	pLoadMonitor3->setBeginAddr(4700);
-	pLoadMonitor3->setIndex(2);
-	AddComponent(pLoadMonitor3);
-	pLoadMonitor3->init();
 
 
 	// BEQ与EFEM通讯
@@ -289,10 +250,7 @@
 	};
 	m_pEquipment->setEquipmentListener(equListener);
 	m_pEquipment->setVersion(m_strSoftRev.c_str());
-	m_pEquipment->addUnit(UNITA, 5);
-	m_pEquipment->addUnit(UNITB, 5);
-	BEQ::IUnit* pUnitC = m_pEquipment->addUnit(UNITC, 1);
-	pUnitC->setLayerCount(4);
+	m_pEquipment->addUnit(UNIT1, 5);
 	m_pEquipment->runOnServerMode(8192);
 
 
@@ -449,6 +407,17 @@
 		item->OnTimer(nTimerid);
 	}
 
+
+	// PLC延时连接
+	static int nPlc = 0;
+	nPlc++;
+	if (nPlc == 3) {
+		CPLC* pPLC = (CPLC*)GetComponent("PLC(1)");
+		pPLC->init();
+	}
+
+
+	// 自动保存
 	static int iii = 0;
 	iii++;
 	if (iii % 5 == 0) {
@@ -563,11 +532,7 @@
 BEQ::IUnit* CBonder::getUnit(int index)
 {
 	if (index == 0)
-		return m_pEquipment->getUnit(UNITA);
-	if (index == 1)
-		return m_pEquipment->getUnit(UNITB);
-	if (index == 2)
-		return m_pEquipment->getUnit(UNITC);
+		return m_pEquipment->getUnit(UNIT1);
 
 	return nullptr;
 }
@@ -784,24 +749,14 @@
 	}
 
 
-	// 单元C为水冷塔,不需要写
-	if (strcmp(szUnitName, UNITC) == 0) {
-		return 0;
-	}
-
-
 	// 如果是单元A或单元B, 写物料ID和配方ID到PLC
 	CLoadMonitor* pLoadMonitor = nullptr;
-	if (strcmp(szUnitName, UNITA) == 0) {
+	if (strcmp(szUnitName, UNIT1) == 0) {
 
-		pLoadMonitor = (CLoadMonitor*)GetComponent("上下料(A单元)");
+		pLoadMonitor = (CLoadMonitor*)GetComponent("上下料");
 		return pLoadMonitor->loadReady(pszMaterielId, pszRecipeId);
 	}
-	else if (strcmp(szUnitName, UNITB) == 0) {
 
-		pLoadMonitor = (CLoadMonitor*)GetComponent("上下料(B单元)");
-		return pLoadMonitor->loadReady(pszMaterielId, pszRecipeId);
-	}
 
 	return -2;
 }
@@ -817,7 +772,7 @@
 	if (!pPLC->isConnected()) {
 		return -1;
 	}
-	if (layer <= 0 || layer > 4) {
+	if (layer <= 0 || layer > 1) {
 		return -2;
 	}
 
@@ -860,36 +815,10 @@
 
 	// 写
 	int index, nFlagAddr;
-	if (strcmp(szUnitName, UNITA) == 0) {
+	if (strcmp(szUnitName, UNIT1) == 0) {
 		index = 0;
 		nFlagAddr = 4710;
 		szBuffer[index * 2] |= 0x02;
-	}
-	else if (strcmp(szUnitName, UNITB) == 0) {
-		index = 1;
-		nFlagAddr = 4711;
-		szBuffer[index * 2] |= 0x02;
-	}
-	else if (strcmp(szUnitName, UNITC) == 0) {
-		index = 2;
-		nFlagAddr = 4712;
-		switch (layer)
-		{
-		case 1:
-			szBuffer[index * 2] |= 0x01;
-			break;
-		case 2:
-			szBuffer[index * 2] |= 0x02;
-			break;
-		case 3:
-			szBuffer[index * 2] |= 0x04;
-			break;
-		case 4:
-			szBuffer[index * 2] |= 0x08;
-			break;
-		default:
-			break;
-		}
 	}
 
 
@@ -970,36 +899,10 @@
 
 	// 写
 	int index, nFlagAddr;
-	if (strcmp(szUnitName, UNITA) == 0) {
+	if (strcmp(szUnitName, UNIT1) == 0) {
 		index = 0;
 		nFlagAddr = 4710;
 		szBuffer[index * 2 + 1] |= 0x02;
-	}
-	else if (strcmp(szUnitName, UNITB) == 0) {
-		index = 1;
-		nFlagAddr = 4711;
-		szBuffer[index * 2 + 1] |= 0x02;
-	}
-	else if (strcmp(szUnitName, UNITC) == 0) {
-		index = 2;
-		nFlagAddr = 4712;
-		switch (layer)
-		{
-		case 1:
-			szBuffer[index * 2] |= 0x20;
-			break;
-		case 2:
-			szBuffer[index * 2] |= 0x40;
-			break;
-		case 3:
-			szBuffer[index * 2] |= 0x80;
-			break;
-		case 4:
-			szBuffer[index * 2 + 1] |= 0x01;
-			break;
-		default:
-			break;
-		}
 	}
 
 
diff --git a/SourceCode/Bond/BondEq/CBonder.h b/SourceCode/Bond/BondEq/CBonder.h
index 295cac7..c932b47 100644
--- a/SourceCode/Bond/BondEq/CBonder.h
+++ b/SourceCode/Bond/BondEq/CBonder.h
@@ -20,7 +20,6 @@
 
 typedef std::function<void(void* pFrom, int)> ONBONDSTATECHANGED;
 typedef std::function<void(void* pFrom, int)> ONPLCSTATECHANGED;
-typedef std::function<void(void* pFrom, int)> ONCIMSTATECHANGED;
 typedef std::function<void(void* pFrom, const char* pszAddr, int port, int)> ONEFEMSTATECHANGED;
 typedef std::function<void(void* pFrom, void*)> ONRECVBROADCAST;
 
@@ -28,7 +27,6 @@
 {
 	ONBONDSTATECHANGED		onStateChanged;
 	ONPLCSTATECHANGED		onPlcStateChanged;
-	ONCIMSTATECHANGED		onCimStateChanged;
 	ONEFEMSTATECHANGED		onEfemStateChanged;
 	ONRECVBROADCAST			onRecvBroadcast;
 } BondListener;
@@ -44,6 +42,7 @@
 	void setListener(BondListener& listener);
 	void setWorkDir(const char* pszWorkDir);
 	const std::vector<CComponent*>& getComponents();
+	CPLC* getPLC(const char* pszName);
 	int init();
 	int term();
 	void sendBroadcast(CComponent* pSender, CIntent* pIntent);
diff --git a/SourceCode/Bond/BondEq/CPLC.cpp b/SourceCode/Bond/BondEq/CPLC.cpp
index 9b1584c..7a7afcf 100644
--- a/SourceCode/Bond/BondEq/CPLC.cpp
+++ b/SourceCode/Bond/BondEq/CPLC.cpp
@@ -308,7 +308,7 @@
 	static int iii = 0;
 	iii++;
 	if (iii % 5 == 3) {
-		if (!m_pChannel->isConnected())
+		if (m_pChannel != nullptr && !m_pChannel->isConnected())
 			m_pChannel->connect();
 	}
 }
\ No newline at end of file
diff --git a/SourceCode/Bond/BondEq/CPanelProject.cpp b/SourceCode/Bond/BondEq/CPanelProject.cpp
index 92cf9e9..0aa4518 100644
--- a/SourceCode/Bond/BondEq/CPanelProject.cpp
+++ b/SourceCode/Bond/BondEq/CPanelProject.cpp
@@ -19,6 +19,7 @@
 	m_nPanelWidth = int((double)GetSystemMetrics(SM_CXSCREEN) * 0.25);
 	m_pAccordionWnd = nullptr;
 	m_pPageRemoteEqs = nullptr;
+	m_pPageComponents = nullptr;
 }
 
 CPanelProject::~CPanelProject()
@@ -75,6 +76,10 @@
 	m_pPageRemoteEqs->ShowWindow(SW_SHOW);
 	m_pAccordionWnd->AddItem("杩滅▼璁惧", m_pPageRemoteEqs, 0, TRUE, TRUE);
 	
+	m_pPageComponents = new CProjectPageComponents();
+	m_pPageComponents->Create(IDD_PROJECT_PAGE_COMPONENTS, GetDlgItem(IDC_ACCORDION_WND1));
+	m_pPageComponents->ShowWindow(SW_SHOW);
+	m_pAccordionWnd->AddItem("缁勪欢鍒楄〃", m_pPageComponents, -1, TRUE, TRUE);
 
 	return TRUE;  // return TRUE unless you set the focus to a control
 				  // 寮傚父: OCX 灞炴�ч〉搴旇繑鍥� FALSE
@@ -110,6 +115,12 @@
 		::DeleteObject(m_hbrBkgnd);
 	}
 
+	if (m_pPageComponents != nullptr) {
+		m_pPageComponents->DestroyWindow();
+		delete m_pPageComponents;
+		m_pPageComponents = nullptr;
+	}
+
 	if (m_pPageRemoteEqs != nullptr) {
 		m_pPageRemoteEqs->DestroyWindow();
 		delete m_pPageRemoteEqs;
diff --git a/SourceCode/Bond/BondEq/CPanelProject.h b/SourceCode/Bond/BondEq/CPanelProject.h
index d62a58b..3b3f7f6 100644
--- a/SourceCode/Bond/BondEq/CPanelProject.h
+++ b/SourceCode/Bond/BondEq/CPanelProject.h
@@ -1,6 +1,7 @@
 锘�#pragma once
 #include "VerticalLine.h"
 #include "CProjectPageRemoteEqs.h"
+#include "CProjectPageComponents.h"
 #include "AccordionWnd.h"
 
 
@@ -29,6 +30,7 @@
 	int m_nPanelWidth;
 	CAccordionWnd* m_pAccordionWnd;
 	CProjectPageRemoteEqs* m_pPageRemoteEqs;
+	CProjectPageComponents* m_pPageComponents;
 
 
 // 瀵硅瘽妗嗘暟鎹�
diff --git a/SourceCode/Bond/BondEq/Common.h b/SourceCode/Bond/BondEq/Common.h
index d37499f..6cc098b 100644
--- a/SourceCode/Bond/BondEq/Common.h
+++ b/SourceCode/Bond/BondEq/Common.h
@@ -4,9 +4,7 @@
 #define MC_TIME_SEPAR				1000
 
 
-#define UNITA			_T("UNITA")
-#define UNITB			_T("UNITB")
-#define UNITC			_T("C")
+#define UNIT1			_T("UNIT1")
 
 
 /* Context Ret code */
@@ -20,7 +18,6 @@
 #define RX_CODE_TEST					0
 #define RX_CODE_LOG						1000
 #define RX_CODE_BONDER_STATE_CHANGED	1001
-#define RX_CODE_PASSIVE_STATUS_CHANGED	1002
 #define RX_CODE_PLC1_CONNECTTD			1003
 #define RX_CODE_PLC1_DISCONNECTTD		1004
 #define RX_CODE_SELECT_EQ				1005
@@ -33,7 +30,8 @@
 #define RX_CODE_ALARM_EVENT				1012
 #define RX_CODE_EQSTATE_EVENT			1013
 #define RX_CODE_EFEM_STATUS_CHANGED		1014
-#define RX_CODE_EQ_STATE_CHANGED	1015
+#define RX_CODE_EQ_STATE_CHANGED		1015
+#define RX_CODE_SELECT_COMPONENT		1016
 
 /* 广播代码 */
 #define BC_CODE_DATA1_MATERIAL_RECEIVED	5000
diff --git a/SourceCode/Bond/BondEq/Model.cpp b/SourceCode/Bond/BondEq/Model.cpp
index 30fd949..2a41c86 100644
--- a/SourceCode/Bond/BondEq/Model.cpp
+++ b/SourceCode/Bond/BondEq/Model.cpp
@@ -4,6 +4,8 @@
 #include "Model.h"
 #include "Log.h"
 #include "ToolUnits.h"
+#include "Alarm.h"
+#include "EQState.h"
 
 
 CModel* g_pModel = NULL;
@@ -36,6 +38,7 @@
 void CModel::setWorkDir(const char* pszWorkDir)
 {
 	m_strWorkDir = pszWorkDir;
+	m_bonder.setWorkDir(pszWorkDir);
 }
 
 int CModel::init()
@@ -74,24 +77,24 @@
 	LOGI("\r\n\r\n~~~ Prog Start! ~~~");
 
 
-	// 创建Servo
+	// ??Servo
 	BEQ_CreateEquipment(m_pEquipment, "BLBonder");
 	ASSERT(m_pEquipment);
 	BEQ::EquipmentListener listener;
 	listener.onConnected = [&](void* pEiuipment, const char* pszAddr, int port) -> void {
-		LOGI("<EquipmentListener>连接进入(%s:%d).", pszAddr, port);
+		LOGI("<EquipmentListener>????(%s:%d).", pszAddr, port);
 		notifyPtr(RX_CODE_EQ_STATE_CHANGED, pEiuipment);
 	};
 	listener.onDisconnected = [&](void* pEiuipment, const char* pszAddr, int port) -> void {
-		LOGI("<EquipmentListener>连接断开(%s:%d).", pszAddr, port);
+		LOGI("<EquipmentListener>????(%s:%d).", pszAddr, port);
 		notifyPtr(RX_CODE_EQ_STATE_CHANGED, pEiuipment);
 	};
-	// 注意此处还有几个回调函数未处理
+	// ???????????????
 	m_pEquipment->setEquipmentListener(listener);
 
 
 	m_pObservable = RX_AllocaObservable([&](IObservableEmitter* e) -> void {
-		m_pObservableEmitter = e;			// 保存发射器
+		m_pObservableEmitter = e;			// ?????
 	});
 
 
@@ -99,11 +102,85 @@
 	g_pModel = this;
 
 
+	BondListener bonderListener;
+	bonderListener.onStateChanged = [&](void* pFrom, int state) -> void {
+		notifyInt(RX_CODE_BONDER_STATE_CHANGED, state);
+	};
+	bonderListener.onPlcStateChanged = [&](void* pFrom, int state) -> void {
+		PLCSTATE ps = (PLCSTATE)state;
+		if (ps == PLCSTATE::CONNECTED) {
+			notifyPtrAndInt(RX_CODE_PLC1_CONNECTTD, pFrom, 0, state);
+		}
+		else if (ps == PLCSTATE::DISCONNECTED) {
+			notifyPtrAndInt(RX_CODE_PLC1_DISCONNECTTD, pFrom, 0, state);
+		}
+	};
+	bonderListener.onEfemStateChanged = [&](void* pFrom, const char* pszAddr, int port, int state) -> void {
+		if (m_pObservableEmitter != NULL) {
+			IAny* pAny = RX_AllocaAny();
+			if (pAny != NULL) {
+				pAny->addRef();
+				pAny->setCode(RX_CODE_EFEM_STATUS_CHANGED);
+				pAny->setStringValue("addr", pszAddr);
+				pAny->setIntValue("port", port);
+				pAny->setIntValue("state", state);
+				m_pObservableEmitter->onNext(pAny);
+				pAny->release();
+			}
+		}
+	};
+	bonderListener.onRecvBroadcast = [&](void* pFrom, void* p) -> void {
+		CComponent* pSender = (CComponent*)pFrom;
+		CIntent* pIntent = (CIntent*)p;
+		int code = pIntent->getCode();
+		if (code == BC_CODE_DATA1_MATERIAL_RECEIVED) {
+			notifyPtr(RX_CODE_DATA1_MATERIAL_RECEIVED, pSender);
+		}
+		else if (code == BC_CODE_DATA1_BEGIN_SAMPLING) {
+			notifyPtr(RX_CODE_DATA1_BEGIN_SAMPLING, pSender);
+		}
+		else if (code == BC_CODE_DATA1_UPDATE) {
+			notifyPtr(RX_CODE_DATA1_UPDATE, pSender);
+		}
+		else if (code == BC_CODE_DATA1_END_SAMPLING) {
+			notifyPtr(RX_CODE_DATA1_END_SAMPLING, pSender);
+		}
+		else if (code == BC_CODE_DATA1_MATERIAL_REMOVED) {
+			std::string strError;
+			CPanel* pPanel = (CPanel*)pIntent->getContext();
+			pPanel->addRef();
+			savePanel(pPanel, pSender);
+			m_sqlite.insertPanel(pPanel, strError);
+			notifyPtr(RX_CODE_DATA1_MATERIAL_REMOVEED, pSender);
+			notifyObj(RX_CODE_PANEL_COMPLATE, pPanel);
+			pPanel->release();
+		}
+		else if (code == BC_CODE_ALARM_EVENT) {
+			CAlarm* pAlarm = (CAlarm*)pIntent->getContext();
+			pAlarm->addRef();
+			notifyObjAndPtr(RX_CODE_ALARM_EVENT, pAlarm, pSender);
+			pAlarm->release();
+		}
+		else if (code == BC_CODE_EQSTATE_EVENT) {
+			CEQState* pState = (CEQState*)pIntent->getContext();
+			pState->addRef();
+			notifyObjAndPtr(RX_CODE_EQSTATE_EVENT, pState, pSender);
+			pState->release();
+		}
+	};
+	m_bonder.setListener(bonderListener);
+	m_bonder.init();
+
+
 	return 0;
 }
 
 int CModel::term()
 {
+	m_bonder.save();
+	m_bonder.term();
+	m_sqlite.term();
+
 	CLog::GetLog()->SetOnLogCallback(nullptr);
 	return 0;
 }
@@ -293,4 +370,113 @@
 void CModel::onTimer(UINT nTimerid)
 {
 
-}
\ No newline at end of file
+}
+
+int CModel::savePanel(CPanel* pPanel, CComponent* pComponent)
+{
+	int year, month, day;
+	pPanel->getReceivedTime(year, month, day);
+	CString strDir, strFilepath;
+	strDir.Format("%s\\%d\\%d\\%d", (LPTSTR)(LPCTSTR)m_strDataDir, year, month, day);
+	CToolUnits::createDir((LPTSTR)(LPCTSTR)strDir);
+	strFilepath.Format("%s\\%s.csv", (LPTSTR)(LPCTSTR)strDir, pPanel->getQRCode().c_str());
+
+	CStdioFile file;
+	if (!file.Open(strFilepath, CFile::modeCreate | CFile::modeWrite)) {
+		return -1;
+	}
+
+	// ????
+	// ??, id,??????,??????
+	CString strLine;
+	file.WriteString("# ??\n");
+	strLine.Format(_T("??,%s\n"), pComponent->getName().c_str());
+	file.WriteString(strLine);
+	strLine.Format(_T("id,%s\n"), pPanel->getQRCode().c_str());
+	file.WriteString(strLine);
+	strLine.Format(_T("????,%s\n"),
+		CToolUnits::timeToString3(pPanel->getReceivedTime()).c_str());
+	file.WriteString(strLine);
+	strLine.Format(_T("??????,%s\n"),
+		CToolUnits::timeToString3(pPanel->getBeginSamplingTime()).c_str());
+	file.WriteString(strLine);
+	strLine.Format(_T("??????,%s\n"),
+		CToolUnits::timeToString3(pPanel->getEndSamplingTime()).c_str());
+	file.WriteString(strLine);
+	strLine.Format(_T("????,%s\n"),
+		CToolUnits::timeToString3(pPanel->getRemovedTime()).c_str());
+	file.WriteString(strLine);
+	strLine.Format(_T("Recipe name,%s\n"), pPanel->getRecipeName().c_str());
+	file.WriteString(strLine);
+	strLine.Format(_T("??????,%f\n"), pPanel->getAir1());
+	file.WriteString(strLine);
+	strLine.Format(_T("???????,%f\n"), pPanel->getAir2());
+	file.WriteString(strLine);
+	strLine.Format(_T("?????,%f\n"), pPanel->getAir3());
+	file.WriteString(strLine);
+	strLine.Format(_T("?????,%d\n"), pPanel->getPre1());
+	file.WriteString(strLine);
+	strLine.Format(_T("?????,%f\n"), pPanel->getTmp1());
+	file.WriteString(strLine);
+	strLine.Format(_T("?????,%f\n"), pPanel->getTmp2());
+	file.WriteString(strLine);
+	file.WriteString("\n");
+
+
+	// ???
+	file.WriteString("# ??\n");
+	file.WriteString("?,?????(?),?????(?),?????1(?),?????2(?),?????3(?),?????4(?),?????5(?),?????1(?),?????2(?),?????3(?),?????4(?),?????5(?),????(Pa),????1(Kg),????2(Kg),????3(Kg),????4(Kg),????5(Kg)\n");
+	UNITDATA1 dataMax = pPanel->getMathData(IMAX);
+	strLine.Format(_T("???,%.01f,%.01f,%.01f,%.01f,%.01f,%.01f,%.01f,%.01f,%.01f,%.01f,%.03f,%.01f,%.01f,%.01f,%.01f,%.01f,%.01f,%.01f\n"),
+		dataMax.temp[0], dataMax.temp[1],
+		dataMax.temp[2], dataMax.temp[3], dataMax.temp[4], dataMax.temp[5], dataMax.temp[6],
+		dataMax.temp[7], dataMax.temp[8], dataMax.temp[9], dataMax.temp[10], dataMax.temp[11],
+		dataMax.vacuum,
+		dataMax.pressure[0], dataMax.pressure[1], dataMax.pressure[2],
+		dataMax.pressure[3], dataMax.pressure[4]);
+	file.WriteString(strLine);
+
+	UNITDATA1 dataMin = pPanel->getMathData(IMIN);
+	strLine.Format(_T("???,%.01f,%.01f,%.01f,%.01f,%.01f,%.01f,%.01f,%.01f,%.01f,%.01f,%.03f,%.01f,%.01f,%.01f,%.01f,%.01f,%.01f,%.01f\n"),
+		dataMin.temp[0], dataMin.temp[1],
+		dataMin.temp[2], dataMin.temp[3], dataMin.temp[4], dataMin.temp[5], dataMin.temp[6],
+		dataMin.temp[7], dataMin.temp[8], dataMin.temp[9], dataMin.temp[10], dataMin.temp[11],
+		dataMin.vacuum,
+		dataMin.pressure[0], dataMin.pressure[1], dataMin.pressure[2],
+		dataMin.pressure[3], dataMin.pressure[4]);
+	file.WriteString(strLine);
+
+	UNITDATA1 dataAve = pPanel->getMathData(IAVE);
+	strLine.Format(_T("???,%.01f,%.01f,%.01f,%.01f,%.01f,%.01f,%.01f,%.01f,%.01f,%.01f,%.03f,%.01f,%.01f,%.01f,%.01f,%.01f,%.01f,%.01f\n"),
+		dataAve.temp[0], dataAve.temp[1],
+		dataAve.temp[2], dataAve.temp[3], dataAve.temp[4], dataAve.temp[5], dataAve.temp[6],
+		dataAve.temp[7], dataAve.temp[8], dataAve.temp[9], dataAve.temp[10], dataAve.temp[11],
+		dataAve.vacuum,
+		dataAve.pressure[0], dataAve.pressure[1], dataAve.pressure[2],
+		dataAve.pressure[3], dataAve.pressure[4]);
+	file.WriteString(strLine);
+	file.WriteString("\n");
+
+
+	// ???
+	file.WriteString("# ???\n");
+	file.WriteString("??,?????(?),?????(?),?????1(?),?????2(?),?????3(?),?????4(?),?????5(?),?????1(?),?????2(?),?????3(?),?????4(?),?????5(?),????(Pa),????1(Kg),????2(Kg),????3(Kg),????4(Kg),????5(Kg)\n");
+	std::vector<UNITDATA1> datas;
+	pPanel->getDatas(datas);
+	for (auto item : datas) {
+		strLine.Format(_T("%s,%.01f,%.01f,%.01f,%.01f,%.01f,%.01f,%.01f,%.01f,%.01f,%.01f,%.03f,%.01f,%.01f,%.01f,%.01f,%.01f,%.01f,%.01f\n"),
+			CToolUnits::timeToString3(item.time).c_str(),
+			item.temp[0], item.temp[1],
+			item.temp[2], item.temp[3], item.temp[4], item.temp[5], item.temp[6],
+			item.temp[7], item.temp[8], item.temp[9], item.temp[10], item.temp[11],
+			item.vacuum,
+			item.pressure[0], item.pressure[1], item.pressure[2],
+			item.pressure[3], item.pressure[4]);
+		file.WriteString(strLine);
+	}
+
+
+	file.Close();
+
+	return 0;
+}
diff --git a/SourceCode/Bond/BondEq/Model.h b/SourceCode/Bond/BondEq/Model.h
index 0feb0c9..1d243a3 100644
--- a/SourceCode/Bond/BondEq/Model.h
+++ b/SourceCode/Bond/BondEq/Model.h
@@ -1,6 +1,8 @@
 #pragma once
 #include "CBonder.h"
 #include "Configuration.h"
+#include "CPanel.h"
+#include "GB2860SQLite.h"
 
 
 class CModel
@@ -30,6 +32,9 @@
 	int notifyTextAndInt(int code, const char* pszText, int exCode);
 	int notifyMesMsg(int code, int stream, int function, const char* pszText);
 
+private:
+	int savePanel(CPanel* pPanel, CComponent* pComponent);
+
 public:
 	CConfiguration m_configuration;
 
@@ -44,5 +49,6 @@
 	CBonder m_bonder;
 	BEQ::IEquipment* m_pEquipment;
 	int m_nTimerID;
+	CGB2860SQLite m_sqlite;
 };
 
diff --git a/SourceCode/Bond/BondEq/Resource.h b/SourceCode/Bond/BondEq/Resource.h
index 2dca32a..40c8681 100644
--- a/SourceCode/Bond/BondEq/Resource.h
+++ b/SourceCode/Bond/BondEq/Resource.h
Binary files differ
diff --git a/SourceCode/Bond/BondEq/ToolUnits.cpp b/SourceCode/Bond/BondEq/ToolUnits.cpp
index fecc6c1..3c65c30 100644
--- a/SourceCode/Bond/BondEq/ToolUnits.cpp
+++ b/SourceCode/Bond/BondEq/ToolUnits.cpp
@@ -145,3 +145,20 @@
 	DWORD attributes = GetFileAttributes(path.c_str());
 	return (attributes != INVALID_FILE_ATTRIBUTES && (attributes & FILE_ATTRIBUTE_DIRECTORY));
 }
+
+double CToolUnits::toInt32(const char* pBuffer)
+{
+	return (pBuffer[0] & 0xff) | (pBuffer[1] & 0xff) << 8 | (pBuffer[2] & 0xff) << 16 | (pBuffer[3] & 0xff) << 24;
+}
+
+double CToolUnits::toInt16(const char* pBuffer)
+{
+	return (pBuffer[0] & 0xff) | (pBuffer[1] & 0xff) << 8;
+}
+
+void CToolUnits::setDlgItemDouble(CWnd* pWnd, int nCtrlId, double value)
+{
+	CString strText;
+	strText.Format(_T("%.03f"), value);
+	pWnd->SetDlgItemText(nCtrlId, strText);
+}
diff --git a/SourceCode/Bond/BondEq/ToolUnits.h b/SourceCode/Bond/BondEq/ToolUnits.h
index 3dfc929..167cf0e 100644
--- a/SourceCode/Bond/BondEq/ToolUnits.h
+++ b/SourceCode/Bond/BondEq/ToolUnits.h
@@ -20,5 +20,8 @@
 	static std::string getCurrentExePath();
 	static bool isFile(const std::string& path);
 	static bool isDirectory(const std::string& path);
+	static double toInt32(const char* pBuffer);
+	static double toInt16(const char* pBuffer);
+	static void setDlgItemDouble(CWnd* pWnd, int nCtrlId, double value);
 };
 
diff --git a/SourceCode/Bond/BondEq/View/AxisSettingsDlg.cpp b/SourceCode/Bond/BondEq/View/AxisSettingsDlg.cpp
index d12c269..e83a616 100644
--- a/SourceCode/Bond/BondEq/View/AxisSettingsDlg.cpp
+++ b/SourceCode/Bond/BondEq/View/AxisSettingsDlg.cpp
@@ -5,7 +5,10 @@
 #include "BondEq.h"
 #include "afxdialogex.h"
 #include "AxisSettingsDlg.h"
+#include "ToolUnits.h"
 
+#define TIMER_INIT				1
+#define TIMER_READ_PLC_DATA		2
 
 // CAxisSettingsDlg 瀵硅瘽妗�
 
@@ -16,6 +19,7 @@
 {
 	m_nInitialWidth = 0;
 	m_nInitialHeight = 0;
+	m_pPLC = nullptr;
 }
 
 CAxisSettingsDlg::~CAxisSettingsDlg()
@@ -29,9 +33,21 @@
 	m_mapFonts.clear();
 }
 
+void CAxisSettingsDlg::SetPLC(CPLC* pPLC)
+{
+	ASSERT(pPLC);
+	m_pPLC = pPLC;
+}
+
 void CAxisSettingsDlg::DoDataExchange(CDataExchange* pDX)
 {
 	CDialogEx::DoDataExchange(pDX);
+	DDX_Control(pDX, IDC_STATIC_AXIS_TEST_FLS, m_staticFLS);
+	DDX_Control(pDX, IDC_STATIC_AXIS_TEST_DOG, m_staticDOG);
+	DDX_Control(pDX, IDC_STATIC_AXIS_TEST_RLS, m_staticRLS);
+	DDX_Control(pDX, IDC_STATIC_AXIS_TEST_READY, m_staticReady);
+	DDX_Control(pDX, IDC_STATIC_AXIS_TEST_BUSY, m_staticBusy);
+	DDX_Control(pDX, IDC_STATIC_AXIS_TEST_ERR, m_staticErr);
 }
 
 CFont* CAxisSettingsDlg::GetOrCreateFont(int nFontSize)
@@ -98,12 +114,45 @@
 	// 鏍规嵁鎺т欢楂樺害鍔ㄦ�佽皟鏁村瓧浣撳ぇ灏�
 	int fontSize = nHeight / 2;
 	if (fontSize < 8) fontSize = 8;
+	if (fontSize > 24) fontSize = 24;  // 鏈�澶у瓧浣撳ぇ灏�
 
 	// 鑾峰彇鎴栧垱寤哄瓧浣�
 	CFont* pFont = GetOrCreateFont(fontSize);
 
 	pWnd->SetFont(pFont);
 	pWnd->Invalidate(); // 鍒锋柊鎺т欢鏄剧ず
+}
+
+void CAxisSettingsDlg::AdjustLabelFont(CBLLabel& label)
+{
+	// 鑾峰彇鎺т欢鐨勭煩褰㈠尯鍩�
+	CRect rect;
+	label.GetClientRect(&rect);
+
+	// 鍔ㄦ�佽绠楀瓧浣撳ぇ灏忥紝鍩轰簬鎺т欢鐨勯珮搴�
+	int fontSize = rect.Height() / 2; // 鎺т欢楂樺害鐨勪竴鍗婁綔涓哄瓧浣撳ぇ灏�
+	if (fontSize < 8) fontSize = 8;   // 鏈�灏忓瓧浣撳ぇ灏�
+	if (fontSize > 30) fontSize = 30; // 鏈�澶у瓧浣撳ぇ灏�
+
+	// 璁剧疆瀛椾綋澶у皬
+	label.SetFontSize(fontSize);
+
+	// 鍒锋柊鎺т欢鏄剧ず
+	label.Invalidate();
+	label.UpdateWindow();
+}
+
+void CAxisSettingsDlg::SetStatusColor(CBLLabel& label, BOOL bStatus)
+{
+	if (bStatus) {
+		label.SetBkColor(RGB(0, 255, 0)); // 缁胯壊
+	}
+	else {
+		label.SetBkColor(RGB(255, 0, 0)); // 绾㈣壊
+	}
+
+	label.Invalidate();              // 鏍囪鍖哄煙鏃犳晥
+	label.UpdateWindow();            // 绔嬪嵆鍒锋柊
 }
 
 
@@ -127,6 +176,7 @@
 	ON_WM_SIZE()
 	ON_WM_CTLCOLOR()
 	ON_WM_SIZING()
+	ON_WM_TIMER()
 END_MESSAGE_MAP()
 
 
@@ -138,6 +188,18 @@
 	CDialogEx::OnInitDialog();
 
 	// TODO:  鍦ㄦ娣诲姞棰濆鐨勫垵濮嬪寲
+	SetWindowText(_T("Axis璁惧畾"));
+
+	// 璁剧疆娴嬭瘯鐘舵��
+	CBLLabel* pLabels[] = { &m_staticFLS, &m_staticDOG, &m_staticRLS, &m_staticReady, &m_staticBusy, &m_staticErr };
+	for (auto pLabel : pLabels) {
+		SetStatusColor(*pLabel, FALSE);
+		pLabel->ModifyStyle(0, SS_NOTIFY);
+		pLabel->SetTextColor(RGB(255, 255, 255));
+		pLabel->SetAlignment(AlignCenter);
+		pLabel->SetDynamicFont(TRUE);
+	}
+
 	CRect screenRect, dlgRect, clientRect;
 	GetClientRect(&clientRect);
 	m_nInitialWidth = clientRect.Width();
@@ -178,6 +240,8 @@
 	int centerX = screenRect.left + (screenRect.Width() - dlgWidth) / 2;
 	int centerY = screenRect.top + (screenRect.Height() - dlgHeight) / 2;
 	MoveWindow(centerX, centerY, dlgWidth, dlgHeight);
+	
+	SetTimer(TIMER_READ_PLC_DATA, 500, nullptr);
 
 	return TRUE;  // return TRUE unless you set the focus to a control
 	// 寮傚父: OCX 灞炴�ч〉搴旇繑鍥� FALSE
@@ -188,11 +252,21 @@
 	CDialogEx::OnSize(nType, cx, cy);
 
 	// TODO: 鍦ㄦ澶勬坊鍔犳秷鎭鐞嗙▼搴忎唬鐮�
-	CRect rect;
-	GetClientRect(&rect);
+	if (nType == SIZE_MINIMIZED || m_mapCtrlLayouts.empty()) {
+		return;
+	}
+
+	float dScaleX = static_cast<float>(cx) / m_nInitialWidth;
+	float dScaleY = static_cast<float>(cy) / m_nInitialHeight;
 
 	// 閬嶅巻瀵硅瘽妗嗕腑鐨勬墍鏈夋帶浠�
-	AdjustControls(rect.Width(), rect.Height());
+	AdjustControls(dScaleX, dScaleY);
+
+	// 鍔ㄦ�佽皟鏁村悇涓� CBLLabel 鐨勫瓧浣撳ぇ灏�
+	CBLLabel* pLabels[] = { &m_staticFLS, &m_staticDOG, &m_staticRLS, &m_staticReady, &m_staticBusy, &m_staticErr };
+	for (auto pLabel : pLabels) {
+		AdjustLabelFont(*pLabel);
+	}
 }
 
 void CAxisSettingsDlg::OnSizing(UINT fwSide, LPRECT pRect)
@@ -297,4 +371,37 @@
 void CAxisSettingsDlg::OnBnClickedButtonAxisTestStop()
 {
 	// TODO: 鍦ㄦ娣诲姞鎺т欢閫氱煡澶勭悊绋嬪簭浠g爜
-}
\ No newline at end of file
+}
+
+void CAxisSettingsDlg::OnTimer(UINT_PTR nIDEvent)
+{
+	if (TIMER_READ_PLC_DATA == nIDEvent) {
+		ASSERT(m_pPLC);
+
+		int addr1, addr2, readSize;
+		addr1 = 5120;
+		addr2 = 5425;
+		readSize = (addr2 - addr1 + 1) * 2;
+		auto funOnReadData = [&, addr1, readSize](IMcChannel* pChannel, int addr, char* pData, unsigned int nDataSize, int flag) -> void {
+			if (nDataSize == readSize && flag == 0) {
+				double fCurPos = CToolUnits::toInt32(pData) * 0.001;
+				double fManualSpeed = CToolUnits::toInt32(&pData[(5422- addr1)*2]) * 0.001;
+				double fAutoSpeed = CToolUnits::toInt32(&pData[(5424 - addr1) * 2]) * 0.001;
+				double fPrm = CToolUnits::toInt32(&pData[(5150 - addr1) * 2]) * 0.1;
+				int nLoad = CToolUnits::toInt16(&pData[(5154 - addr1) * 2]);
+				int nErrCode = CToolUnits::toInt16(&pData[(5126 - addr1) * 2]);
+				int nAlarmCode = CToolUnits::toInt16(&pData[(5127 - addr1) * 2]);
+				CToolUnits::setDlgItemDouble(this, IDC_EDIT_AXIS_CURR_POS, fCurPos);
+				CToolUnits::setDlgItemDouble(this, IDC_EDIT_AXIS_CURR_MANUAL_SPEED, fManualSpeed);
+				CToolUnits::setDlgItemDouble(this, IDC_EDIT_AXIS_CURR_AUTO_SPEED, fAutoSpeed);
+				CToolUnits::setDlgItemDouble(this, IDC_EDIT_AXIS_CURR_ROTA_SPEED, fPrm);
+				SetDlgItemInt(IDC_EDIT_AXIS_CURR_LOAD, nLoad);
+				SetDlgItemInt(IDC_EDIT_AXIS_CURR_ERROR_NUMBER, nErrCode);
+				SetDlgItemInt(IDC_EDIT_AXIS_CURR_ALARM_NUMBER, nAlarmCode);
+			}
+		};
+		m_pPLC->readData(MC::SOFT_COMPONENT::D, addr1, readSize, funOnReadData);
+	}
+
+	CDialogEx::OnTimer(nIDEvent);
+}
diff --git a/SourceCode/Bond/BondEq/View/AxisSettingsDlg.h b/SourceCode/Bond/BondEq/View/AxisSettingsDlg.h
index 6c73683..d8bb7f4 100644
--- a/SourceCode/Bond/BondEq/View/AxisSettingsDlg.h
+++ b/SourceCode/Bond/BondEq/View/AxisSettingsDlg.h
@@ -1,6 +1,7 @@
 锘�#pragma once
 #include "afxdialogex.h"
-
+#include "BLLabel.h"
+#include "CPLC.h"
 
 // CAxisSettingsDlg 瀵硅瘽妗�
 
@@ -12,6 +13,9 @@
 	CAxisSettingsDlg(CWnd* pParent = nullptr);   // 鏍囧噯鏋勯�犲嚱鏁�
 	virtual ~CAxisSettingsDlg();
 
+public:
+	void SetPLC(CPLC* pPLC);
+
 // 瀵硅瘽妗嗘暟鎹�
 #ifdef AFX_DESIGN_TIME
 	enum { IDD = IDD_DIALOG_AXIS_SETTINGS };
@@ -22,10 +26,21 @@
 	void SetDefaultFont();
 	void AdjustControls(float dScaleX, float dScaleY);
 	void AdjustControlFont(CWnd* pWnd, int nWidth, int nHeight);
+	void AdjustLabelFont(CBLLabel& label);
+	void SetStatusColor(CBLLabel& label, BOOL bStatus);
 
 private:
+	CPLC* m_pPLC;
 	int m_nInitialWidth;
 	int m_nInitialHeight;
+
+	// 鎺т欢
+	CBLLabel m_staticFLS;
+	CBLLabel m_staticDOG;
+	CBLLabel m_staticRLS;
+	CBLLabel m_staticReady;
+	CBLLabel m_staticBusy;
+	CBLLabel m_staticErr;
 	std::map<int, CRect> m_mapCtrlLayouts;
 	std::map<int, CFont*> m_mapFonts;
 
@@ -51,5 +66,6 @@
 	afx_msg void OnBnClickedButtonAxisTestJogAdd();
 	afx_msg void OnBnClickedButtonAxisTestJogSub();
 	afx_msg void OnBnClickedButtonAxisTestStop();
+	afx_msg void OnTimer(UINT_PTR nIDEvent);
 	DECLARE_MESSAGE_MAP()
 };
diff --git a/SourceCode/Bond/x64/Debug/Config/BondEq.db b/SourceCode/Bond/x64/Debug/Config/BondEq.db
index 9d40f9e..0f9a419 100644
--- a/SourceCode/Bond/x64/Debug/Config/BondEq.db
+++ b/SourceCode/Bond/x64/Debug/Config/BondEq.db
Binary files differ

--
Gitblit v1.9.3