From 592c0397bd5bc333b37b0b762b1bfeedae11f770 Mon Sep 17 00:00:00 2001
From: LAPTOP-T815PCOQ\25526 <mr.liuyang@126.com>
Date: 星期四, 09 一月 2025 19:30:16 +0800
Subject: [PATCH] 1. 添加删除目录的辅助函数 2.添加PLC列表管理 3.进一步完善输出PLC功能

---
 SourceCode/Bond/BoounionPLC/BoounionPLCDlg.cpp |    9 -
 SourceCode/Bond/BoounionPLC/Model.cpp          |   27 +++-
 SourceCode/Bond/BoounionPLC/ToolUnits.cpp      |   47 +++++++++
 SourceCode/Bond/BoounionPLC/Configuration.cpp  |  132 ++++++++++++++++++++++++++
 SourceCode/Bond/BoounionPLC/Configuration.h    |   22 ++++
 SourceCode/Bond/BoounionPLC/PagePlcList.cpp    |    9 +
 SourceCode/Bond/BoounionPLC/ToolUnits.h        |    1 
 7 files changed, 234 insertions(+), 13 deletions(-)

diff --git a/SourceCode/Bond/BoounionPLC/BoounionPLCDlg.cpp b/SourceCode/Bond/BoounionPLC/BoounionPLCDlg.cpp
index 2d941e7..1c72de5 100644
--- a/SourceCode/Bond/BoounionPLC/BoounionPLCDlg.cpp
+++ b/SourceCode/Bond/BoounionPLC/BoounionPLCDlg.cpp
@@ -489,11 +489,10 @@
 		theApp.m_model.addPlc(szName, "192.168.1.188", 1001);
 	}
 	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) {
 
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/Model.cpp b/SourceCode/Bond/BoounionPLC/Model.cpp
index b915b33..6ac7225 100644
--- a/SourceCode/Bond/BoounionPLC/Model.cpp
+++ b/SourceCode/Bond/BoounionPLC/Model.cpp
@@ -75,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;
 }
@@ -326,6 +328,11 @@
 	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;
 }
@@ -335,11 +342,15 @@
 	auto iter = m_mapPlc.find(pszName);
 	if (iter == m_mapPlc.end()) return -1;
 
-	notifyPtr(RX_CODE_REMOVE_PLC, iter->second);
-	delete iter->second;
-	m_mapPlc.erase(iter);
+	CString strDir;
+	strDir.Format(_T("%s\\PLCs\\%s"), (LPTSTR)(LPCTSTR)m_strWorkDir, (LPTSTR)(LPCTSTR)pszName);
+	CToolUnits::deleteDir(strDir);
+	m_configuration.removePLC(pszName);
 
-	m_strCurrPlc = "";
+	notifyPtr(RX_CODE_REMOVE_PLC, iter->second);
+	//delete iter->second;
+	//m_mapPlc.erase(iter);		这个地方需要研究一下
+
 	return 0;
 }
 
diff --git a/SourceCode/Bond/BoounionPLC/PagePlcList.cpp b/SourceCode/Bond/BoounionPLC/PagePlcList.cpp
index 937c6cf..a2b32ff 100644
--- a/SourceCode/Bond/BoounionPLC/PagePlcList.cpp
+++ b/SourceCode/Bond/BoounionPLC/PagePlcList.cpp
@@ -72,6 +72,15 @@
 					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();  
+					if (hSelectedItem != NULL) {
+						CPLC* pSelectedPlc = (CPLC*)m_treeCtrl.GetItemData(hSelectedItem);
+						if (pSelectedPlc != nullptr) {
+							theApp.m_model.notifyPtr(RX_CODE_SELECT_PLC, pSelectedPlc);
+						}
+					}
 				}
 			}
 
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);

--
Gitblit v1.9.3