1. 添加删除目录的辅助函数
2.添加PLC列表管理
3.进一步完善输出PLC功能
| | |
| | | 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) { |
| | | |
| | |
| | | CConfiguration::CConfiguration(const char* pszFilepath) |
| | | { |
| | | m_strFilepath = pszFilepath; |
| | | loadPLCListFromFile(); |
| | | } |
| | | |
| | | CConfiguration::~CConfiguration() |
| | |
| | | void CConfiguration::setFilepath(const char* pszFilepath) |
| | | { |
| | | m_strFilepath = pszFilepath; |
| | | loadPLCListFromFile(); |
| | | } |
| | | |
| | | void CConfiguration::getUnitId(CString& strUnitId) |
| | |
| | | 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); |
| | | } |
| | | } |
| | | |
| | |
| | | #pragma once |
| | | #include <vector> |
| | | #include <string> |
| | | #include <algorithm> |
| | | |
| | | // PLC信息 |
| | | struct PlcInfo { |
| | | CString strName; // PLC 名称 |
| | | CString strIp; // IP 地址 |
| | | UINT nPort; // 端口号 |
| | | }; |
| | | |
| | | class CConfiguration |
| | | { |
| | |
| | | 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; |
| | | }; |
| | | |
| | |
| | | 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; |
| | | } |
| | |
| | | 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; |
| | | } |
| | |
| | | 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; |
| | | } |
| | | |
| | |
| | | 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); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | 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); |
| | |
| | | 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); |