| SourceCode/Bond/SGMeasurement/Logger.cpp | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| SourceCode/Bond/SGMeasurement/PLCSignalListener.cpp | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| SourceCode/Bond/SGMeasurement/PLCSignalListener.h | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| SourceCode/Bond/SGMeasurement/SGMeasurement.cpp | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| SourceCode/Bond/SGMeasurement/SGMeasurement.rc | 补丁 | 查看 | 原始文档 | blame | 历史 | |
| SourceCode/Bond/SGMeasurement/SGMeasurement.vcxproj | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| SourceCode/Bond/SGMeasurement/SGMeasurement.vcxproj.filters | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| SourceCode/Bond/SGMeasurement/SGMeasurement.vcxproj.user | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| SourceCode/Bond/SGMeasurement/SGMeasurementDlg.cpp | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| SourceCode/Bond/SGMeasurement/SGMeasurementDlg.h | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| SourceCode/Bond/SGMeasurement/res/menu_open_dir.ico | 补丁 | 查看 | 原始文档 | blame | 历史 | |
| SourceCode/Bond/SGMeasurement/resource.h | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
SourceCode/Bond/SGMeasurement/Logger.cpp
@@ -21,8 +21,17 @@ { CSingleLock lock(&m_csLogLock, TRUE); TCHAR szPath[MAX_PATH] = { 0 }; GetModuleFileName(NULL, szPath, MAX_PATH); CString strPath = szPath; int pos = strPath.ReverseFind('\\'); if (pos != -1) { strPath = strPath.Left(pos + 1); } CTime now = CTime::GetCurrentTime(); CString strLogDir = _T("Log"); CString strLogDir = strPath + _T("Log"); if (!PathFileExists(strLogDir)) { CreateDirectory(strLogDir, NULL); @@ -37,8 +46,7 @@ m_logFile.Close(); } if (m_logFile.Open(strNewPath, CFile::modeCreate | CFile::modeNoTruncate | CFile::modeWrite | CFile::typeBinary)) { if (m_logFile.Open(strNewPath, CFile::modeCreate | CFile::modeNoTruncate | CFile::modeWrite | CFile::typeBinary | CFile::shareDenyWrite)) { if (m_logFile.GetLength() == 0) { WCHAR bom = 0xFEFF; SourceCode/Bond/SGMeasurement/PLCSignalListener.cpp
@@ -255,7 +255,7 @@ std::string strProductID; if (ReadProductID(strProductID)) { CString msg; msg.Format(_T("读取到产品ID:%s"), strProductID); msg.Format(_T("读取到产品ID:%s"), CString(strProductID.c_str())); LOG_MSG(msg, LOG_TYPE_SUCCESS); } } @@ -309,15 +309,22 @@ } for (int i = 0; i < PLC_RESULT_ADDR_COUNT; ++i) { // 放大1000倍并四舍五入,转为PLC整数 int32_t nScaled = static_cast<int32_t>(std::round(values[i] * 1000.0)); DWordContainer vec = { static_cast<uint32_t>(nScaled) }; double dVal = values[i]; int32_t nScaled = 0; if (dVal == DBL_MAX || dVal == DBL_MIN || std::isnan(dVal)) { nScaled = static_cast<int32_t>(dVal); } else { nScaled = static_cast<int32_t>(std::round(dVal * 1000.0)); } short nTargetAddr = PLC_RESULT_ADDR_START + i * 2; DWordContainer vec = { static_cast<uint32_t>(nScaled) }; int ret = m_pPlc->WriteDWordDataEx(m_station, PLC_WORD_DEVICE_TYPE, nTargetAddr, vec); if (ret != 0) { CString msg; msg.Format(_T("写入OUT%d到地址%d失败,值=%.2f"), i + 1, nTargetAddr, values[i]); msg.Format(_T("写入OUT%d到地址%d失败,值=%.2f"), i + 1, nTargetAddr, dVal); LOG_MSG(msg, LOG_TYPE_ERROR); return false; } @@ -360,4 +367,43 @@ } return true; } bool CPLCSignalListener::WriteProductID(const std::string& strProductID) { if (!m_pPlc || !m_bConnected) { LOG_MSG(_T("PLC未连接或未初始化,无法写入产品ID。"), LOG_TYPE_ERROR); return false; } WordContainer vec; vec.reserve(PLC_PRODUCT_ID_WORDS); for (size_t i = 0; i < strProductID.size();) { unsigned char c1 = static_cast<unsigned char>(strProductID[i]); unsigned char c2 = 0; if (i + 1 < strProductID.size()) { c2 = static_cast<unsigned char>(strProductID[i + 1]); } uint16_t w = static_cast<uint16_t>(c2 << 8 | c1); vec.push_back(w); i += 2; } while (vec.size() < PLC_PRODUCT_ID_WORDS) { vec.push_back(0); } int ret = m_pPlc->WriteWordDataEx(m_station, PLC_WORD_DEVICE_TYPE, PLC_PRODUCT_ID_ADDR, vec); if (ret != 0) { CString msg; msg.Format(_T("写入产品ID失败,错误码=%d"), ret); LOG_MSG(msg, LOG_TYPE_ERROR); return false; } return true; } SourceCode/Bond/SGMeasurement/PLCSignalListener.h
@@ -87,6 +87,17 @@ */ bool ReadProductID(std::string& strProductID); /** * @brief 将产品 ID(字符串形式)写入 PLC 内部。 * * @param strProductID 输入参数,要写入的产品 ID。 * 字符串会按字节对齐,每两个字节组成一个 Word, * 写入 PLC 的指定寄存器区域,不足时自动补零。 * @return true 写入成功。 * @return false 写入失败。 */ bool WriteProductID(const std::string& strProductID); private: /** * @brief 输出日志信息(封装日志回调)。 SourceCode/Bond/SGMeasurement/SGMeasurement.cpp
@@ -103,7 +103,7 @@ CWinApp::InitInstance(); // 唯一实例运行检测 m_hMutex = ::CreateMutex(NULL, FALSE, _T("MutexEdgeInspector_App")); m_hMutex = ::CreateMutex(NULL, FALSE, _T("MutexSGMeasurementApp")); if (m_hMutex != NULL) { if (::GetLastError() == ERROR_ALREADY_EXISTS) { AfxMessageBox(_T("The Program is already running. Exit this Program."), MB_OK | MB_ICONERROR); SourceCode/Bond/SGMeasurement/SGMeasurement.rcBinary files differ
SourceCode/Bond/SGMeasurement/SGMeasurement.vcxproj
@@ -238,6 +238,7 @@ </ItemGroup> <ItemGroup> <Image Include="res\menu_close.ico" /> <Image Include="res\menu_open_dir.ico" /> <Image Include="res\menu_restore.ico" /> <Image Include="res\SGMeasurement.ico" /> </ItemGroup> SourceCode/Bond/SGMeasurement/SGMeasurement.vcxproj.filters
@@ -98,5 +98,8 @@ <Image Include="res\menu_close.ico"> <Filter>资源文件</Filter> </Image> <Image Include="res\menu_open_dir.ico"> <Filter>资源文件</Filter> </Image> </ItemGroup> </Project> SourceCode/Bond/SGMeasurement/SGMeasurement.vcxproj.user
@@ -4,12 +4,12 @@ <RESOURCE_FILE>SGMeasurement.rc</RESOURCE_FILE> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> <DebuggerFlavor>WindowsRemoteDebugger</DebuggerFlavor> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <RemoteDebuggerCommand>\\DESKTOP-IODBVIQ\SGMeasurement\$(ProjectName).exe</RemoteDebuggerCommand> <RemoteDebuggerWorkingDirectory>\\DESKTOP-IODBVIQ\SGMeasurement</RemoteDebuggerWorkingDirectory> <RemoteDebuggerServerName>DESKTOP-IODBVIQ</RemoteDebuggerServerName> <DebuggerFlavor>WindowsRemoteDebugger</DebuggerFlavor> <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> </PropertyGroup> </Project> SourceCode/Bond/SGMeasurement/SGMeasurementDlg.cpp
@@ -17,6 +17,7 @@ #define DeviceID 0 // 托盘图标 ID 与消息宏 #define ID_TRAY_OPEN_DIR 2000 // 打开目录 #define ID_TRAY_RESTORE 2001 // 恢复窗口 #define ID_TRAY_EXIT 2002 // 退出程序 #define WM_TRAY_ICON_NOTIFY (WM_USER + 1000) // 托盘图标回调消息 ID @@ -94,6 +95,7 @@ , m_nTrayIconID(0) , m_bTrayIconCreated(FALSE) , m_bExitingFromTray(FALSE) , m_nAutoStart(TRUE) { m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } @@ -131,6 +133,9 @@ } m_plcListener.Stop(); // 保存配置文件 SaveConfig(GetConfigPath()); DestroyWindow(); CDialogEx::OnClose(); @@ -301,6 +306,134 @@ strLine.Empty(); } } } CString CSGMeasurementDlg::GetAppDirectory() { TCHAR szPath[MAX_PATH] = { 0 }; GetModuleFileName(NULL, szPath, MAX_PATH); CString strPath = szPath; int pos = strPath.ReverseFind('\\'); if (pos != -1) { strPath = strPath.Left(pos + 1); } return strPath; } CString CSGMeasurementDlg::GetConfigPath() { return GetAppDirectory() + _T("SGConfig.ini"); } bool CSGMeasurementDlg::LoadConfig(const CString& strFile) { CString strSection = _T("StorageConfig"); TCHAR buf[256]; GetPrivateProfileString(strSection, _T("UseTrigger"), _T("0"), buf, 256, strFile); m_nUseTrigger = _ttoi(buf); GetPrivateProfileString(strSection, _T("SavePointCount"), _T("100000"), buf, 256, strFile); m_nSavePointCount = _ttoi(buf); // 输出端口 GetPrivateProfileString(strSection, _T("OutputPort"), _T("OUT1"), buf, 256, strFile); { int idx = m_comboOutputPort.FindStringExact(-1, buf); if (idx != CB_ERR) { m_comboOutputPort.SetCurSel(idx); } else { m_comboOutputPort.SetCurSel(0); } } // 跳变检测参数 GetPrivateProfileString(strSection, _T("JumpThreshold"), _T("0.2"), buf, 256, strFile); m_fJumpThreshold = static_cast<float>(_tstof(buf)); GetPrivateProfileString(strSection, _T("JumpWindow"), _T("3"), buf, 256, strFile); m_nJumpWindow = _ttoi(buf); GetPrivateProfileString(strSection, _T("ValleyMargin"), _T("0"), buf, 256, strFile); m_nValleyMargin = _ttoi(buf); GetPrivateProfileString(strSection, _T("MinGlass1Count"), _T("10"), buf, 256, strFile); m_nMinGlass1Count = _ttoi(buf); // 稳定区域参数 GetPrivateProfileString(strSection, _T("FixedCount"), _T("5"), buf, 256, strFile); m_nFixedCount = _ttoi(buf); GetPrivateProfileString(strSection, _T("MaxDelta"), _T("0.05"), buf, 256, strFile); m_fMaxDelta = static_cast<float>(_tstof(buf)); // 自启动 GetPrivateProfileString(strSection, _T("AutoStart"), _T("1"), buf, 256, strFile); m_nAutoStart = _ttoi(buf); return true; } bool CSGMeasurementDlg::SaveConfig(const CString& strFile) { CString strSection = _T("StorageConfig"); WritePrivateProfileString(strSection, _T("UseTrigger"), std::to_wstring(m_nUseTrigger).c_str(), strFile); WritePrivateProfileString(strSection, _T("SavePointCount"), std::to_wstring(m_nSavePointCount).c_str(), strFile); // 输出端口下拉框 CString strPort; m_comboOutputPort.GetWindowText(strPort); WritePrivateProfileString(strSection, _T("OutputPort"), strPort, strFile); // 跳变检测 WritePrivateProfileString(strSection, _T("JumpThreshold"), std::to_wstring(m_fJumpThreshold).c_str(), strFile); WritePrivateProfileString(strSection, _T("JumpWindow"), std::to_wstring(m_nJumpWindow).c_str(), strFile); WritePrivateProfileString(strSection, _T("ValleyMargin"), std::to_wstring(m_nValleyMargin).c_str(), strFile); WritePrivateProfileString(strSection, _T("MinGlass1Count"), std::to_wstring(m_nMinGlass1Count).c_str(), strFile); // 稳定区 WritePrivateProfileString(strSection, _T("FixedCount"), std::to_wstring(m_nFixedCount).c_str(), strFile); WritePrivateProfileString(strSection, _T("MaxDelta"), std::to_wstring(m_fMaxDelta).c_str(), strFile); // 自启动 WritePrivateProfileString(strSection, _T("AutoStart"), std::to_wstring(m_nAutoStart).c_str(), strFile); return true; } bool CSGMeasurementDlg::SetAutoStart(bool bEnable) { // 获取当前程序路径 TCHAR szPath[MAX_PATH] = { 0 }; GetModuleFileName(NULL, szPath, MAX_PATH); CString strAppPath = szPath; // 获取应用程序名称 CString strAppName = ::PathFindFileName(strAppPath); strAppName = strAppName.Left(strAppName.ReverseFind('.')); HKEY hKey; LONG lRet = RegOpenKeyEx(HKEY_CURRENT_USER, _T("Software\\Microsoft\\Windows\\CurrentVersion\\Run"), 0, KEY_WRITE, &hKey); if (lRet != ERROR_SUCCESS) { return false; } if (bEnable) { // 设置自启 lRet = RegSetValueEx(hKey, strAppName, 0, REG_SZ, (BYTE*)(LPCTSTR)strAppPath, (strAppPath.GetLength() + 1) * sizeof(TCHAR)); } else { // 取消自启 lRet = RegDeleteValue(hKey, strAppName); } RegCloseKey(hKey); return (lRet == ERROR_SUCCESS); } bool CSGMeasurementDlg::ConnectToDevice() @@ -715,7 +848,7 @@ return false; } float CSGMeasurementDlg::AnalyzeStoredData(int nOutNo) double CSGMeasurementDlg::AnalyzeStoredData(int nOutNo) { MEASURE_FUNC_START(); @@ -724,27 +857,27 @@ if (m_nUseTrigger) { UpdateControlStatus(m_bConnected, m_bSaving); AfxMessageBox(_T("当前是硬触发模式,请检查触发器状态。"), MB_ICONINFORMATION); return 0xFF; return DBL_MAX; } if (!m_bConnected) { AppendLogLineRichStyled(_T("设备未连接,请先连接设备。"), LOG_COLOR_WARNING); return 0xFF; return DBL_MAX; } if (m_bSaving) { AppendLogLineRichStyled(_T("数据存储正在进行中,请先停止存储。"), LOG_COLOR_WARNING); return 0xFF; return DBL_MAX; } if (nOutNo < 1 || nOutNo > 4) { AppendLogLineRichStyled(_T("输出端口编号无效,必须在 1 到 4 之间。"), LOG_COLOR_ERROR); return 0xFF; return DBL_MAX; } if (m_nSavePointCount < 0) { AppendLogLineRichStyled(_T("数据点数必须大于 0。"), LOG_COLOR_ERROR); return 0xFF; return DBL_MAX; } std::vector<float> vecBuffer(m_nSavePointCount, 0.0f); @@ -755,7 +888,7 @@ CString strError; strError.Format(_T("读取 OUT%d 数据失败,错误码:%#X"), nOutNo, nRet); AppendLogLineRichStyled(strError, LOG_COLOR_ERROR); return 0xFF; return DBL_MAX; } vecBuffer.resize(nReceived); @@ -764,7 +897,7 @@ std::vector<float> vecGlass1, vecGlass2; if (!SplitGlassSegments(nOutNo, vecBuffer, vecGlass1, vecGlass2, m_fJumpThreshold, m_nJumpWindow, m_nValleyMargin, m_nMinGlass1Count)) { AppendLogLineRichStyled(_T("未能识别出两片玻璃的数据。"), LOG_COLOR_WARNING); return 0xFF; return DBL_MAX; } std::vector<float> vecGlass1Filtered, vecGlass2Filtered; @@ -815,6 +948,7 @@ ON_WM_DRAWITEM() ON_WM_CLOSE() ON_MESSAGE(WM_TRAY_ICON_NOTIFY, &CSGMeasurementDlg::OnTrayIconClick) ON_COMMAND(ID_TRAY_OPEN_DIR, &CSGMeasurementDlg::OnTrayOpenDir) ON_COMMAND(ID_TRAY_RESTORE, &CSGMeasurementDlg::OnTrayRestore) ON_COMMAND(ID_TRAY_EXIT, &CSGMeasurementDlg::OnTrayExit) ON_BN_CLICKED(IDC_BUTTON_CONNECT, &CSGMeasurementDlg::OnBnClickedButtonConnect) @@ -924,7 +1058,7 @@ m_plcListener.SetAnalyzeCallback([this]() { if (!m_bConnected) { AppendLogLineRichStyled(_T("设备未连接,请先连接设备。"), LOG_COLOR_WARNING); return std::array<double, 4>{ 0xFF, 0xFF, 0xFF, 0xFF }; return std::array<double, 4>{ DBL_MAX, DBL_MAX, DBL_MAX, DBL_MAX }; } std::array<double, 4> result; @@ -941,6 +1075,27 @@ return result; }); m_plcListener.Start(); // 加载配置文件 if (LoadConfig(GetConfigPath())) { AppendLogLineRichStyled(_T("配置已从 SGConfig.ini 加载成功"), LOG_COLOR_SUCCESS); } else { AppendLogLineRichStyled(_T("配置加载失败,使用默认参数"), LOG_COLOR_WARNING); } // 设置自动启动 if (SetAutoStart(m_nAutoStart)) { if (m_nAutoStart) { AppendLogLineRichStyled(_T("已启用开机自启动"), LOG_COLOR_SUCCESS); } else { AppendLogLineRichStyled(_T("已取消开机自启动"), LOG_COLOR_WARNING); } } else { AppendLogLineRichStyled(_T("设置开机自启动失败,请检查权限"), LOG_COLOR_ERROR); } // 初始化日志框 AppendLogLineRichStyled(_T("准备就绪..."), LOG_COLOR_SUCCESS); @@ -1053,6 +1208,10 @@ // 图标 HICON hIcon = nullptr; if (id == ID_TRAY_OPEN_DIR) { hIcon = AfxGetApp()->LoadIcon(IDI_ICON_OPEN_DIR); } if (id == ID_TRAY_RESTORE) { hIcon = AfxGetApp()->LoadIcon(IDI_ICON_RESTORE); } @@ -1067,6 +1226,10 @@ // 文本 CString str; if (id == ID_TRAY_OPEN_DIR) { str = _T("打开目录"); } if (id == ID_TRAY_RESTORE) { str = _T("恢复界面"); } @@ -1110,22 +1273,23 @@ // 右键点击弹出菜单 CMenu menu; menu.CreatePopupMenu(); menu.AppendMenu(MF_OWNERDRAW, ID_TRAY_OPEN_DIR, (LPCTSTR)ID_TRAY_OPEN_DIR); menu.AppendMenu(MF_OWNERDRAW, ID_TRAY_RESTORE, (LPCTSTR)ID_TRAY_RESTORE); menu.AppendMenu(MF_OWNERDRAW, ID_TRAY_EXIT, (LPCTSTR)ID_TRAY_EXIT); // 加载图标 HICON hIconRestore = (HICON)::LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDI_ICON_RESTORE), IMAGE_ICON, 16, 16, LR_SHARED); HICON hIconExit = (HICON)::LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDI_ICON_EXIT), IMAGE_ICON, 16, 16, LR_SHARED); // 设置图标到菜单项 MENUITEMINFO mii = { sizeof(MENUITEMINFO) }; mii.fMask = MIIM_BITMAP; // 恢复菜单项图标 // 打开目录菜单项图标 mii.hbmpItem = HBMMENU_CALLBACK; menu.SetMenuItemInfo(ID_TRAY_OPEN_DIR, &mii); // 恢复窗口菜单项图标 mii.hbmpItem = HBMMENU_CALLBACK; menu.SetMenuItemInfo(ID_TRAY_RESTORE, &mii); // 退出菜单项图标 // 退出程序菜单项图标 mii.hbmpItem = HBMMENU_CALLBACK; menu.SetMenuItemInfo(ID_TRAY_EXIT, &mii); @@ -1139,6 +1303,18 @@ return 0; } void CSGMeasurementDlg::OnTrayOpenDir() { CString strDir = GetAppDirectory(); if (PathFileExists(strDir)) { ShellExecute(NULL, _T("open"), strDir, NULL, NULL, SW_SHOWDEFAULT); AppendLogLineRichStyled(_T("已打开程序目录"), LOG_COLOR_SUCCESS); } else { AppendLogLineRichStyled(_T("目录不存在,无法打开"), LOG_COLOR_ERROR); } } void CSGMeasurementDlg::OnTrayRestore() { ShowWindow(SW_SHOW); // 恢复窗口 SourceCode/Bond/SGMeasurement/SGMeasurementDlg.h
@@ -41,6 +41,7 @@ afx_msg void OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct); afx_msg void OnClose(); afx_msg LRESULT OnTrayIconClick(WPARAM wParam, LPARAM lParam); afx_msg void OnTrayOpenDir(); afx_msg void OnTrayRestore(); afx_msg void OnTrayExit(); afx_msg void OnBnClickedButtonConnect(); @@ -116,6 +117,60 @@ * @param vecBuffer 测量数据缓存,将被逐行打印到日志中。 */ void PrintSampleData(int nOutNo, const std::vector<float>& vecBuffer); /** * @brief 获取当前应用程序所在的目录路径。 * * 通过 GetModuleFileName 获取当前可执行文件的完整路径, * 并截取掉文件名部分,返回目录路径,末尾自带反斜杠。 * * @return CString 应用程序所在目录,例如 "C:\\Program Files\\SGMeasurement\\" */ CString GetAppDirectory(); /** * @brief 获取配置文件的完整路径。 * * 配置文件名固定为 "config.ini",位于应用程序目录下。 * * @return CString 配置文件完整路径,例如 "C:\\Program Files\\SGMeasurement\\config.ini" */ CString GetConfigPath(); /** * @brief 从 ini 配置文件加载存储与分析参数。 * * 读取指定 ini 文件中的参数值,并更新对话框类中的成员变量, * 包括存储设置(触发方式、采样点数)、跳变检测参数、稳定区提取参数等。 * 若文件中缺少某些字段,将使用默认值。 * * @param strFile ini 文件路径。 * @return true 表示加载成功,false 表示加载失败(如文件不存在)。 */ bool LoadConfig(const CString& strFile); /** * @brief 将当前存储与分析参数保存到 ini 配置文件。 * * 把对话框类中的成员变量(存储设置、跳变检测、稳定区提取等参数) * 序列化并写入到指定的 ini 文件中,以便下次启动时恢复。 * * @param strFile ini 文件路径。 * @return true 表示保存成功,false 表示保存失败。 */ bool SaveConfig(const CString& strFile); /** * @brief 设置或取消当前程序的开机自启动。 * * 该函数会在注册表 `HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run` * 下写入或删除当前程序的路径,从而控制是否随 Windows 启动自动运行。 * * @param bEnable 是否启用自启动。true 表示设置开机自启,false 表示取消自启。 * * @return true 表示操作成功;false 表示操作失败(如注册表权限不足)。 */ bool SetAutoStart(bool bEnable); /** * @brief 尝试连接到测量设备。 @@ -234,9 +289,9 @@ * @brief 分析指定端口的存储数据,并提取两段玻璃数据与稳定区,计算偏移。 * * @param nOutNo 输出端口编号(1~4) * @return float 成功返回计算出的偏移量,失败返回 -1.0f * @return double 成功返回计算出的偏移量,失败返回 -1.0f */ float AnalyzeStoredData(int nOutNo); double AnalyzeStoredData(int nOutNo); // === 系统状态与运行数据 === @@ -335,6 +390,13 @@ */ BOOL m_bExitingFromTray; // === 自启动相关 === /** * @brief 是否开机自启动 */ BOOL m_nAutoStart; // === PLC 信号监听器 === /** SourceCode/Bond/SGMeasurement/res/menu_open_dir.ico
SourceCode/Bond/SGMeasurement/resource.h
@@ -9,6 +9,7 @@ #define IDR_MAINFRAME 128 #define IDI_ICON_RESTORE 130 #define IDI_ICON_EXIT 131 #define IDI_ICON_OPEN_DIR 132 #define IDC_IPADDRESS 1000 #define IDC_BUTTON_CONNECT 1001 #define IDC_BUTTON_DISCONNECT 1002 @@ -37,7 +38,7 @@ // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 132 #define _APS_NEXT_RESOURCE_VALUE 133 #define _APS_NEXT_COMMAND_VALUE 32771 #define _APS_NEXT_CONTROL_VALUE 1023 #define _APS_NEXT_SYMED_VALUE 101