From bfe14e41fa5b07771d78af4511ba18d706bc23cc Mon Sep 17 00:00:00 2001
From: LAPTOP-SNT8I5JK\Boounion <Chenluhua@qq.com>
Date: 星期一, 28 七月 2025 17:07:52 +0800
Subject: [PATCH] 1.Spooling Config功能EAP模拟测试;

---
 SourceCode/Bond/BondEq/View/IOMonitoringDlg.cpp |  455 +++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 413 insertions(+), 42 deletions(-)

diff --git a/SourceCode/Bond/BondEq/View/IOMonitoringDlg.cpp b/SourceCode/Bond/BondEq/View/IOMonitoringDlg.cpp
index 1185f82..dee2397 100644
--- a/SourceCode/Bond/BondEq/View/IOMonitoringDlg.cpp
+++ b/SourceCode/Bond/BondEq/View/IOMonitoringDlg.cpp
@@ -5,7 +5,16 @@
 #include "BondEq.h"
 #include "afxdialogex.h"
 #include "IOMonitoringDlg.h"
+#include "ToolUnits.h"
 
+#define TIMER_INIT				1
+#define TIMER_READ_PLC_DATA		2
+#define TIMER_READ_UPDATE		3
+
+#define LABEL_ID_BEGIN			2000
+#define	ADDR_WND				_T("ADDR_WND")
+
+#define ID_MSG_IO_CLICK			WM_USER + 101
 
 // CIOMonitoringDlg 瀵硅瘽妗�
 
@@ -16,7 +25,7 @@
 {
 	m_nCurrentPage = 1;
 	m_nTotalPages = 1;
-	m_nRowsPerPage = 10;
+	m_nRowsPerPage = 16;
 	m_nCols = 6;
 }
 
@@ -50,7 +59,13 @@
 
 	// 璁$畻椤垫暟
 	m_nCurrentPage = 1;
-	m_nTotalPages = (m_displayData.size() + m_nRowsPerPage - 1) / m_nRowsPerPage;
+	m_nTotalPages = ((int)m_displayData.size() + m_nRowsPerPage - 1) / m_nRowsPerPage;
+}
+
+void CIOMonitoringDlg::SetPLC(CPLC* pPLC)
+{
+	ASSERT(pPLC);
+	m_pPLC = pPLC;
 }
 
 CFont* CIOMonitoringDlg::GetOrCreateFont(int nFontSize)
@@ -88,8 +103,7 @@
 	CWnd* pWnd = GetWindow(GW_CHILD);
 	while (pWnd) {
 		int nCtrlID = pWnd->GetDlgCtrlID();
-		if (nCtrlID != -1 && m_mapCtrlLayouts.find(nCtrlID) != m_mapCtrlLayouts.end())
-		{
+		if (nCtrlID != -1 && m_mapCtrlLayouts.find(nCtrlID) != m_mapCtrlLayouts.end()) {
 			CRect originalRect = m_mapCtrlLayouts[nCtrlID];
 			CRect newRect(
 				static_cast<int>(originalRect.left * dScaleX),
@@ -112,6 +126,7 @@
 	// 鏍规嵁鎺т欢楂樺害鍔ㄦ�佽皟鏁村瓧浣撳ぇ灏�
 	int fontSize = nHeight / 2;
 	if (fontSize < 8) fontSize = 8;
+	if (fontSize < 24) fontSize = 24;
 
 	// 鑾峰彇鎴栧垱寤哄瓧浣�
 	CFont* pFont = GetOrCreateFont(fontSize);
@@ -146,7 +161,7 @@
 	ScreenToClient(&nextButtonRect);
 
 	int buttonHeight = prevButtonRect.Height();     // 鎸夐挳鐨勯珮搴�
-	int topMargin = rect.Height() * 0.05;           // 椤堕儴淇濈暀 5% 鐨勯珮搴�
+	int topMargin = int(rect.Height() * 0.05);      // 椤堕儴淇濈暀 5% 鐨勯珮搴�
 	int bottomMargin = buttonHeight + topMargin;    // 搴曢儴淇濈暀鎸夐挳楂樺害鍔犻棿璺�
 	int sideMargin = topMargin;                     // 宸﹀彸闂磋窛涓庨《閮ㄩ棿璺濈浉鍚�
 	int groupSpacing = 20;                          // 涓ょ粍涔嬮棿鐨勯棿璺�
@@ -161,53 +176,97 @@
 	int colWidthLarge = availableWidth * 4 / 14;		// 澶у搴﹀垪姣斾緥
 	int groupWidth = colWidthSmall * 2 + colWidthLarge; // 姣忕粍鎬诲搴�
 
-	for (int i = 0; i < m_nRowsPerPage; ++i)
-	{
+	UINT id = LABEL_ID_BEGIN;
+	for (int i = 0; i < m_nRowsPerPage; ++i) {
 		// 姣忎竴琛岀殑璧峰 Y 鍧愭爣
 		int y = topMargin + i * (rowHeight + verticalSpacing);
 
 		// 鍒涘缓绗� 1 缁� (0, 1, 2)
 		int x = sideMargin; // 浠庡乏杈硅窛寮�濮�
-		CreateStaticControl(x, y, colWidthSmall, rowHeight, _T("OFF"), true);
+		CreateStaticControl(++id, x, y, colWidthSmall, rowHeight, _T("OFF"), true, AlignCenter);
 		x += colWidthSmall;
-		CreateStaticControl(x, y, colWidthSmall, rowHeight, _T("X1000"));
+		CreateStaticControl(++id, x, y, colWidthSmall, rowHeight, _T("X1000"), false, AlignCenter);
 		x += colWidthSmall;
-		CreateStaticControl(x, y, colWidthLarge, rowHeight, _T("鎻忚堪鏂囨湰"), false, true);
+		CreateStaticControl(++id, x, y, colWidthLarge, rowHeight, _T("鎻忚堪鏂囨湰"), false);
 
 		// 绗� 2 缁勮捣濮嬩綅缃紝鍔犱笂缁勯棿璺�
 		x += colWidthLarge + groupSpacing;
 
 		// 鍒涘缓绗� 2 缁� (3, 4, 5)
-		CreateStaticControl(x, y, colWidthSmall, rowHeight, _T("OFF"), true);
+		id++;
+		CWnd* pBtn = CreateStaticControl(id, x, y, colWidthSmall, rowHeight, _T("OFF"), true, AlignCenter, [this, id, i, x, y]() {
+			// 鑷畾涔夌偣鍑讳簨浠剁殑閫昏緫
+			auto* pControl = static_cast<CBLLabel*>(m_staticControls[i * m_nCols + 3]);
+			CString currentText;
+			pControl->GetWindowText(currentText);
+			PostMessage(ID_MSG_IO_CLICK, id, currentText == _T("OFF") ? 1 : 0);
+		});
 		x += colWidthSmall;
-		CreateStaticControl(x, y, colWidthSmall, rowHeight, _T("Y1010"));
+		CWnd* pLabel = CreateStaticControl(++id, x, y, colWidthSmall, rowHeight, _T("Y1010"), false, AlignCenter);
 		x += colWidthSmall;
-		CreateStaticControl(x, y, colWidthLarge, rowHeight, _T("鎻忚堪鏂囨湰"), false, true);
+		CreateStaticControl(++id, x, y, colWidthLarge, rowHeight, _T("鎻忚堪鏂囨湰"), false);
+		::SetProp(pBtn->GetSafeHwnd(), ADDR_WND, pLabel);
 	}
 }
 
-void CIOMonitoringDlg::CreateStaticControl(int x, int y, int width, int height, const CString& text, bool hasBorder, bool alignLeft)
+CWnd* CIOMonitoringDlg::CreateStaticControl(UINT id, int x, int y, int width, int height, const CString& text, bool hasBorder, TextAlign alignment, std::function<void()> clickCallback)
 {
+	// 鍒涘缓鍔ㄦ�佹帶浠�
+	CBLLabel* pStatic = new CBLLabel();
 	DWORD style = WS_CHILD | WS_VISIBLE | SS_CENTERIMAGE; // 纭繚鍨傜洿灞呬腑
-	if (hasBorder) {
-		style |= WS_BORDER;		// 娣诲姞杈规
+	if (!hasBorder) {
+		pStatic->DisableBorder();
 	}
-	if (alignLeft) {
-		style |= SS_LEFT;		// 宸﹀榻愭枃鏈�
-	}
-	else {
-		style |= SS_CENTER;		// 灞呬腑鏂囨湰
-	}
+	pStatic->Create(text, style, CRect(x, y, x + width, y + height), this, id);
 
-	CStatic* pStatic = new CStatic();
-	pStatic->Create(text, style, CRect(x, y, x + width, y + height), this);
+	// 璁剧疆鏂囨湰瀵归綈鏂瑰紡
+	pStatic->SetAlignment(alignment);
 
-	// 鍔ㄦ�佽缃瓧浣撳ぇ灏�
-	CFont* pFont = GetOrCreateFont(height / 3);
+	// 璁剧疆鍔ㄦ�佸瓧浣撹皟鏁达紝骞惰缃瓧浣撳ぇ灏忥紙鍔ㄦ�佸瓧浣撲細鏍规嵁鎺т欢澶у皬璋冩暣锛�
+	int nSize = height / 3;
+	CFont* pFont = GetOrCreateFont(nSize);
 	pStatic->SetFont(pFont);
+	pStatic->SetFontSize(nSize);
+	pStatic->SetDynamicFont(TRUE);
+
+	// 璁剧疆鍥炶皟
+	UserManager& userManager = UserManager::getInstance();
+	UserRole enRole = userManager.getCurrentUserRole();
+	if (clickCallback && (enRole == UserRole::SuperAdmin || enRole == UserRole::Operator)) {
+		pStatic->SetClickCallback(clickCallback);
+		pStatic->SetRoundedCorners(TRUE, 5);
+		pStatic->DisableBorder();
+	}
 
 	// 瀛樺偍鎺т欢鎸囬拡
 	m_staticControls.push_back(pStatic);
+
+	return pStatic;
+}
+
+CWnd* CIOMonitoringDlg::GetStaticControl(UINT id)
+{
+	for (auto item : m_staticControls) {
+		TRACE(">>id锛�%d\n", item->GetDlgCtrlID());
+		if (item->GetDlgCtrlID() == id) {
+			return item;
+		}
+	}
+
+	return nullptr;
+}
+
+CString& CIOMonitoringDlg::GetStaticControlAddrText(UINT id, CString& strAddr)
+{
+	CWnd* pBtn = GetStaticControl(id);
+	if (pBtn != nullptr) {
+		CWnd* pLabel = (CWnd*)::GetProp(pBtn->GetSafeHwnd(), ADDR_WND);
+		if (pLabel != nullptr) {
+			pLabel->GetWindowText(strAddr);
+		}
+	}
+
+	return strAddr;
 }
 
 void CIOMonitoringDlg::DisplayCurrentPage()
@@ -215,27 +274,61 @@
 	int startIndex = (m_nCurrentPage - 1) * m_nRowsPerPage;
 	int endIndex = min(startIndex + m_nRowsPerPage, static_cast<int>(m_displayData.size()));
 
-	for (int i = startIndex; i < endIndex; ++i)
-	{
-		const auto& data = m_displayData[i];
-		int row = i - startIndex;
+	m_inputStates.clear();
+	m_outputStates.clear();
+	m_inputPLCAddresses.clear();
+	m_outputPLCAddresses.clear();
 
-		m_staticControls[row * m_nCols + 0]->SetWindowText(_T("OFF"));
-		m_staticControls[row * m_nCols + 1]->SetWindowText(CString(data.inputAddress.c_str()));
-		m_staticControls[row * m_nCols + 2]->SetWindowText(CString(data.inputDescription.c_str()));
-		m_staticControls[row * m_nCols + 3]->SetWindowText(_T("OFF"));
-		m_staticControls[row * m_nCols + 4]->SetWindowText(CString(data.outputAddress.c_str()));
-		m_staticControls[row * m_nCols + 5]->SetWindowText(CString(data.outputDescription.c_str()));
+	for (int i = 0; i < m_nRowsPerPage; ++i) {
+		int row = i;
+
+		if (startIndex + i < endIndex) {
+			const auto& data = m_displayData[startIndex + i];
+
+			// 娣诲姞鐘舵�佸埌瀹瑰櫒涓�
+			m_inputStates.push_back(FALSE);		// 0 鍒�
+			m_outputStates.push_back(FALSE);	// 3 鍒�
+
+			// 娣诲姞 PLC 鍦板潃鍒板鍣ㄤ腑
+			m_inputPLCAddresses.push_back(CString(data.inputAddress.c_str()));		// 1 鍒�
+			m_outputPLCAddresses.push_back(CString(data.outputAddress.c_str()));	// 4 鍒�
+
+			// 鏄剧ず鎺т欢骞惰缃唴瀹�
+			m_staticControls[row * m_nCols + 0]->SetWindowText(_T("OFF"));
+			m_staticControls[row * m_nCols + 0]->ShowWindow(SW_SHOW);
+			m_staticControls[row * m_nCols + 0]->SetBkColor(RGB(255, 0, 0));
+
+			m_staticControls[row * m_nCols + 1]->SetWindowText(CString(data.inputAddress.c_str()));
+			m_staticControls[row * m_nCols + 1]->ShowWindow(SW_SHOW);
+
+			m_staticControls[row * m_nCols + 2]->SetWindowText(CString(data.inputDescription.c_str()));
+			m_staticControls[row * m_nCols + 2]->ShowWindow(SW_SHOW);
+
+			m_staticControls[row * m_nCols + 3]->SetWindowText(_T("OFF"));
+			m_staticControls[row * m_nCols + 3]->ShowWindow(SW_SHOW);
+			m_staticControls[row * m_nCols + 3]->SetBkColor(RGB(255, 0, 0));
+
+			m_staticControls[row * m_nCols + 4]->SetWindowText(CString(data.outputAddress.c_str()));
+			m_staticControls[row * m_nCols + 4]->ShowWindow(SW_SHOW);
+
+			m_staticControls[row * m_nCols + 5]->SetWindowText(CString(data.outputDescription.c_str()));
+			m_staticControls[row * m_nCols + 5]->ShowWindow(SW_SHOW);
+		}
+		else {
+			// 闅愯棌杩欎竴琛岀殑鎵�鏈夋帶浠�
+			for (int col = 0; col < m_nCols; ++col) {
+				m_staticControls[row * m_nCols + col]->ShowWindow(SW_HIDE);
+			}
+		}
 	}
+
 	UpdatePageInfo();
 }
 
 void CIOMonitoringDlg::ClearDynamicControls()
 {
-	for (auto* pStatic : m_staticControls)
-	{
-		if (pStatic)
-		{
+	for (auto* pStatic : m_staticControls) {
+		if (pStatic) {
 			pStatic->DestroyWindow();
 			delete pStatic;
 		}
@@ -243,10 +336,229 @@
 	m_staticControls.clear();
 }
 
+bool CIOMonitoringDlg::ParsePLCAddress(const CString& address, MC::SOFT_COMPONENT& component, int& addr)
+{
+	if (address.GetLength() < 2) {
+		return false;
+	}
+
+	// 鎻愬彇缁勪欢绫诲瀷锛堢涓�涓瓧绗︼級
+	TCHAR componentChar = address[0];
+	if (address.Left(2) == _T("ZR")) {
+		component = MC::SOFT_COMPONENT::ZR;
+		// 鎻愬彇鏁板瓧閮ㄥ垎锛堝幓闄R鍓嶇紑锛�
+		CString numericAddress = address.Mid(2);
+		addr = _tcstoul(numericAddress, nullptr, 16);
+		return addr != 0 || numericAddress.CompareNoCase(_T("0")) == 0;  // 濡傛灉鏄� "0"锛屼篃璁や负鏈夋晥
+	}
+
+	// 瀵逛簬鍏朵粬缁勪欢锛屾寜鐓у父瑙勮鍒欏鐞�
+	CString hexAddress = address.Mid(1);
+	switch (componentChar) {
+	case 'D':
+		component = MC::SOFT_COMPONENT::D;
+		addr = _ttoi(hexAddress);
+		break;
+	case 'M':
+		component = MC::SOFT_COMPONENT::M;
+		addr = _tcstoul(hexAddress, nullptr, 16);
+		break;
+	case 'X':
+		component = MC::SOFT_COMPONENT::X;
+		addr = _tcstoul(hexAddress, nullptr, 16);
+		break;
+	case 'Y':
+		component = MC::SOFT_COMPONENT::Y;
+		addr = _tcstoul(hexAddress, nullptr, 16);
+		break;
+	case 'W':
+		component = MC::SOFT_COMPONENT::W;
+		addr = _tcstoul(hexAddress, nullptr, 16);
+		break;
+	case 'L':
+		component = MC::SOFT_COMPONENT::L;
+		addr = _tcstoul(hexAddress, nullptr, 16);
+		break;
+	case 'S':
+		component = MC::SOFT_COMPONENT::S;
+		addr = _tcstoul(hexAddress, nullptr, 16);
+		break;
+	case 'B':
+		component = MC::SOFT_COMPONENT::B;
+		addr = _tcstoul(hexAddress, nullptr, 16);
+		break;
+	case 'F':
+		component = MC::SOFT_COMPONENT::F;
+		addr = _tcstoul(hexAddress, nullptr, 16);
+		break;
+	default:
+		return false;
+	}
+
+	// 妫�鏌ュ湴鍧�鏄惁鏈夋晥
+	if (addr == 0 && hexAddress.CompareNoCase(_T("0")) != 0) {
+		return false;
+	}
+
+	return true;
+}
+
+bool CIOMonitoringDlg::GeneratePLCAddress(MC::SOFT_COMPONENT component, int addr, CString& address, bool bHexFormat)
+{
+	// 鏍规嵁缁勪欢绫诲瀷鐢熸垚鍓嶇紑
+	CString prefix;
+	switch (component) {
+	case MC::SOFT_COMPONENT::D:
+		prefix = _T("D");
+		break;
+	case MC::SOFT_COMPONENT::M:
+		prefix = _T("M");
+		break;
+	case MC::SOFT_COMPONENT::X:
+		prefix = _T("X");
+		break;
+	case MC::SOFT_COMPONENT::Y:
+		prefix = _T("Y");
+		break;
+	case MC::SOFT_COMPONENT::W:
+		prefix = _T("W");
+		break;
+	case MC::SOFT_COMPONENT::L:
+		prefix = _T("L");
+		break;
+	case MC::SOFT_COMPONENT::S:
+		prefix = _T("S");
+		break;
+	case MC::SOFT_COMPONENT::B:
+		prefix = _T("B");
+		break;
+	case MC::SOFT_COMPONENT::F:
+		prefix = _T("F");
+		break;
+	case MC::SOFT_COMPONENT::ZR:
+		prefix = _T("ZR");
+		break;
+	default:
+		return false;  // 濡傛灉鏄湭鐭ョ粍浠剁被鍨嬶紝杩斿洖澶辫触
+	}
+
+	// 鏍规嵁 bHexFormat 鍒ゆ柇杈撳嚭鏍煎紡
+	CString strAddr;
+	if (bHexFormat) {
+		strAddr.Format(_T("%X"), addr);  // 鍗佸叚杩涘埗鏍煎紡
+	}
+	else {
+		strAddr.Format(_T("%d"), addr);  // 鍗佽繘鍒舵牸寮�
+	}
+
+	// 鐢熸垚鏈�缁堢殑鍦板潃瀛楃涓�
+	address = prefix + strAddr;
+	return true;
+}
+
+// 澶勭悊PLC鏁版嵁璇诲彇鐨勯�氱敤鏂规硶
+void CIOMonitoringDlg::ReadPLCData(MC::SOFT_COMPONENT softComponent, int startAddr, int endAddr, std::function<void(IMcChannel*, int, char*, unsigned int, int)> callback)
+{
+	int nSize;
+	// 妫�鏌ュ湴鍧�鏄惁鏈夋晥锛屼互鍙婄粍浠舵槸鍚﹀尮閰�
+	nSize = endAddr - startAddr + 1;
+	if (nSize < 1) {
+		return;
+	}
+
+	// 璇诲彇鏁版嵁
+	m_pPLC->readData(softComponent, startAddr, nSize, callback);
+}
+
+void CIOMonitoringDlg::ReadPLCStates()
+{
+	if (m_displayData.empty()) {
+		return;
+	}
+
+	auto startData = m_displayData.front();
+	auto endData = m_displayData.back();
+	MC::SOFT_COMPONENT startSoftComponent, endSoftComponent;
+	int inputStartAddr, inputEndAddr;
+	ParsePLCAddress(CString(startData.inputAddress.c_str()), startSoftComponent, inputStartAddr);
+	ParsePLCAddress(CString(endData.inputAddress.c_str()), endSoftComponent, inputEndAddr);
+	ASSERT(startSoftComponent == endSoftComponent);
+
+	// 璇诲彇杈撳叆鏁版嵁
+	ReadPLCData(startSoftComponent, inputStartAddr, inputEndAddr, [this, inputStartAddr](IMcChannel* pChannel, int addr, char* pData, unsigned int nDataSize, int flag) {
+		if (!::IsWindow(m_hWnd)) return;
+		for (auto& data : m_displayData) {
+			int nAddress;
+			MC::SOFT_COMPONENT enComponent;
+			if (ParsePLCAddress(CString(data.inputAddress.c_str()), enComponent, nAddress)) {
+				int nOffset = nAddress - inputStartAddr;
+				if (nOffset >= 0 && nOffset < (int)nDataSize) {
+					int byteIndex = nOffset / 8;
+					int bitIndex = nOffset % 8;
+					data.bInputStates = CToolUnits::getBit(pData[byteIndex], bitIndex);
+				}
+			}
+		}
+	});
+
+	// 璇诲彇杈撳嚭鏁版嵁
+	int outputStartAddr, outputEndAddr;
+	ParsePLCAddress(CString(startData.outputAddress.c_str()), startSoftComponent, outputStartAddr);
+	ParsePLCAddress(CString(endData.outputAddress.c_str()), endSoftComponent, outputEndAddr);
+	ASSERT(startSoftComponent == endSoftComponent);
+	ReadPLCData(startSoftComponent, outputStartAddr, outputEndAddr, [this, outputStartAddr](IMcChannel* pChannel, int addr, char* pData, unsigned int nDataSize, int flag) {
+		if (!::IsWindow(m_hWnd)) return;
+		for (auto& data : m_displayData) {
+			int nAddress;
+			MC::SOFT_COMPONENT enComponent;
+			if (ParsePLCAddress(CString(data.outputAddress.c_str()), enComponent, nAddress)) {
+				int nOffset = nAddress - outputStartAddr;
+				if (nOffset >= 0 && nOffset < (int)nDataSize) {
+					int byteIndex = nOffset / 8;
+					int bitIndex = nOffset % 8;
+					data.bOutputStates = CToolUnits::getBit(pData[byteIndex], bitIndex);
+					TRACE(">>>> %d %d %d |||| %d\n", nOffset, byteIndex, bitIndex, data.bOutputStates);
+				}
+			}
+		}
+	});
+}
+
+void CIOMonitoringDlg::UpdatePLCStatesToUI()
+{
+	int startIndex = (m_nCurrentPage - 1) * m_nRowsPerPage;
+	int endIndex = min(startIndex + m_nRowsPerPage, static_cast<int>(m_displayData.size()));
+
+	for (int i = 0; i < m_nRowsPerPage; ++i) {
+		int row = i;
+
+		if (startIndex + i < endIndex) {
+			const auto& data = m_displayData[startIndex + i];
+			// 璁剧疆鍐呭鍜岃儗鏅鑹�
+			if (m_inputStates[i] != data.bInputStates)
+			{
+				m_staticControls[row * m_nCols + 0]->SetText(data.bInputStates ? _T("ON") : _T("OFF"));
+				m_staticControls[row * m_nCols + 0]->SetBkColor(data.bInputStates ? RGB(0, 255, 0) : RGB(255, 0, 0));
+				m_inputStates[i] = data.bInputStates;
+			}
+
+			if (m_outputStates[i] != data.bOutputStates)
+			{
+				m_staticControls[row * m_nCols + 3]->SetText(data.bOutputStates ? _T("ON") : _T("OFF"));
+				m_staticControls[row * m_nCols + 3]->SetBkColor(data.bOutputStates ? RGB(0, 255, 0) : RGB(255, 0, 0));
+				m_outputStates[i] = data.bOutputStates;
+			}
+		}
+	}
+}
+
 BEGIN_MESSAGE_MAP(CIOMonitoringDlg, CDialogEx)
 	ON_BN_CLICKED(IDC_BUTTON_PREV_PAGE, &CIOMonitoringDlg::OnBnClickedButtonPrevPage)
 	ON_BN_CLICKED(IDC_BUTTON_NEXT_PAGE, &CIOMonitoringDlg::OnBnClickedButtonNextPage)
+	ON_MESSAGE(ID_MSG_IO_CLICK, &CIOMonitoringDlg::OnIoClicked)
 	ON_WM_SIZE()
+	ON_WM_TIMER()
+	ON_WM_CLOSE()
 END_MESSAGE_MAP()
 
 
@@ -294,8 +606,8 @@
 	}
 
 	GetWindowRect(&dlgRect);
-	int dlgWidth = dlgRect.Width() * 2;
-	int dlgHeight = dlgRect.Height() * 2;
+	int dlgWidth = dlgRect.Width() * 3;
+	int dlgHeight = dlgRect.Height() * 3;
 
 	if (dlgWidth > screenRect.Width()) {
 		dlgWidth = screenRect.Width();
@@ -310,6 +622,12 @@
 
 	CreateDynamicControls();
 	DisplayCurrentPage();
+
+	GetDlgItem(IDC_BUTTON_PREV_PAGE)->EnableWindow(m_nCurrentPage > 1);
+	GetDlgItem(IDC_BUTTON_NEXT_PAGE)->EnableWindow(m_nCurrentPage < m_nTotalPages);
+
+	SetTimer(TIMER_READ_PLC_DATA, 500, nullptr);
+	SetTimer(TIMER_READ_UPDATE, 200, nullptr);
 
 	return TRUE;  // return TRUE unless you set the focus to a control
 	// 寮傚父: OCX 灞炴�ч〉搴旇繑鍥� FALSE
@@ -341,6 +659,9 @@
 	else {
 		AfxMessageBox(_T("宸茬粡鏄涓�椤碉紒"));
 	}
+
+	GetDlgItem(IDC_BUTTON_PREV_PAGE)->EnableWindow(m_nCurrentPage > 1);
+	GetDlgItem(IDC_BUTTON_NEXT_PAGE)->EnableWindow(m_nCurrentPage < m_nTotalPages);
 }
 
 void CIOMonitoringDlg::OnBnClickedButtonNextPage()
@@ -353,4 +674,54 @@
 	else {
 		AfxMessageBox(_T("宸茬粡鏄渶鍚庝竴椤碉紒"));
 	}
+	
+	GetDlgItem(IDC_BUTTON_PREV_PAGE)->EnableWindow(m_nCurrentPage > 1);
+	GetDlgItem(IDC_BUTTON_NEXT_PAGE)->EnableWindow(m_nCurrentPage < m_nTotalPages);
+}
+
+LRESULT CIOMonitoringDlg::OnIoClicked(WPARAM wParam, LPARAM lParam)
+{
+	CString strAddr;
+	GetStaticControlAddrText((UINT)wParam, strAddr);
+
+	BOOL bOn = (BOOL)lParam;
+	int nAddress;
+	MC::SOFT_COMPONENT component;
+	if (ParsePLCAddress(strAddr, component, nAddress) && m_pPLC) {
+		TRACE("鍦板潃瑙f瀽鎴愬姛: %s %d\n", strAddr, GetCurrentThreadId());
+		int n = m_pPLC->writeBit(component, nAddress, bOn, [](IMcChannel* pChannel, int addr, DWORD value, int flag) {
+			if (flag == 0) {
+				TRACE("鍐欏叆鎴愬姛: 鍦板潃: %d, 鍊�: %lu\n", addr, value);
+			}
+			else {
+				TRACE("鍐欏叆澶辫触: 鍦板潃: %d, 閿欒鐮�: %d\n", addr, flag);
+			}
+			});
+		TRACE("鍦板潃瑙f瀽鎴愬姛2: %d\n", n);
+	}
+
+	return 0;
+}
+
+void CIOMonitoringDlg::OnTimer(UINT_PTR nIDEvent)
+{
+	// TODO: 鍦ㄦ娣诲姞娑堟伅澶勭悊绋嬪簭浠g爜鍜�/鎴栬皟鐢ㄩ粯璁ゅ��
+	if (TIMER_READ_PLC_DATA == nIDEvent) {
+		ASSERT(m_pPLC);
+		ReadPLCStates();
+	}
+	else if (TIMER_READ_UPDATE == nIDEvent) {
+		ASSERT(m_pPLC);
+		UpdatePLCStatesToUI();
+	}
+
+	CDialogEx::OnTimer(nIDEvent);
+}
+
+void CIOMonitoringDlg::OnClose()
+{
+	// TODO: 鍦ㄦ娣诲姞娑堟伅澶勭悊绋嬪簭浠g爜鍜�/鎴栬皟鐢ㄩ粯璁ゅ��
+	KillTimer(TIMER_READ_PLC_DATA);
+	KillTimer(TIMER_READ_UPDATE);
+	CDialogEx::OnClose();
 }

--
Gitblit v1.9.3