From 2be286ac19bf2bb00e27f556e8b2cc292a58bd09 Mon Sep 17 00:00:00 2001
From: chenluhua1980 <Chenluhua@qq.com>
Date: 星期四, 08 一月 2026 18:48:59 +0800
Subject: [PATCH] 1.EAP状态继续实现,已在左侧加入相关按钮

---
 SourceCode/Bond/Servo/CPageCtrlState.cpp    |  157 +++++++++++++++++++++++++++++++
 SourceCode/Bond/Servo/Servo.vcxproj         |    2 
 SourceCode/Bond/Servo/Servo.vcxproj.filters |    2 
 SourceCode/Bond/Servo/resource.h            |   16 ++-
 SourceCode/Bond/Servo/Model.h               |    4 
 SourceCode/Bond/Servo/Servo.rc              |   22 ++++
 SourceCode/Bond/Servo/CPageCtrlState.h      |   41 ++++++++
 SourceCode/Bond/Servo/CPanelProduction.cpp  |   18 +++
 SourceCode/Bond/Servo/Model.cpp             |    4 
 SourceCode/Bond/Servo/CPanelProduction.h    |    2 
 SourceCode/Bond/Servo/Common.h              |    1 
 11 files changed, 262 insertions(+), 7 deletions(-)

diff --git a/SourceCode/Bond/Servo/CPageCtrlState.cpp b/SourceCode/Bond/Servo/CPageCtrlState.cpp
new file mode 100644
index 0000000..de9972c
--- /dev/null
+++ b/SourceCode/Bond/Servo/CPageCtrlState.cpp
@@ -0,0 +1,157 @@
+锘�// CPageCtrlState.cpp: 瀹炵幇鏂囦欢
+//
+
+#include "stdafx.h"
+#include "Servo.h"
+#include "CPageCtrlState.h"
+#include "afxdialogex.h"
+#include "Common.h"
+#include "Model.h"
+#include "ColorTransfer.h"
+
+
+// CPageCtrlState 瀵硅瘽妗�
+
+IMPLEMENT_DYNAMIC(CPageCtrlState, CDialogEx)
+
+CPageCtrlState::CPageCtrlState(CWnd* pParent /*=nullptr*/)
+	: CDialogEx(IDD_PROD_CTRL_STATE, pParent)
+{
+
+}
+
+CPageCtrlState::~CPageCtrlState()
+{
+}
+
+void CPageCtrlState::DoDataExchange(CDataExchange* pDX)
+{
+	CDialogEx::DoDataExchange(pDX);
+	DDX_Control(pDX, IDC_BUTTON_OFFLINE, m_btnOffline);
+	DDX_Control(pDX, IDC_BUTTON_ONLINE_LOCAL, m_btnOnlineLocal);
+	DDX_Control(pDX, IDC_BUTTON_ONLINE_REMOTE, m_btnOnlineRemote);
+}
+
+
+BEGIN_MESSAGE_MAP(CPageCtrlState, CDialogEx)
+	ON_WM_CTLCOLOR()
+	ON_WM_SIZE()
+	ON_WM_DESTROY()
+	ON_BN_CLICKED(IDC_BUTTON_OFFLINE, &CPageCtrlState::OnBnClickedOffline)
+	ON_BN_CLICKED(IDC_BUTTON_ONLINE_LOCAL, &CPageCtrlState::OnBnClickedOnlineLocal)
+	ON_BN_CLICKED(IDC_BUTTON_ONLINE_REMOTE, &CPageCtrlState::OnBnClickedOnlineRemote)
+END_MESSAGE_MAP()
+
+
+// CPageCtrlState 娑堟伅澶勭悊绋嬪簭
+
+void CPageCtrlState::InitRxWindows()
+{
+	IRxWindows* pRxWindows = RX_GetRxWindows();
+	if (m_pObserver == nullptr) {
+		m_pObserver = pRxWindows->allocObserver([this](IAny* pAny) -> void {
+			pAny->addRef();
+			const int code = pAny->getCode();
+			if (code == RX_CODE_CONTROL_STATE_CHANGED && ::IsWindow(m_hWnd)) {
+				UpdateButtonStyles();
+			}
+			pAny->release();
+			}, [&]() -> void {
+				// onComplete
+			}, [&](IThrowable* pThrowable) -> void {
+				// onError
+				pThrowable->printf();
+			});
+
+		theApp.m_model.getObservable()->observeOn(pRxWindows->mainThread())
+			->subscribe(m_pObserver);
+	}
+}
+
+void CPageCtrlState::ApplyButtonTheme(CBlButton& btn, bool active)
+{
+	const COLORREF text = active ? RGB(255, 255, 255) : RGB(0, 0, 0);
+	const COLORREF normal = active ? RGB(34, 177, 76) : RGB(222, 222, 222);
+	const COLORREF hover = CColorTransfer::ApproximateColor(normal, active ? 0.08 : 0.05);
+	const COLORREF press = CColorTransfer::ApproximateColor(normal, active ? -0.10 : -0.12);
+	const COLORREF frame = active ? CColorTransfer::ApproximateColor(normal, -0.18) : RGB(168, 168, 168);
+
+	btn.SetRoundWidth(6);
+	btn.SetTextColor(BS_NORMAL, text);
+	btn.SetTextColor(BS_HOVER, text);
+	btn.SetTextColor(BS_PRESS, text);
+	btn.SetTextColor(BS_DISABLE, RGB(120, 120, 120));
+
+	btn.SetBkgndColor(BS_NORMAL, normal);
+	btn.SetBkgndColor(BS_HOVER, hover);
+	btn.SetBkgndColor(BS_PRESS, press);
+	btn.SetBkgndColor(BS_DISABLE, RGB(210, 210, 210));
+
+	btn.SetFrameColor(BS_NORMAL, frame);
+	btn.SetFrameColor(BS_HOVER, frame);
+	btn.SetFrameColor(BS_PRESS, frame);
+	btn.SetFrameColor(BS_DISABLE, RGB(180, 180, 180));
+}
+
+void CPageCtrlState::UpdateButtonStyles()
+{
+	const auto state = theApp.m_model.getControlState();
+	ApplyButtonTheme(m_btnOffline, state == ControlState::OfflineEquipment || state == ControlState::OfflineHost);
+	ApplyButtonTheme(m_btnOnlineLocal, state == ControlState::OnlineLocal);
+	ApplyButtonTheme(m_btnOnlineRemote, state == ControlState::OnlineRemote);
+
+	Invalidate();
+	UpdateWindow();
+}
+
+BOOL CPageCtrlState::OnInitDialog()
+{
+	CDialogEx::OnInitDialog();
+
+	// TODO:  鍦ㄦ娣诲姞棰濆鐨勫垵濮嬪寲
+	InitRxWindows();
+	UpdateButtonStyles();
+
+	return TRUE;  // return TRUE unless you set the focus to a control
+				  // 寮傚父: OCX 灞炴�ч〉搴旇繑鍥� FALSE
+}
+
+
+HBRUSH CPageCtrlState::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
+{
+	HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
+
+	// TODO:  鍦ㄦ鏇存敼 DC 鐨勪换浣曠壒鎬�
+
+	// TODO:  濡傛灉榛樿鐨勪笉鏄墍闇�鐢荤瑪锛屽垯杩斿洖鍙︿竴涓敾绗�
+	return hbr;
+}
+
+void CPageCtrlState::OnSize(UINT nType, int cx, int cy)
+{
+	CDialogEx::OnSize(nType, cx, cy);
+
+	// TODO: 鍦ㄦ澶勬坊鍔犳秷鎭鐞嗙▼搴忎唬鐮�
+}
+
+void CPageCtrlState::OnDestroy()
+{
+	CDialogEx::OnDestroy();
+
+	// TODO: 鍦ㄦ澶勬坊鍔犳秷鎭鐞嗙▼搴忎唬鐮�
+}
+
+void CPageCtrlState::OnBnClickedOffline()
+{
+	theApp.m_model.setControlState(ControlState::OfflineEquipment);
+}
+
+void CPageCtrlState::OnBnClickedOnlineLocal()
+{
+	theApp.m_model.setControlState(ControlState::OnlineLocal);
+}
+
+void CPageCtrlState::OnBnClickedOnlineRemote()
+{
+	theApp.m_model.setControlState(ControlState::OnlineRemote);
+}
diff --git a/SourceCode/Bond/Servo/CPageCtrlState.h b/SourceCode/Bond/Servo/CPageCtrlState.h
new file mode 100644
index 0000000..2ed7343
--- /dev/null
+++ b/SourceCode/Bond/Servo/CPageCtrlState.h
@@ -0,0 +1,41 @@
+锘�#pragma once
+#include "BlButton.h"
+
+// CPageCtrlState 瀵硅瘽妗�
+
+class CPageCtrlState : public CDialogEx
+{
+	DECLARE_DYNAMIC(CPageCtrlState)
+
+public:
+	CPageCtrlState(CWnd* pParent = nullptr);   // 鏍囧噯鏋勯�犲嚱鏁�
+	virtual ~CPageCtrlState();
+
+private:
+	void InitRxWindows();
+	void UpdateButtonStyles();
+	void ApplyButtonTheme(CBlButton& btn, bool active);
+
+	CBlButton m_btnOffline;
+	CBlButton m_btnOnlineLocal;
+	CBlButton m_btnOnlineRemote;
+	IObserver* m_pObserver{ nullptr };
+
+// 瀵硅瘽妗嗘暟鎹�
+#ifdef AFX_DESIGN_TIME
+	enum { IDD = IDD_PROD_CTRL_STATE };
+#endif
+
+protected:
+	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 鏀寔
+
+	DECLARE_MESSAGE_MAP()
+public:
+	virtual BOOL OnInitDialog();
+	afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
+	afx_msg void OnSize(UINT nType, int cx, int cy);
+	afx_msg void OnDestroy();
+	afx_msg void OnBnClickedOffline();
+	afx_msg void OnBnClickedOnlineLocal();
+	afx_msg void OnBnClickedOnlineRemote();
+};
diff --git a/SourceCode/Bond/Servo/CPanelProduction.cpp b/SourceCode/Bond/Servo/CPanelProduction.cpp
index d8c9e2c..f3a5ab2 100644
--- a/SourceCode/Bond/Servo/CPanelProduction.cpp
+++ b/SourceCode/Bond/Servo/CPanelProduction.cpp
@@ -24,6 +24,7 @@
 	m_pStatsThread = nullptr;
 	m_pAccordionWnd = nullptr;
 	m_pPageProdOverview = nullptr;
+	m_pPageCtrlState = nullptr;
 }
 
 CPanelProduction::~CPanelProduction()
@@ -77,6 +78,12 @@
 	m_pAccordionWnd->Setpadding(PADDING_BOTTOM, 2);
 	m_pAccordionWnd->LoadExpandIcon(strExpandIcon, strCloseIcon);
 
+	m_pPageCtrlState = new CPageCtrlState();
+	m_pPageCtrlState->SetBackgroundColor(m_crBkgnd);
+	m_pPageCtrlState->Create(IDD_PROD_CTRL_STATE, GetDlgItem(IDC_ACCORDION_WND1));
+	m_pPageCtrlState->ShowWindow(SW_HIDE);
+	m_pAccordionWnd->AddItem("鐘舵��", m_pPageCtrlState, 120, TRUE, TRUE);
+
 	m_pPageProdOverview = new CPageProdOverview();
 	m_pPageProdOverview->SetBackgroundColor(m_crBkgnd);
 	m_pPageProdOverview->Create(IDD_PROD_OVERVIEW, GetDlgItem(IDC_ACCORDION_WND1));
@@ -112,6 +119,17 @@
 
 	CDialogEx::OnDestroy();
 
+	if (m_pPageCtrlState != nullptr) {
+		m_pPageCtrlState->DestroyWindow();
+		delete m_pPageCtrlState;
+		m_pPageCtrlState = nullptr;
+	}
+	if (m_pPageProdOverview != nullptr) {
+		m_pPageProdOverview->DestroyWindow();
+		delete m_pPageProdOverview;
+		m_pPageProdOverview = nullptr;
+	}
+
 	if (m_hbrBkgnd != nullptr) {
 		::DeleteObject(m_hbrBkgnd);
 	}
diff --git a/SourceCode/Bond/Servo/CPanelProduction.h b/SourceCode/Bond/Servo/CPanelProduction.h
index 66f5d06..a4bd705 100644
--- a/SourceCode/Bond/Servo/CPanelProduction.h
+++ b/SourceCode/Bond/Servo/CPanelProduction.h
@@ -4,6 +4,7 @@
 #include "AccordionWnd.h"
 #include "ProductionStats.h"
 #include "CPageProdOverview.h"
+#include "CPageCtrlState.h"
 
 // CPanelProduction dialog
 class CPanelProduction : public CDialogEx
@@ -32,6 +33,7 @@
 	CWinThread* m_pStatsThread;
 	CEvent m_evStopStats;
 	CPageProdOverview* m_pPageProdOverview;
+	CPageCtrlState* m_pPageCtrlState;
 
 protected:
 	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
diff --git a/SourceCode/Bond/Servo/Common.h b/SourceCode/Bond/Servo/Common.h
index ed3798c..4969d57 100644
--- a/SourceCode/Bond/Servo/Common.h
+++ b/SourceCode/Bond/Servo/Common.h
@@ -19,6 +19,7 @@
 #define RX_CODE_MASTER_STATE_CHANGED	1011
 #define RX_CODE_EQ_ROBOT_TASK			1012
 #define RX_CODE_LOADPORT_STATUS_CHANGED	1014
+#define RX_CODE_CONTROL_STATE_CHANGED	1015
 
 
 /* Channel Name */
diff --git a/SourceCode/Bond/Servo/Model.cpp b/SourceCode/Bond/Servo/Model.cpp
index f267b26..9011afb 100644
--- a/SourceCode/Bond/Servo/Model.cpp
+++ b/SourceCode/Bond/Servo/Model.cpp
@@ -41,6 +41,10 @@
 
 	// Always keep SV in sync (even if state didn't change or variables were just loaded).
 	m_hsmsPassive.setVariableValue("CurrentControlState", (__int64)static_cast<uint8_t>(m_currentControlState));
+
+	if (newState != prev) {
+		notifyInt(RX_CODE_CONTROL_STATE_CHANGED, static_cast<int>(m_currentControlState));
+	}
 }
 
 IObservable* CModel::getObservable()
diff --git a/SourceCode/Bond/Servo/Model.h b/SourceCode/Bond/Servo/Model.h
index c38017f..839e949 100644
--- a/SourceCode/Bond/Servo/Model.h
+++ b/SourceCode/Bond/Servo/Model.h
@@ -31,9 +31,11 @@
 	int init();
 	int term();
 
+	ControlState getControlState() const noexcept { return m_currentControlState; }
+	void setControlState(ControlState newState);
+
 private:
 	void refreshDerivedSVs();
-	void setControlState(ControlState newState);
 
 public:
 	int notify(int code);
diff --git a/SourceCode/Bond/Servo/Servo.rc b/SourceCode/Bond/Servo/Servo.rc
index 1cc02ae..1c07a27 100644
--- a/SourceCode/Bond/Servo/Servo.rc
+++ b/SourceCode/Bond/Servo/Servo.rc
@@ -826,6 +826,15 @@
     CTEXT           "-",IDC_PROD_NIGHT_TAKT,126,82,68,45,SS_CENTERIMAGE
 END
 
+IDD_PROD_CTRL_STATE DIALOGEX 0, 0, 216, 97
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+    PUSHBUTTON      "Offline",IDC_BUTTON_OFFLINE,9,15,58,27
+    PUSHBUTTON      "Online Local",IDC_BUTTON_ONLINE_LOCAL,74,15,58,27
+    PUSHBUTTON      "Online Remote",IDC_BUTTON_ONLINE_REMOTE,138,15,58,27
+END
+
 
 /////////////////////////////////////////////////////////////////////////////
 //
@@ -1271,6 +1280,14 @@
         TOPMARGIN, 7
         BOTTOMMARGIN, 152
     END
+
+    IDD_PROD_CTRL_STATE, DIALOG
+    BEGIN
+        LEFTMARGIN, 7
+        RIGHTMARGIN, 209
+        TOPMARGIN, 7
+        BOTTOMMARGIN, 90
+    END
 END
 #endif    // APSTUDIO_INVOKED
 
@@ -1530,6 +1547,11 @@
     0
 END
 
+IDD_PROD_CTRL_STATE AFX_DIALOG_LAYOUT
+BEGIN
+    0
+END
+
 
 /////////////////////////////////////////////////////////////////////////////
 //
diff --git a/SourceCode/Bond/Servo/Servo.vcxproj b/SourceCode/Bond/Servo/Servo.vcxproj
index 8b7b8a4..8926423 100644
--- a/SourceCode/Bond/Servo/Servo.vcxproj
+++ b/SourceCode/Bond/Servo/Servo.vcxproj
@@ -242,6 +242,7 @@
     <ClInclude Include="ClientListDlg.h" />
     <ClInclude Include="CMyStatusbar.h" />
     <ClInclude Include="CPageCollectionEvent.h" />
+    <ClInclude Include="CPageCtrlState.h" />
     <ClInclude Include="CPageGlassList.h" />
     <ClInclude Include="CPageLinkSignal.h" />
     <ClInclude Include="CPageProdOverview.h" />
@@ -468,6 +469,7 @@
     <ClCompile Include="ClientListDlg.cpp" />
     <ClCompile Include="CMyStatusbar.cpp" />
     <ClCompile Include="CPageCollectionEvent.cpp" />
+    <ClCompile Include="CPageCtrlState.cpp" />
     <ClCompile Include="CPageGlassList.cpp" />
     <ClCompile Include="CPageLinkSignal.cpp" />
     <ClCompile Include="CPageProdOverview.cpp" />
diff --git a/SourceCode/Bond/Servo/Servo.vcxproj.filters b/SourceCode/Bond/Servo/Servo.vcxproj.filters
index ccbde0c..ece83fa 100644
--- a/SourceCode/Bond/Servo/Servo.vcxproj.filters
+++ b/SourceCode/Bond/Servo/Servo.vcxproj.filters
@@ -242,6 +242,7 @@
     <ClCompile Include="AccordionWnd.cpp" />
     <ClCompile Include="CPageProdOverview.cpp" />
     <ClCompile Include="HmLabel.cpp" />
+    <ClCompile Include="CPageCtrlState.cpp" />
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="AlarmManager.h" />
@@ -526,6 +527,7 @@
     <ClInclude Include="AccordionWnd.h" />
     <ClInclude Include="CPageProdOverview.h" />
     <ClInclude Include="HmLabel.h" />
+    <ClInclude Include="CPageCtrlState.h" />
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="Servo.rc" />
diff --git a/SourceCode/Bond/Servo/resource.h b/SourceCode/Bond/Servo/resource.h
index 8f303c6..52ee640 100644
--- a/SourceCode/Bond/Servo/resource.h
+++ b/SourceCode/Bond/Servo/resource.h
@@ -61,12 +61,13 @@
 #define IDD_CJ_PAGE3                    180
 #define IDD_DIALOG_USER_MANAGER2        181
 #define IDD_DIALOG_USER_EDIT2           182
-#define IDD_PROD_OVERVIEW				183
+#define IDD_PROD_OVERVIEW               183
 #define IDD_DIALOG_USERX_LOG            184
 #define IDD_DIALOG_VARIABLE_EDIT2       186
 #define IDD_DIALOG_REPORT_EDIT          187
 #define IDD_DIALOG_EVENT_EDIT           188
 #define IDD_PANEL_PRODUCTION            189
+#define IDD_PROD_CTRL_STATE             190
 #define IDC_SERVO_GRAPH1                1001
 #define IDC_BUTTON_LOG                  1002
 #define IDC_EDIT_LOG                    1003
@@ -324,10 +325,13 @@
 #define IDC_EDIT_EVT_DESC               1245
 #define IDC_LIST_EVT_RPTS               1246
 #define IDC_ACCORDION_WND1              1247
-#define IDC_PROD_DAY_OUTPUT				1248
-#define IDC_PROD_NIGHT_OUTPUT			1249
-#define IDC_PROD_DAY_TAKT				1250
-#define IDC_PROD_NIGHT_TAKT				1251
+#define IDC_PROD_DAY_OUTPUT             1248
+#define IDC_PROD_NIGHT_OUTPUT           1249
+#define IDC_PROD_DAY_TAKT               1250
+#define IDC_PROD_NIGHT_TAKT             1251
+#define IDC_BUTTON_OFFLINE              1252
+#define IDC_BUTTON_ONLINE_LOCAL         1253
+#define IDC_BUTTON_ONLINE_REMOTE        1254
 #define ID_MENU_HELP_ABOUT              32771
 #define ID_MENU_FILE_EXIT               32772
 #define ID_MENU_FILE_SECSTEST           32773
@@ -367,7 +371,7 @@
 #ifndef APSTUDIO_READONLY_SYMBOLS
 #define _APS_NEXT_RESOURCE_VALUE        191
 #define _APS_NEXT_COMMAND_VALUE         32804
-#define _APS_NEXT_CONTROL_VALUE         1252
+#define _APS_NEXT_CONTROL_VALUE         1255
 #define _APS_NEXT_SYMED_VALUE           101
 #endif
 #endif

--
Gitblit v1.9.3