From aedb3b85fed48cb2cf0abb5fafa8e7591644c9f4 Mon Sep 17 00:00:00 2001
From: LAPTOP-SNT8I5JK\Boounion <Chenluhua@qq.com>
Date: 星期一, 02 十二月 2024 08:53:06 +0800
Subject: [PATCH] Merge branch 'liuyang' into clh

---
 SourceCode/Bond/BondEq/View/IOMonitoringDlg.cpp |  568 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 568 insertions(+), 0 deletions(-)

diff --git a/SourceCode/Bond/BondEq/View/IOMonitoringDlg.cpp b/SourceCode/Bond/BondEq/View/IOMonitoringDlg.cpp
new file mode 100644
index 0000000..f707501
--- /dev/null
+++ b/SourceCode/Bond/BondEq/View/IOMonitoringDlg.cpp
@@ -0,0 +1,568 @@
+锘�// IOMonitoringDlg.cpp: 瀹炵幇鏂囦欢
+//
+
+#include "stdafx.h"
+#include "BondEq.h"
+#include "afxdialogex.h"
+#include "IOMonitoringDlg.h"
+#include "ToolUnits.h"
+
+#define TIMER_INIT				1
+#define TIMER_READ_PLC_DATA		2
+
+// CIOMonitoringDlg 瀵硅瘽妗�
+
+IMPLEMENT_DYNAMIC(CIOMonitoringDlg, CDialogEx)
+
+CIOMonitoringDlg::CIOMonitoringDlg(CWnd* pParent /*=nullptr*/)
+	: CDialogEx(IDD_DIALOG_IO_MONITORING, pParent)
+{
+	m_nCurrentPage = 1;
+	m_nTotalPages = 1;
+	m_nRowsPerPage = 10;
+	m_nCols = 6;
+}
+
+CIOMonitoringDlg::~CIOMonitoringDlg()
+{
+	for (auto& pair : m_mapFonts) {
+		if (pair.second) {
+			pair.second->DeleteObject();
+			delete pair.second;
+		}
+	}
+	m_mapFonts.clear();
+
+	ClearDynamicControls();
+}
+
+void CIOMonitoringDlg::DoDataExchange(CDataExchange* pDX)
+{
+	CDialogEx::DoDataExchange(pDX);
+	DDX_Control(pDX, IDC_STATIC_PAGE_NUMBER, m_staticPageNum);
+}
+
+void CIOMonitoringDlg::SetIOManager(const std::string& machineName)
+{
+	IOManager manager;
+	manager.loadFromFile(machineName);
+	m_machineName = machineName;
+
+	// 鍔犺浇鏁版嵁
+	m_displayData = manager.GetMachineData(machineName);
+
+	// 璁$畻椤垫暟
+	m_nCurrentPage = 1;
+	m_nTotalPages = (m_displayData.size() + m_nRowsPerPage - 1) / m_nRowsPerPage;
+}
+
+void CIOMonitoringDlg::SetPLC(CPLC* pPLC)
+{
+	ASSERT(pPLC);
+	m_pPLC = pPLC;
+}
+
+CFont* CIOMonitoringDlg::GetOrCreateFont(int nFontSize)
+{
+	auto it = m_mapFonts.find(nFontSize);
+	if (it != m_mapFonts.end()) {
+		return it->second;
+	}
+
+	CFont* font = new CFont();
+	LOGFONT logFont = { 0 };
+	_tcscpy_s(logFont.lfFaceName, _T("Segoe UI"));
+	logFont.lfHeight = -nFontSize;
+	logFont.lfQuality = CLEARTYPE_QUALITY;
+	font->CreateFontIndirect(&logFont);
+	m_mapFonts[nFontSize] = font;
+
+	return font;
+}
+
+void CIOMonitoringDlg::SetDefaultFont()
+{
+	CFont* defaultFont = GetOrCreateFont(12);
+
+	// 閬嶅巻鎵�鏈夋帶浠讹紝搴旂敤榛樿瀛椾綋
+	CWnd* pWnd = GetWindow(GW_CHILD);
+	while (pWnd) {
+		pWnd->SetFont(defaultFont, TRUE);
+		pWnd = pWnd->GetNextWindow();
+	}
+}
+
+void CIOMonitoringDlg::AdjustControls(float dScaleX, float dScaleY)
+{
+	CWnd* pWnd = GetWindow(GW_CHILD);
+	while (pWnd) {
+		int nCtrlID = pWnd->GetDlgCtrlID();
+		if (nCtrlID != -1 && m_mapCtrlLayouts.find(nCtrlID) != m_mapCtrlLayouts.end()) {
+			CRect originalRect = m_mapCtrlLayouts[nCtrlID];
+			CRect newRect(
+				static_cast<int>(originalRect.left * dScaleX),
+				static_cast<int>(originalRect.top * dScaleY),
+				static_cast<int>(originalRect.right * dScaleX),
+				static_cast<int>(originalRect.bottom * dScaleY));
+
+			pWnd->MoveWindow(&newRect);
+			AdjustControlFont(pWnd, newRect.Width(), newRect.Height());
+		}
+		pWnd = pWnd->GetNextWindow();
+	}
+}
+
+void CIOMonitoringDlg::AdjustControlFont(CWnd* pWnd, int nWidth, int nHeight)
+{
+	TCHAR szClassName[256];
+	GetClassName(pWnd->m_hWnd, szClassName, sizeof(szClassName));
+
+	// 鏍规嵁鎺т欢楂樺害鍔ㄦ�佽皟鏁村瓧浣撳ぇ灏�
+	int fontSize = nHeight / 2;
+	if (fontSize < 8) fontSize = 8;
+	if (fontSize < 24) fontSize = 24;
+
+	// 鑾峰彇鎴栧垱寤哄瓧浣�
+	CFont* pFont = GetOrCreateFont(fontSize);
+
+	pWnd->SetFont(pFont);
+	pWnd->Invalidate(); // 鍒锋柊鎺т欢鏄剧ず
+}
+
+void CIOMonitoringDlg::UpdatePageInfo()
+{
+	// 鏍煎紡鍖栭〉鐮佷俊鎭负 "褰撳墠椤�/鎬婚〉鏁�"
+	CString pageInfo;
+	pageInfo.Format(_T("%d/%d 椤�"), m_nCurrentPage, m_nTotalPages);
+	m_staticPageNum.SetWindowText(pageInfo);
+}
+
+void CIOMonitoringDlg::CreateDynamicControls()
+{
+	CRect rect;
+	GetClientRect(&rect);
+
+	// 鑾峰彇鎸夐挳鐨勫ぇ灏�
+	CWnd* pPrevButton = GetDlgItem(IDC_BUTTON_PREV_PAGE);
+	CWnd* pNextButton = GetDlgItem(IDC_BUTTON_NEXT_PAGE);
+
+	CRect prevButtonRect, nextButtonRect;
+	pPrevButton->GetWindowRect(&prevButtonRect);
+	pNextButton->GetWindowRect(&nextButtonRect);
+
+	// 杞崲鎸夐挳鍧愭爣鍒板璇濇鐨勫潗鏍囩郴缁�
+	ScreenToClient(&prevButtonRect);
+	ScreenToClient(&nextButtonRect);
+
+	int buttonHeight = prevButtonRect.Height();     // 鎸夐挳鐨勯珮搴�
+	int topMargin = rect.Height() * 0.05;           // 椤堕儴淇濈暀 5% 鐨勯珮搴�
+	int bottomMargin = buttonHeight + topMargin;    // 搴曢儴淇濈暀鎸夐挳楂樺害鍔犻棿璺�
+	int sideMargin = topMargin;                     // 宸﹀彸闂磋窛涓庨《閮ㄩ棿璺濈浉鍚�
+	int groupSpacing = 20;                          // 涓ょ粍涔嬮棿鐨勯棿璺�
+	int verticalSpacing = 10;                       // 鍨傜洿闂磋窛
+
+	// 姣忚楂樺害鍜屽垪瀹藉害
+	int availableHeight = rect.Height() - topMargin - bottomMargin;
+	int rowHeight = (availableHeight / m_nRowsPerPage) - verticalSpacing; // 鎺т欢楂樺害鍖呭惈闂磋窛
+
+	int availableWidth = rect.Width() - 2 * sideMargin; // 鍙敤瀹藉害锛堝噺鍘诲乏鍙抽棿璺濓級
+	int colWidthSmall = availableWidth / 14;			// 灏忓搴﹀垪鏇村皬
+	int colWidthLarge = availableWidth * 4 / 14;		// 澶у搴﹀垪姣斾緥
+	int groupWidth = colWidthSmall * 2 + colWidthLarge; // 姣忕粍鎬诲搴�
+
+	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, AlignCenter);
+		x += colWidthSmall;
+		CreateStaticControl(x, y, colWidthSmall, rowHeight, _T("X1000"), false, AlignCenter);
+		x += colWidthSmall;
+		CreateStaticControl(x, y, colWidthLarge, rowHeight, _T("鎻忚堪鏂囨湰"), false);
+
+		// 绗� 2 缁勮捣濮嬩綅缃紝鍔犱笂缁勯棿璺�
+		x += colWidthLarge + groupSpacing;
+
+		// 鍒涘缓绗� 2 缁� (3, 4, 5)
+		CreateStaticControl(x, y, colWidthSmall, rowHeight, _T("OFF"), true, AlignCenter, [this, i]() {
+			// 鑷畾涔夌偣鍑讳簨浠剁殑閫昏緫
+			auto* pControl = static_cast<CBLLabel*>(m_staticControls[i * m_nCols + 3]);
+			CString currentText;
+			pControl->GetWindowText(currentText);
+
+			BOOL bOn = FALSE;
+			if (currentText == _T("OFF")) {
+				//pControl->SetBkColor(RGB(0, 255, 0)); // 缁胯壊鑳屾櫙
+				//pControl->SetText(_T("ON"));          // 鏇存柊鏂囨湰涓� ON
+				bOn = TRUE;
+			}
+			else {
+				//pControl->SetBkColor(RGB(255, 0, 0)); // 绾㈣壊鑳屾櫙
+				//pControl->SetText(_T("OFF"));         // 鏇存柊鏂囨湰涓� OFF
+				bOn = FALSE;
+			}
+
+			pControl = static_cast<CBLLabel*>(m_staticControls[i * m_nCols + 4]);
+			pControl->GetWindowText(currentText);
+
+			int nAddress;
+			MC::SOFT_COMPONENT component;
+			if (ParsePLCAddress(currentText, component, nAddress) && m_pPLC) {
+				TRACE("鍦板潃瑙f瀽鎴愬姛: %s\n", currentText);
+				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);
+					}
+				});
+			}
+		});
+		x += colWidthSmall;
+		CreateStaticControl(x, y, colWidthSmall, rowHeight, _T("Y1010"), false, AlignCenter);
+		x += colWidthSmall;
+		CreateStaticControl(x, y, colWidthLarge, rowHeight, _T("鎻忚堪鏂囨湰"), false);
+	}
+}
+
+void CIOMonitoringDlg::CreateStaticControl(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; // 娣诲姞杈规
+	}
+	pStatic->Create(text, style, CRect(x, y, x + width, y + height), this);
+
+	// 璁剧疆鏂囨湰瀵归綈鏂瑰紡
+	pStatic->SetAlignment(alignment);
+
+	// 璁剧疆鍔ㄦ�佸瓧浣撹皟鏁达紝骞惰缃瓧浣撳ぇ灏忥紙鍔ㄦ�佸瓧浣撲細鏍规嵁鎺т欢澶у皬璋冩暣锛�
+	int nSize = height / 3;
+	CFont* pFont = GetOrCreateFont(nSize);
+	pStatic->SetFont(pFont);
+	pStatic->SetFontSize(nSize);
+	pStatic->SetDynamicFont(TRUE);
+
+	// 璁剧疆鍥炶皟
+	if (clickCallback) {
+		pStatic->SetClickCallback(clickCallback);
+	}
+
+	// 瀛樺偍鎺т欢鎸囬拡
+	m_staticControls.push_back(pStatic);
+}
+
+void CIOMonitoringDlg::DisplayCurrentPage()
+{
+	int startIndex = (m_nCurrentPage - 1) * m_nRowsPerPage;
+	int endIndex = min(startIndex + m_nRowsPerPage, static_cast<int>(m_displayData.size()));
+
+	m_inputPLCAddresses.clear();
+	m_outputPLCAddresses.clear();
+
+	for (int i = 0; i < m_nRowsPerPage; ++i) {
+		int row = i;
+
+		if (startIndex + i < endIndex) {
+			const auto& data = m_displayData[startIndex + i];
+
+			// 娣诲姞 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) {
+			pStatic->DestroyWindow();
+			delete pStatic;
+		}
+	}
+	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];
+	switch (componentChar) {
+	case 'D':
+		component = MC::SOFT_COMPONENT::D;
+		break;
+	case 'M':
+		component = MC::SOFT_COMPONENT::M;
+		break;
+	case 'X':
+		component = MC::SOFT_COMPONENT::X;
+		break;
+	case 'Y':
+		component = MC::SOFT_COMPONENT::Y;
+		break;
+	default:
+		return false;
+	}
+
+	CString hexAddress = address.Mid(1);
+	addr = _tcstoul(hexAddress, nullptr, 16);
+
+	return true;
+}
+
+void CIOMonitoringDlg::UpdatePLCStates()
+{
+	// 绀轰緥锛氫粠 PLC 鑾峰彇鍊硷紝杩欓噷鐢ㄩ殢鏈哄�兼ā鎷�
+	//for (size_t i = 0; i < m_inputPLCAddresses.size(); ++i) {
+	//	// 妯℃嫙鑾峰彇杈撳叆鐘舵��
+	//	bool inputState = (rand() % 2 == 0); // 鍋跺皵涓� true/false
+	//	auto* inputControl = static_cast<CBLLabel*>(m_staticControls[i * m_nCols + 0]);
+	//	inputControl->SetBkColor(inputState ? RGB(0, 255, 0) : RGB(255, 0, 0));
+	//	inputControl->SetText(inputState ? _T("ON") : _T("OFF"));
+	//}
+
+	//for (size_t i = 0; i < m_outputPLCAddresses.size(); ++i) {
+	//	// 妯℃嫙鑾峰彇杈撳嚭鐘舵��
+	//	bool outputState = (rand() % 2 == 0); // 鍋跺皵涓� true/false
+	//	auto* outputControl = static_cast<CBLLabel*>(m_staticControls[i * m_nCols + 3]);
+	//	outputControl->SetBkColor(outputState ? RGB(0, 255, 0) : RGB(255, 0, 0));
+	//	outputControl->SetText(outputState ? _T("ON") : _T("OFF"));
+	//}
+
+	// 杈撳叆鍦板潃鐨勮鍙�
+	if (!m_inputPLCAddresses.empty()) {
+		// 鑾峰彇璧峰鍦板潃鍜岄暱搴�
+		CString startAddressStr = m_inputPLCAddresses.front();
+		CString endAddressStr = m_inputPLCAddresses.back();
+		MC::SOFT_COMPONENT component;
+		int startAddress, endAddress;
+
+		// 瑙f瀽璧峰鍜岀粨鏉熷湴鍧�
+		if (ParsePLCAddress(startAddressStr, component, startAddress) &&
+			ParsePLCAddress(endAddressStr, component, endAddress)) {
+			int inputSize = endAddress - startAddress + 1;
+
+			// 鍥炶皟澶勭悊杈撳叆鏁版嵁
+			auto funOnReadInput = [this, startAddress](IMcChannel* pChannel, int addr, char* pData, unsigned int nDataSize, int flag) {
+				if (nDataSize == (unsigned int)(m_inputPLCAddresses.size()) && flag == 0) {
+					for (size_t i = 0; i < m_inputPLCAddresses.size(); ++i) {
+						int offset = i;
+						int value = CToolUnits::toInt16(&pData[offset]);
+
+						auto* inputControl = static_cast<CBLLabel*>(m_staticControls[i * m_nCols + 0]); // 绗� 0 鍒�
+						inputControl->SetBkColor(value ? RGB(0, 255, 0) : RGB(255, 0, 0)); // 鏇存柊鑳屾櫙棰滆壊
+						inputControl->SetText(value ? _T("ON") : _T("OFF"));               // 鏇存柊鏂囨湰
+					}
+				}
+			};
+
+			// 璇诲彇杈撳叆鏁版嵁
+			m_pPLC->readData(component, startAddress, inputSize, funOnReadInput);
+		}
+	}
+
+	// 杈撳嚭鍦板潃鐨勮鍙�
+	if (!m_outputPLCAddresses.empty()) {
+		// 鑾峰彇璧峰鍦板潃鍜岄暱搴�
+		CString startAddressStr = m_outputPLCAddresses.front();
+		CString endAddressStr = m_outputPLCAddresses.back();
+		MC::SOFT_COMPONENT component;
+		int startAddress, endAddress;
+
+		// 瑙f瀽璧峰鍜岀粨鏉熷湴鍧�
+		if (ParsePLCAddress(startAddressStr, component, startAddress) &&
+			ParsePLCAddress(endAddressStr, component, endAddress)) {
+			int outputSize = endAddress - startAddress + 1;
+
+			// 鍥炶皟澶勭悊杈撳嚭鏁版嵁
+			auto funOnReadOutput = [this, startAddress](IMcChannel* pChannel, int addr, char* pData, unsigned int nDataSize, int flag) {
+				if (nDataSize == (unsigned int)(m_outputPLCAddresses.size()) && flag == 0) {
+					for (size_t i = 0; i < m_outputPLCAddresses.size(); ++i) {
+						int offset = i;
+						int value = CToolUnits::toInt16(&pData[offset]);
+
+						auto* outputControl = static_cast<CBLLabel*>(m_staticControls[i * m_nCols + 3]); // 绗� 3 鍒�
+						outputControl->SetBkColor(value ? RGB(0, 255, 0) : RGB(255, 0, 0)); // 鏇存柊鑳屾櫙棰滆壊
+						outputControl->SetText(value ? _T("ON") : _T("OFF"));               // 鏇存柊鏂囨湰
+					}
+				}
+			};
+
+			// 璇诲彇杈撳嚭鏁版嵁
+			m_pPLC->readData(component, startAddress, outputSize, funOnReadOutput);
+		}
+	}
+}
+
+BEGIN_MESSAGE_MAP(CIOMonitoringDlg, CDialogEx)
+	ON_BN_CLICKED(IDC_BUTTON_PREV_PAGE, &CIOMonitoringDlg::OnBnClickedButtonPrevPage)
+	ON_BN_CLICKED(IDC_BUTTON_NEXT_PAGE, &CIOMonitoringDlg::OnBnClickedButtonNextPage)
+	ON_WM_SIZE()
+	ON_WM_TIMER()
+	ON_WM_CLOSE()
+END_MESSAGE_MAP()
+
+
+// CIOMonitoringDlg 娑堟伅澶勭悊绋嬪簭
+
+
+BOOL CIOMonitoringDlg::OnInitDialog()
+{
+	CDialogEx::OnInitDialog();
+
+	// TODO:  鍦ㄦ娣诲姞棰濆鐨勫垵濮嬪寲
+	CRect screenRect, dlgRect, clientRect;
+	SystemParametersInfo(SPI_GETWORKAREA, 0, &screenRect, 0);
+
+	GetClientRect(&clientRect);
+	m_nInitialWidth = clientRect.Width();
+	m_nInitialHeight = clientRect.Height();
+
+	// 鍒濆鍖栭粯璁ゅ瓧浣�
+	CFont* pDefaultFont = GetOrCreateFont(12);
+
+	// 閬嶅巻鎵�鏈夊瓙鎺т欢锛岃褰曞垵濮嬩綅缃苟璁剧疆榛樿瀛椾綋
+	CWnd* pWnd = GetWindow(GW_CHILD);
+	while (pWnd) {
+		int nCtrlID = pWnd->GetDlgCtrlID();
+		if (nCtrlID != -1) {
+			// 璁板綍鎺т欢鍒濆甯冨眬
+			CRect ctrlRect;
+			pWnd->GetWindowRect(&ctrlRect);
+			ScreenToClient(&ctrlRect);
+			m_mapCtrlLayouts[nCtrlID] = ctrlRect;
+
+			// 璺宠繃鐗规畩鎺т欢锛堝 MFCGridCtrl锛�
+			TCHAR szClassName[256];
+			GetClassName(pWnd->m_hWnd, szClassName, sizeof(szClassName));
+			if (_tcsicmp(szClassName, _T("MFCGridCtrl")) == 0) {
+				pWnd = pWnd->GetNextWindow();
+				continue;
+			}
+
+			// 璁剧疆榛樿瀛椾綋
+			pWnd->SetFont(pDefaultFont);
+		}
+		pWnd = pWnd->GetNextWindow();
+	}
+
+	GetWindowRect(&dlgRect);
+	int dlgWidth = dlgRect.Width() * 2;
+	int dlgHeight = dlgRect.Height() * 2;
+
+	if (dlgWidth > screenRect.Width()) {
+		dlgWidth = screenRect.Width();
+	}
+	if (dlgHeight > screenRect.Height()) {
+		dlgHeight = screenRect.Height();
+	}
+
+	int centerX = screenRect.left + (screenRect.Width() - dlgWidth) / 2;
+	int centerY = screenRect.top + (screenRect.Height() - dlgHeight) / 2;
+	MoveWindow(centerX, centerY, dlgWidth, dlgHeight);
+
+	CreateDynamicControls();
+	DisplayCurrentPage();
+
+	SetTimer(TIMER_READ_PLC_DATA, 500, nullptr);
+
+	return TRUE;  // return TRUE unless you set the focus to a control
+	// 寮傚父: OCX 灞炴�ч〉搴旇繑鍥� FALSE
+}
+
+void CIOMonitoringDlg::OnSize(UINT nType, int cx, int cy)
+{
+	CDialogEx::OnSize(nType, cx, cy);
+
+	// TODO: 鍦ㄦ澶勬坊鍔犳秷鎭鐞嗙▼搴忎唬鐮�
+	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(dScaleX, dScaleY);
+}
+
+void CIOMonitoringDlg::OnBnClickedButtonPrevPage()
+{
+	// TODO: 鍦ㄦ娣诲姞鎺т欢閫氱煡澶勭悊绋嬪簭浠g爜
+	if (m_nCurrentPage > 1) {
+		--m_nCurrentPage;
+		DisplayCurrentPage();
+	}
+	else {
+		AfxMessageBox(_T("宸茬粡鏄涓�椤碉紒"));
+	}
+}
+
+void CIOMonitoringDlg::OnBnClickedButtonNextPage()
+{
+	// TODO: 鍦ㄦ娣诲姞鎺т欢閫氱煡澶勭悊绋嬪簭浠g爜
+	if (m_nCurrentPage < m_nTotalPages) {
+		++m_nCurrentPage;
+		DisplayCurrentPage();
+	}
+	else {
+		AfxMessageBox(_T("宸茬粡鏄渶鍚庝竴椤碉紒"));
+	}
+}
+
+void CIOMonitoringDlg::OnTimer(UINT_PTR nIDEvent)
+{
+	// TODO: 鍦ㄦ娣诲姞娑堟伅澶勭悊绋嬪簭浠g爜鍜�/鎴栬皟鐢ㄩ粯璁ゅ��
+	if (TIMER_READ_PLC_DATA == nIDEvent) {
+		ASSERT(m_pPLC);
+		UpdatePLCStates();
+		Sleep(100);
+	}
+	CDialogEx::OnTimer(nIDEvent);
+}
+
+void CIOMonitoringDlg::OnClose()
+{
+	// TODO: 鍦ㄦ娣诲姞娑堟伅澶勭悊绋嬪簭浠g爜鍜�/鎴栬皟鐢ㄩ粯璁ゅ��
+	KillTimer(TIMER_READ_PLC_DATA);
+	CDialogEx::OnClose();
+}

--
Gitblit v1.9.3