From 5a8bbd2426aeacdbbb2fdb1a7f7a1adce0cac7f9 Mon Sep 17 00:00:00 2001
From: mrDarker <mr.darker@163.com>
Date: 星期五, 01 八月 2025 16:23:29 +0800
Subject: [PATCH] 1. 新增以下功能函数并集成: - InitStorage():初始化存储区域 - StartStorage():开始数据存储 - StopStorage():停止存储并自动提取、分析数据 - AnalyzeStoredData():分析指定端口数据,返回偏移量
---
SourceCode/Bond/SGMeasurement/SGMeasurementDlg.cpp | 993 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 993 insertions(+), 0 deletions(-)
diff --git a/SourceCode/Bond/SGMeasurement/SGMeasurementDlg.cpp b/SourceCode/Bond/SGMeasurement/SGMeasurementDlg.cpp
new file mode 100644
index 0000000..b946b61
--- /dev/null
+++ b/SourceCode/Bond/SGMeasurement/SGMeasurementDlg.cpp
@@ -0,0 +1,993 @@
+锘�
+// SGMeasurementDlg.cpp: 瀹炵幇鏂囦欢
+//
+
+#include "pch.h"
+#include "framework.h"
+#include "SGMeasurement.h"
+#include "SGMeasurementDlg.h"
+#include "afxdialogex.h"
+#include "SGIF.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+#define DeviceID 0
+
+// 鎵樼洏鍥炬爣 ID 涓庢秷鎭畯
+#define ID_TRAY_RESTORE 2001 // 鎭㈠绐楀彛
+#define ID_TRAY_EXIT 2002 // 閫�鍑虹▼搴�
+#define WM_TRAY_ICON_NOTIFY (WM_USER + 1000) // 鎵樼洏鍥炬爣鍥炶皟娑堟伅 ID
+
+// 鎵樼洏鎻愮ず鏂囨湰瀹�
+#define TRAY_ICON_TOOLTIP_TEXT _T("SGMeasurement")
+
+// 鏃ュ織棰滆壊瀹忓畾涔�
+#define LOG_COLOR_NORMAL RGB(0, 0, 0) // 鏅�氾細榛戣壊
+#define LOG_COLOR_SUCCESS RGB(0, 128, 0) // 鎴愬姛锛氱豢鑹�
+#define LOG_COLOR_ERROR RGB(255, 0, 0) // 閿欒锛氱孩鑹�
+#define LOG_COLOR_WARNING RGB(255, 165, 0) // 璀﹀憡锛氭鑹�
+#define LOG_COLOR_TIME RGB(0, 0, 255) // 鏃堕棿鎴筹細钃濊壊
+
+// 瀹氭椂鍣ㄧ浉鍏冲畯瀹氫箟
+#define TIMER_INTERVAL_MS 500
+#define TIMER_ID_OUTPUT_UPDATE 1
+
+class CAboutDlg : public CDialogEx
+{
+public:
+ CAboutDlg();
+
+// 瀵硅瘽妗嗘暟鎹�
+#ifdef AFX_DESIGN_TIME
+ enum { IDD = IDD_ABOUTBOX };
+#endif
+
+ protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 鏀寔
+
+// 瀹炵幇
+protected:
+ DECLARE_MESSAGE_MAP()
+};
+
+CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX)
+{
+}
+
+void CAboutDlg::DoDataExchange(CDataExchange* pDX)
+{
+ CDialogEx::DoDataExchange(pDX);
+}
+
+BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
+END_MESSAGE_MAP()
+
+CSGMeasurementDlg::CSGMeasurementDlg(CWnd* pParent /*=nullptr*/)
+ : CDialogEx(IDD_SGMEASUREMENT_DIALOG, pParent)
+ , m_bConnected(false)
+ , m_bSaving(false)
+ , m_dOutValues{ 0.0, 0.0, 0.0, 0.0 }
+ , m_nUseTrigger(0)
+ , m_nSavePointCount(100000)
+ , m_fJumpThreshold(1.0f)
+ , m_nJumpWindow(3)
+ , m_nValleyMargin(0)
+ , m_nMinGlass1Count(10)
+ , m_nFixedCount(5)
+ , m_fMaxDelta(0.05f)
+ , m_nTrayIconID(0)
+ , m_bTrayIconCreated(FALSE)
+ , m_bExitingFromTray(FALSE)
+{
+ m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
+}
+
+void CSGMeasurementDlg::DoDataExchange(CDataExchange* pDX)
+{
+ CDialogEx::DoDataExchange(pDX);
+ DDX_Text(pDX, IDC_EDIT_OUT1, m_dOutValues[0]);
+ DDX_Text(pDX, IDC_EDIT_OUT2, m_dOutValues[1]);
+ DDX_Text(pDX, IDC_EDIT_OUT3, m_dOutValues[2]);
+ DDX_Text(pDX, IDC_EDIT_OUT4, m_dOutValues[3]);
+ DDX_Control(pDX, IDC_RICHEDIT_LOG, m_editLog);
+ DDX_Check(pDX, IDC_CHECK_USE_TRIGGER, m_nUseTrigger);
+ DDX_Control(pDX, IDC_COMBO_OUTPUT_PORT, m_comboOutputPort);
+ DDX_Text(pDX, IDC_EDIT_STORE_COUNT, m_nSavePointCount);
+ DDX_Text(pDX, IDC_EDIT_JUMP_WINDOW, m_nJumpWindow);
+ DDX_Text(pDX, IDC_EDIT_VALLEY_MARGIN, m_nValleyMargin);
+ DDX_Text(pDX, IDC_EDIT_MIN_GLASS_COUNT, m_nMinGlass1Count);
+ DDX_Text(pDX, IDC_EDIT_FIXED_COUNT, m_nFixedCount);
+ DDX_Text(pDX, IDC_EDIT_JUMP_THRESHOLD, m_fJumpThreshold);
+ DDX_Text(pDX, IDC_EDIT_MAX_DELTA, m_fMaxDelta);
+}
+
+void CSGMeasurementDlg::ExitApplication()
+{
+ // 鏂紑璁惧杩炴帴锛堝宸茶繛鎺ワ級
+ if (m_bConnected) {
+ DisconnectFromDevice();
+ }
+
+ // 鍒犻櫎鎵樼洏鍥炬爣锛堝宸叉坊鍔狅級
+ if (m_bTrayIconCreated) {
+ Shell_NotifyIcon(NIM_DELETE, &m_trayIconData);
+ m_bTrayIconCreated = FALSE;
+ }
+
+ DestroyWindow();
+ CDialogEx::OnClose();
+}
+
+void CSGMeasurementDlg::UpdateControlStatus(BOOL bConnected, BOOL bStoring/* = FALSE*/)
+{
+ // 杩炴帴鎸夐挳鍜屾柇寮�鎸夐挳鐘舵�佷簰鏂�
+ GetDlgItem(IDC_BUTTON_CONNECT)->EnableWindow(!bConnected);
+ GetDlgItem(IDC_BUTTON_DISCONNECT)->EnableWindow(bConnected);
+
+ // IP鍦板潃杈撳叆鍙厑璁稿湪鏈繛鎺ユ椂淇敼
+ GetDlgItem(IDC_IPADDRESS)->EnableWindow(!bConnected);
+
+ // 瀛樺偍閰嶇疆鎺т欢浠呭湪宸茶繛鎺ヤ笖鏈紑濮嬪瓨鍌ㄦ椂鍏佽鎿嶄綔
+ BOOL bCanConfigure = bConnected && !bStoring;
+ /*GetDlgItem(IDC_CHECK_USE_TRIGGER)->EnableWindow(bCanConfigure);*/
+ GetDlgItem(IDC_COMBO_OUTPUT_PORT)->EnableWindow(bCanConfigure);
+ GetDlgItem(IDC_EDIT_STORE_COUNT)->EnableWindow(bCanConfigure);
+ GetDlgItem(IDC_EDIT_JUMP_THRESHOLD)->EnableWindow(bCanConfigure);
+ GetDlgItem(IDC_EDIT_JUMP_WINDOW)->EnableWindow(bCanConfigure);
+ GetDlgItem(IDC_EDIT_VALLEY_MARGIN)->EnableWindow(bCanConfigure);
+ GetDlgItem(IDC_EDIT_MIN_GLASS_COUNT)->EnableWindow(bCanConfigure);
+ GetDlgItem(IDC_EDIT_FIXED_COUNT)->EnableWindow(bCanConfigure);
+ GetDlgItem(IDC_EDIT_MAX_DELTA)->EnableWindow(bCanConfigure);
+
+ // 瀛樺偍鐩稿叧鎸夐挳
+ GetDlgItem(IDC_BUTTON_RECEIVE_FROM_CTRL)->EnableWindow(bCanConfigure);
+ GetDlgItem(IDC_BUTTON_SEND_TO_CTRL)->EnableWindow(bCanConfigure);
+ GetDlgItem(IDC_BUTTON_CLEAR_STORE)->EnableWindow(bCanConfigure);
+ GetDlgItem(IDC_BUTTON_START_STORE)->EnableWindow(bCanConfigure);
+ GetDlgItem(IDC_BUTTON_STOP_STORE)->EnableWindow(bStoring);
+}
+
+void CSGMeasurementDlg::AppendLogLineBatchBegin()
+{
+ m_editLog.SetRedraw(FALSE);
+ m_editLog.SetEventMask(0); // 闃叉瑙﹀彂涓嶅繀瑕佺殑閫氱煡
+}
+
+void CSGMeasurementDlg::AppendLogLineBatchEnd()
+{
+ m_editLog.SetRedraw(TRUE);
+ m_editLog.Invalidate(); // 寮哄埗閲嶇粯
+ m_editLog.SetEventMask(ENM_CHANGE | ENM_SELCHANGE);
+}
+
+void CSGMeasurementDlg::TrimRichEditLineLimit(int nMaxLines)
+{
+ int nLineCount = m_editLog.GetLineCount();
+ if (nLineCount < nMaxLines) {
+ return;
+ }
+
+ // 鑾峰彇澶氫綑琛岀殑瀛楃鏁拌寖鍥�
+ int charIndex = m_editLog.LineIndex(nMaxLines);
+ m_editLog.SetSel(0, charIndex); // 閫変腑澶氫綑鍐呭
+ m_editLog.ReplaceSel(_T("")); // 鍒犻櫎
+}
+
+void CSGMeasurementDlg::AppendLogLineRichStyled(const CString& content, COLORREF color /*= RGB(0, 0, 0)*/)
+{
+ if (!::IsWindow(GetSafeHwnd()) || !::IsWindow(m_editLog.GetSafeHwnd())) {
+ return;
+ }
+
+ // 鏃堕棿鎴�
+ CString strTimestamp;
+ CTime now = CTime::GetCurrentTime();
+ strTimestamp.Format(_T("[%02d:%02d:%02d] "), now.GetHour(), now.GetMinute(), now.GetSecond());
+
+ // 鎻掑叆鐐圭Щ鍒版渶鍚庯紙涔熷彲浠ヨ涓� 0 琛ㄧず椤堕儴锛�
+ m_editLog.SetSel(-1, -1);
+
+ // 鎻掑叆鏃堕棿锛堣摑鑹诧級
+ CHARFORMAT2 cfTime = {};
+ cfTime.cbSize = sizeof(cfTime);
+ cfTime.dwMask = CFM_COLOR;
+ cfTime.crTextColor = LOG_COLOR_TIME;
+ m_editLog.SetSelectionCharFormat(cfTime);
+ m_editLog.ReplaceSel(strTimestamp);
+
+ // 鎻掑叆鏃ュ織姝f枃锛堜紶鍏ラ鑹诧級
+ CHARFORMAT2 cfMsg = {};
+ cfMsg.cbSize = sizeof(cfMsg);
+ cfMsg.dwMask = CFM_COLOR;
+ cfMsg.crTextColor = color;
+ m_editLog.SetSelectionCharFormat(cfMsg);
+ m_editLog.ReplaceSel(content + _T("\r\n"));
+
+ // 闄愬埗鏈�澶ц鏁�
+ TrimRichEditLineLimit(100);
+}
+
+void CSGMeasurementDlg::HighlightAllMatches(const CString& strSearch, COLORREF clrHighlight/* = RGB(255, 165, 0)*/)
+{
+ if (strSearch.IsEmpty()) {
+ return;
+ }
+
+ long nStart = 0;
+ long nEnd = m_editLog.GetTextLength();
+ FINDTEXTEX ft = { 0 };
+ ft.chrg.cpMin = 0;
+ ft.chrg.cpMax = nEnd;
+ ft.lpstrText = strSearch.GetString();
+
+ // 楂樹寒鍓嶄笉娓呴櫎鍏ㄦ枃棰滆壊锛岄伩鍏嶅巻鍙插鑹叉贩娣�
+ while (m_editLog.FindText(FR_DOWN, &ft) != -1) {
+ m_editLog.SetSel(ft.chrgText.cpMin, ft.chrgText.cpMax);
+
+ CHARFORMAT2 cf = {};
+ cf.cbSize = sizeof(cf);
+ cf.dwMask = CFM_COLOR;
+ cf.crTextColor = clrHighlight;
+ m_editLog.SetSelectionCharFormat(cf);
+
+ // 涓嬫鎼滅储浠庡悗闈㈠紑濮�
+ ft.chrg.cpMin = ft.chrgText.cpMax;
+ }
+ m_editLog.SetSel(-1, 0);
+}
+
+void CSGMeasurementDlg::PrintSampleData(int nOutNo, const std::vector<float>& vecBuffer)
+{
+ int nReceived = static_cast<int>(vecBuffer.size());
+ if (vecBuffer.empty() || nReceived < 0) {
+ CString strError;
+ strError.Format(_T("OUT%d: 鎺ユ敹鏁版嵁涓虹┖鎴栨棤鏁堬紝鏃犳硶鎵撳嵃銆�"), nOutNo);
+ AppendLogLineRichStyled(strError, LOG_COLOR_WARNING);
+ return;
+ }
+
+ CString strLine;
+ for (int i = 0; i < nReceived; ++i) {
+ CString strOne;
+ strOne.Format(_T("%10.3f "), vecBuffer[i]);
+ strLine += strOne;
+
+ // 姣� 7 涓�艰緭鍑轰竴琛�
+ if ((i + 1) % 7 == 0 || i == nReceived - 1) {
+ AppendLogLineRichStyled(strLine, LOG_COLOR_NORMAL);
+ strLine.Empty();
+ }
+ }
+}
+
+bool CSGMeasurementDlg::ConnectToDevice()
+{
+ if (m_bConnected) {
+ AppendLogLineRichStyled(_T("璁惧宸茶繛鎺ワ紝璇峰厛鏂紑杩炴帴銆�"), LOG_COLOR_WARNING);
+ return false;
+ }
+
+ SGIF_OPENPARAM_ETHERNET stIpAddress = { 0 };
+
+ CIPAddressCtrl* pIPCtrl = (CIPAddressCtrl*)GetDlgItem(IDC_IPADDRESS);
+ if (!::IsWindow(pIPCtrl->GetSafeHwnd())) {
+ AppendLogLineRichStyled(_T("IP 鎺т欢鏃犳晥锛岃繛鎺ュけ璐ワ紒"), LOG_COLOR_ERROR);
+ return false;
+ }
+
+ pIPCtrl->GetAddress(
+ stIpAddress.IPAddress.S_un.S_un_b.s_b1,
+ stIpAddress.IPAddress.S_un.S_un_b.s_b2,
+ stIpAddress.IPAddress.S_un.S_un_b.s_b3,
+ stIpAddress.IPAddress.S_un.S_un_b.s_b4
+ );
+
+ RC nRet = SGIF_OpenDeviceETHER(DeviceID, &stIpAddress);
+ if (nRet == RC_OK) {
+ AppendLogLineRichStyled(_T("鎵撳紑杩炴帴鎴愬姛锛�"), LOG_COLOR_SUCCESS);
+
+ m_bConnected = TRUE;
+ UpdateControlStatus(TRUE, FALSE);
+ SetTimer(TIMER_ID_OUTPUT_UPDATE, TIMER_INTERVAL_MS, nullptr);
+ return true;
+ }
+ else {
+ CString strError;
+ strError.Format(_T("鎵撳紑杩炴帴澶辫触锛岄敊璇爜锛�%#X"), nRet);
+ AppendLogLineRichStyled(strError, LOG_COLOR_ERROR);
+
+ m_bConnected = FALSE;
+ UpdateControlStatus(FALSE, FALSE);
+ return false;
+ }
+}
+
+bool CSGMeasurementDlg::DisconnectFromDevice()
+{
+ if (!m_bConnected) {
+ AppendLogLineRichStyled(_T("璁惧鏈繛鎺ワ紝鏃犻渶鏂紑銆�"), LOG_COLOR_WARNING);
+ return false;
+ }
+
+ RC nRet = SGIF_CloseDevice(DeviceID);
+ if (nRet == RC_OK) {
+ if (m_bSaving) {
+ m_bSaving = FALSE;
+ nRet = SGIF_DataStorageStop(DeviceID);
+ if (nRet == RC_OK) {
+ AppendLogLineRichStyled(_T("鏁版嵁瀛樺偍宸插仠姝€��"), LOG_COLOR_SUCCESS);
+ }
+ else {
+ CString strError;
+ strError.Format(_T("鍋滄鏁版嵁瀛樺偍澶辫触锛岄敊璇爜锛�%#X"), nRet);
+ AppendLogLineRichStyled(strError, LOG_COLOR_ERROR);
+ }
+ }
+
+ AppendLogLineRichStyled(_T("鏂紑杩炴帴鎴愬姛锛�"), LOG_COLOR_SUCCESS);
+
+ m_bConnected = FALSE;
+ UpdateControlStatus(FALSE, FALSE);
+ KillTimer(TIMER_ID_OUTPUT_UPDATE);
+ return true;
+ }
+ else {
+ CString strError;
+ strError.Format(_T("鏂紑杩炴帴澶辫触锛岄敊璇爜锛�%#X"), nRet);
+ AppendLogLineRichStyled(strError, LOG_COLOR_ERROR);
+
+ UpdateControlStatus(m_bConnected, m_bSaving);
+ return false;
+ }
+}
+
+void CSGMeasurementDlg::CleanInvalidValuesInPlace(int nOutNo, std::vector<float>& vecData, float fInvalid/* = -999.0f*/)
+{
+ // 鎵惧埌绗竴涓湁鏁堝��
+ auto itStart = std::find_if(vecData.begin(), vecData.end(), [=](float v) { return v > fInvalid; });
+
+ // 鎵惧埌鏈�鍚庝竴涓湁鏁堝��
+ auto itEnd = std::find_if(vecData.rbegin(), vecData.rend(), [=](float v) { return v > fInvalid; }).base();
+
+ // 妫�鏌ユ槸鍚︽湁鏈夋晥鏁版嵁
+ if (itStart < itEnd) {
+ // 鍏堣杈�
+ std::vector<float> vecTrimmed(itStart, itEnd);
+
+ // 鍐嶇Щ闄や腑闂寸殑鏃犳晥鍊�
+ auto itNewEnd = std::remove_if(vecTrimmed.begin(), vecTrimmed.end(), [=](float v) { return v == fInvalid; });
+ vecTrimmed.erase(itNewEnd, vecTrimmed.end());
+
+ vecData = std::move(vecTrimmed);
+
+ CString strLog;
+ strLog.Format(_T("OUT%d: 宸茶鍓棤鏁堣竟鐣屾暟鎹紝鍓╀綑鏈夋晥鏁版嵁 %d 涓��"), nOutNo, static_cast<int>(vecData.size()));
+ AppendLogLineRichStyled(strLog, LOG_COLOR_NORMAL);
+
+ if (vecData.size() < 20) {
+ AppendLogLineRichStyled(_T("璀﹀憡锛氭湁鏁堟暟鎹噺杩囧皯锛屽彲鑳藉奖鍝嶅悗缁鐞嗐��"), LOG_COLOR_WARNING);
+ }
+ else {
+ CString strInfo;
+ strInfo.Format(_T("OUT%d: 鏈夋晥鏁版嵁鑼冨洿 [%f, %f]"), nOutNo, *std::min_element(vecData.begin(), vecData.end()), *std::max_element(vecData.begin(), vecData.end()));
+ AppendLogLineRichStyled(strInfo, LOG_COLOR_NORMAL);
+ }
+
+ PrintSampleData(nOutNo, vecData);
+ }
+ else {
+ vecData.clear();
+ }
+}
+
+bool CSGMeasurementDlg::SplitGlassSegments(int nOutNo, const std::vector<float>& vecData, std::vector<float>& vecGlass1, std::vector<float>& vecGlass2, float fJumpThreshold /*= 0.2f*/, int nWindow /*= 3*/, int nValleyMargin /*= 0*/, int nMinGlass1Count /*= 10*/)
+{
+ const int n = static_cast<int>(vecData.size());
+ if (n < 2 * nWindow + 1 + nMinGlass1Count) {
+ CString strError;
+ strError.Format(_T("OUT%d: 鏁版嵁閲忎笉瓒筹紝鑷冲皯闇�瑕� %d 涓偣鎵嶈兘杩涜鍒囧壊銆�"), nOutNo, 2 * nWindow + 1 + nMinGlass1Count);
+ AppendLogLineRichStyled(strError, LOG_COLOR_WARNING);
+ return false;
+ }
+
+ int nValleyIdx = -1;
+ for (int i = nWindow; i < n - nWindow - nMinGlass1Count; ++i) {
+ float fDelta = std::fabs(vecData[i + nWindow] - vecData[i - nWindow]);
+ if (fDelta > fJumpThreshold) {
+ // 鎵� valley 鐐癸紙绋嶅井寰�鍚庤烦鍑犳浠ラ伩寮�杈圭紭鎶栧姩锛�
+ int nSearchStart = i + nWindow + 2;
+ int nSearchEnd = min(nSearchStart + 10, n);
+
+ auto itValley = std::min_element(vecData.begin() + nSearchStart, vecData.begin() + nSearchEnd,
+ [](float a, float b) {
+ return (a > -900.0f && b > -900.0f) ? a < b : false;
+ });
+
+ if (itValley != vecData.begin() + nSearchEnd) {
+ nValleyIdx = static_cast<int>(std::distance(vecData.begin(), itValley));
+ break;
+ }
+ }
+ }
+
+ if (nValleyIdx < 0 || nValleyIdx < nMinGlass1Count) {
+ AppendLogLineRichStyled(_T("鏈壘鍒板悎閫� valley 鐐癸紝鎴� valley 澶潬鍓嶃��"), LOG_COLOR_WARNING);
+ return false;
+ }
+
+ // 浠� valley 澶勫紑濮嬪垏鍓诧紝鎴栬�呭線鍚庡亸绉�
+ int nCutStart = min(nValleyIdx + nValleyMargin, n);
+ vecGlass1.assign(vecData.begin(), vecData.begin() + nCutStart);
+ vecGlass2.assign(vecData.begin() + nCutStart, vecData.end());
+
+ int nGlass1Count = static_cast<int>(vecGlass1.size());
+ int nGlass2Count = static_cast<int>(vecGlass2.size());
+
+ // 鏃ュ織杈撳嚭
+ CString strLog;
+ strLog.Format(_T("OUT%d: 鍒囧壊鎴愬姛锛岀涓�鐗囩幓鐠冩暟鎹噺 %d锛岀浜岀墖鐜荤拑鏁版嵁閲� %d銆�"), nOutNo, nGlass1Count, nGlass2Count);
+ AppendLogLineRichStyled(strLog, LOG_COLOR_SUCCESS);
+
+ if (nGlass1Count < nMinGlass1Count) {
+ strLog.Format(_T("OUT%d: 绗竴鐗囩幓鐠冩暟鎹噺杩囧皯锛屽彲鑳藉奖鍝嶅悗缁鐞嗐��"), nOutNo);
+ AppendLogLineRichStyled(strLog, LOG_COLOR_WARNING);
+ }
+ if (nGlass2Count < nMinGlass1Count) {
+ strLog.Format(_T("OUT%d: 绗簩鐗囩幓鐠冩暟鎹噺杩囧皯锛屽彲鑳藉奖鍝嶅悗缁鐞嗐��"), nOutNo);
+ AppendLogLineRichStyled(strLog, LOG_COLOR_WARNING);
+ }
+
+ AppendLogLineRichStyled(_T("绗竴鐗囩幓鐠冩暟鎹細"), LOG_COLOR_NORMAL);
+ PrintSampleData(nOutNo, vecGlass1);
+
+ AppendLogLineRichStyled(_T("绗簩鐗囩幓鐠冩暟鎹細"), LOG_COLOR_NORMAL);
+ PrintSampleData(nOutNo, vecGlass2);
+
+ return !vecGlass1.empty() && !vecGlass2.empty();
+}
+
+bool CSGMeasurementDlg::ExtractStableRegionFixed(int nOutNo, const std::vector<float>& vecIn, std::vector<float>& vecOut, int nFixedCount/* = 5*/, float fMaxDelta/* = 0.04f*/)
+{
+ const int n = static_cast<int>(vecIn.size());
+ if (n < nFixedCount) {
+ CString strError;
+ strError.Format(_T("OUT%d: 鏁版嵁閲忎笉瓒筹紝鑷冲皯闇�瑕� %d 涓偣鎵嶈兘鎻愬彇绋冲畾鍖恒��"), nOutNo, nFixedCount);
+ return false;
+ }
+
+ int nBestStart = -1;
+ float fBestRange = FLT_MAX;
+
+ for (int i = 0; i <= n - nFixedCount; ++i) {
+ auto first = vecIn.begin() + i;
+ auto last = first + nFixedCount;
+
+ float fMinVal = *std::min_element(first, last);
+ float fMaxVal = *std::max_element(first, last);
+ float fRange = fMaxVal - fMinVal;
+
+ if (fRange <= fMaxDelta && fRange < fBestRange) {
+ fBestRange = fRange;
+ nBestStart = i;
+ }
+ }
+
+ if (nBestStart < 0) {
+ return false;
+ }
+
+ vecOut.assign(vecIn.begin() + nBestStart, vecIn.begin() + nBestStart + nFixedCount);
+
+ CString strLog;
+ strLog.Format(_T("OUT%d: 鎻愬彇绋冲畾鍖烘垚鍔燂紝璧峰鐐圭储寮� %d锛岃寖鍥� %.3f銆�"), nOutNo, nBestStart, fBestRange);
+ AppendLogLineRichStyled(strLog, LOG_COLOR_SUCCESS);
+
+ if (vecOut.size() < nFixedCount) {
+ CString strWarning;
+ strWarning.Format(_T("OUT%d: 鎻愬彇鐨勭ǔ瀹氬尯鏁版嵁閲忎笉瓒筹紝鍙兘褰卞搷鍚庣画澶勭悊銆�"), nOutNo);
+ AppendLogLineRichStyled(strWarning, LOG_COLOR_WARNING);
+ }
+
+ // 鎵撳嵃鎻愬彇鐨勭ǔ瀹氬尯鏁版嵁
+ AppendLogLineRichStyled(_T("鎻愬彇鐨勭ǔ瀹氬尯鏁版嵁锛�"), LOG_COLOR_NORMAL);
+ PrintSampleData(nOutNo, vecOut);
+
+ return true;
+}
+
+bool CSGMeasurementDlg::CalcGlassOffset(const std::vector<float>& vecGlass1, const std::vector<float>& vecGlass2, float& fAvg1, float& fAvg2, float& fOffset)
+{
+ if (vecGlass1.empty() || vecGlass2.empty()) {
+ AppendLogLineRichStyled(_T("绋冲畾鍖烘暟鎹负绌猴紝鏃犳硶璁$畻骞冲潎鍊煎拰鍋忕Щ銆�"), LOG_COLOR_WARNING);
+ return false;
+ }
+
+ auto CalcAverage = [](const std::vector<float>& data) -> float {
+ float sum = std::accumulate(data.begin(), data.end(), 0.0f);
+ return sum / static_cast<float>(data.size());
+ };
+
+ fAvg1 = CalcAverage(vecGlass1);
+ fAvg2 = CalcAverage(vecGlass2);
+ fOffset = std::fabs(fAvg2 - fAvg1); // 绗簩鐗� - 绗竴鐗�
+
+ CString strLog;
+ strLog.Format(_T("绗竴鐗囩幓鐠冨钩鍧囧��: %.3f锛岀浜岀墖鐜荤拑骞冲潎鍊�: %.3f锛屽亸绉婚噺: %.3f"), fAvg1, fAvg2, fOffset);
+ AppendLogLineRichStyled(strLog, LOG_COLOR_SUCCESS);
+
+ return true;
+}
+
+bool CSGMeasurementDlg::InitDataStorage()
+{
+ if (!m_bConnected) {
+ AppendLogLineRichStyled(_T("璁惧鏈繛鎺ワ紝璇峰厛杩炴帴璁惧銆�"), LOG_COLOR_WARNING);
+ return false;
+ }
+
+ if (m_bSaving) {
+ AppendLogLineRichStyled(_T("鏁版嵁瀛樺偍姝e湪杩涜涓紝璇峰厛鍋滄瀛樺偍銆�"), LOG_COLOR_WARNING);
+ return false;
+ }
+
+ RC nRet = SGIF_DataStorageInit(DeviceID);
+ if (nRet == RC_OK) {
+ AppendLogLineRichStyled(_T("鏁版嵁瀛樺偍宸叉竻闄ゃ��"), LOG_COLOR_SUCCESS);
+ return true;
+ }
+
+ CString strError;
+ strError.Format(_T("娓呴櫎鏁版嵁瀛樺偍澶辫触锛岄敊璇爜锛�%#X"), nRet);
+ AppendLogLineRichStyled(strError, LOG_COLOR_ERROR);
+ return false;
+}
+
+bool CSGMeasurementDlg::StartDataStorage()
+{
+ if (m_bSaving) {
+ AppendLogLineRichStyled(_T("鏁版嵁瀛樺偍宸插湪杩涜涓紝璇峰厛鍋滄瀛樺偍銆�"), LOG_COLOR_WARNING);
+ return false;
+ }
+
+ RC nRet = SGIF_DataStorageStart(DeviceID);
+ if (nRet == RC_OK) {
+ m_bSaving = TRUE;
+ AppendLogLineRichStyled(_T("鏁版嵁瀛樺偍宸插紑濮嬨��"), LOG_COLOR_SUCCESS);
+ return true;
+ }
+
+ CString strError;
+ strError.Format(_T("寮�濮嬫暟鎹瓨鍌ㄥけ璐ワ紝閿欒鐮侊細%#X"), nRet);
+ AppendLogLineRichStyled(strError, LOG_COLOR_ERROR);
+ return false;
+}
+
+bool CSGMeasurementDlg::StopDataStorage()
+{
+ if (!m_bSaving) {
+ AppendLogLineRichStyled(_T("鏁版嵁瀛樺偍鏈湪杩涜涓紝璇峰厛寮�濮嬪瓨鍌ㄣ��"), LOG_COLOR_WARNING);
+ return false;
+ }
+
+ RC nRet = SGIF_DataStorageStop(DeviceID);
+ if (nRet == RC_OK) {
+ m_bSaving = FALSE;
+ AppendLogLineRichStyled(_T("鏁版嵁瀛樺偍宸插仠姝€��"), LOG_COLOR_SUCCESS);
+ return true;
+ }
+
+ CString strError;
+ strError.Format(_T("鍋滄鏁版嵁瀛樺偍澶辫触锛岄敊璇爜锛�%#X"), nRet);
+ AppendLogLineRichStyled(strError, LOG_COLOR_ERROR);
+ return false;
+}
+
+float CSGMeasurementDlg::AnalyzeStoredData(int nOutNo)
+{
+ UpdateData(TRUE);
+
+ if (m_nUseTrigger) {
+ UpdateControlStatus(m_bConnected, m_bSaving);
+ AfxMessageBox(_T("褰撳墠鏄‖瑙﹀彂妯″紡锛岃妫�鏌ヨЕ鍙戝櫒鐘舵�併��"), MB_ICONINFORMATION);
+ return -1.0f;
+ }
+
+ if (!m_bConnected) {
+ AppendLogLineRichStyled(_T("璁惧鏈繛鎺ワ紝璇峰厛杩炴帴璁惧銆�"), LOG_COLOR_WARNING);
+ return -1.0f;
+ }
+
+ if (m_bSaving) {
+ AppendLogLineRichStyled(_T("鏁版嵁瀛樺偍姝e湪杩涜涓紝璇峰厛鍋滄瀛樺偍銆�"), LOG_COLOR_WARNING);
+ return -1.0f;
+ }
+
+ if (nOutNo < 1 || nOutNo > 4) {
+ AppendLogLineRichStyled(_T("杈撳嚭绔彛缂栧彿鏃犳晥锛屽繀椤诲湪 1 鍒� 4 涔嬮棿銆�"), LOG_COLOR_ERROR);
+ return -1.0f;
+ }
+
+ if (m_nSavePointCount < 0) {
+ AppendLogLineRichStyled(_T("鏁版嵁鐐规暟蹇呴』澶т簬 0銆�"), LOG_COLOR_ERROR);
+ return -1.0f;
+ }
+
+ std::vector<float> vecBuffer(m_nSavePointCount, 0.0f);
+ int nReceived = 0;
+
+ RC nRet = SGIF_DataStorageGetData(DeviceID, nOutNo, m_nSavePointCount, vecBuffer.data(), &nReceived);
+ if (nRet != RC_OK) {
+ CString strError;
+ strError.Format(_T("璇诲彇 OUT%d 鏁版嵁澶辫触锛岄敊璇爜锛�%#X"), nOutNo, nRet);
+ AppendLogLineRichStyled(strError, LOG_COLOR_ERROR);
+ return -1.0f;
+ }
+
+ vecBuffer.resize(nReceived);
+ CleanInvalidValuesInPlace(nOutNo, vecBuffer);
+
+ 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 -1.0f;
+ }
+
+ std::vector<float> vecStable1, vecStable2;
+ bool bStable1 = ExtractStableRegionFixed(nOutNo, vecGlass1, vecStable1, m_nFixedCount, m_fMaxDelta);
+ bool bStable2 = ExtractStableRegionFixed(nOutNo, vecGlass2, vecStable2, m_nFixedCount, m_fMaxDelta);
+
+ float fAvg1 = 0.0f, fAvg2 = 0.0f, fOffset = 0.0f;
+ if (bStable1 && bStable2) {
+ AppendLogLineRichStyled(_T("鎴愬姛鎻愬彇鍒颁袱鐗囩幓鐠冪殑绋冲畾鍖烘暟鎹��"), LOG_COLOR_SUCCESS);
+ CalcGlassOffset(vecStable1, vecStable2, fAvg1, fAvg2, fOffset);
+ }
+ else {
+ AppendLogLineRichStyled(_T("鏈兘鎻愬彇鍒扮ǔ瀹氬尯鏁版嵁锛屽皾璇曚娇鐢ㄥ師濮嬪垎娈垫暟鎹绠楀亸绉汇��"), LOG_COLOR_WARNING);
+ CalcGlassOffset(vecGlass1, vecGlass2, fAvg1, fAvg2, fOffset);
+ }
+
+ return fOffset;
+}
+
+BEGIN_MESSAGE_MAP(CSGMeasurementDlg, CDialogEx)
+ ON_WM_SYSCOMMAND()
+ ON_WM_PAINT()
+ ON_WM_QUERYDRAGICON()
+ ON_WM_TIMER()
+ ON_WM_MEASUREITEM()
+ ON_WM_DRAWITEM()
+ ON_WM_CLOSE()
+ ON_MESSAGE(WM_TRAY_ICON_NOTIFY, &CSGMeasurementDlg::OnTrayIconClick)
+ ON_COMMAND(ID_TRAY_RESTORE, &CSGMeasurementDlg::OnTrayRestore)
+ ON_COMMAND(ID_TRAY_EXIT, &CSGMeasurementDlg::OnTrayExit)
+ ON_BN_CLICKED(IDC_BUTTON_CONNECT, &CSGMeasurementDlg::OnBnClickedButtonConnect)
+ ON_BN_CLICKED(IDC_BUTTON_DISCONNECT, &CSGMeasurementDlg::OnBnClickedButtonDisconnect)
+ ON_BN_CLICKED(IDC_BUTTON_RECEIVE_FROM_CTRL, &CSGMeasurementDlg::OnBnClickedButtonReceiveFromCtrl)
+ ON_BN_CLICKED(IDC_BUTTON_SEND_TO_CTRL, &CSGMeasurementDlg::OnBnClickedButtonSendToCtrl)
+ ON_BN_CLICKED(IDC_BUTTON_CLEAR_STORE, &CSGMeasurementDlg::OnBnClickedButtonClearStore)
+ ON_BN_CLICKED(IDC_BUTTON_START_STORE, &CSGMeasurementDlg::OnBnClickedButtonStartStore)
+ ON_BN_CLICKED(IDC_BUTTON_STOP_STORE, &CSGMeasurementDlg::OnBnClickedButtonStopStore)
+ ON_BN_CLICKED(IDC_BUTTON_CLEAR_LOG, &CSGMeasurementDlg::OnBnClickedButtonClearLog)
+END_MESSAGE_MAP()
+
+BOOL CSGMeasurementDlg::OnInitDialog()
+{
+ CDialogEx::OnInitDialog();
+
+ // 灏嗏�滃叧浜�...鈥濊彍鍗曢」娣诲姞鍒扮郴缁熻彍鍗曚腑銆�
+
+ // IDM_ABOUTBOX 蹇呴』鍦ㄧ郴缁熷懡浠よ寖鍥村唴銆�
+ ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
+ ASSERT(IDM_ABOUTBOX < 0xF000);
+
+ CMenu* pSysMenu = GetSystemMenu(FALSE);
+ if (pSysMenu != nullptr)
+ {
+ BOOL bNameValid;
+ CString strAboutMenu;
+ bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
+ ASSERT(bNameValid);
+ if (!strAboutMenu.IsEmpty())
+ {
+ pSysMenu->AppendMenu(MF_SEPARATOR);
+ pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
+ }
+ }
+
+ // 璁剧疆姝ゅ璇濇鐨勫浘鏍囥�� 褰撳簲鐢ㄧ▼搴忎富绐楀彛涓嶆槸瀵硅瘽妗嗘椂锛屾鏋跺皢鑷姩
+ // 鎵ц姝ゆ搷浣�
+ SetIcon(m_hIcon, TRUE); // 璁剧疆澶у浘鏍�
+ SetIcon(m_hIcon, FALSE); // 璁剧疆灏忓浘鏍�
+
+ // TODO: 鍦ㄦ娣诲姞棰濆鐨勫垵濮嬪寲浠g爜
+ UpdateData(FALSE);
+ UpdateControlStatus(FALSE, FALSE);
+
+ // 鎵樼洏鍥炬爣鍒濆鍖�
+ m_trayIconData.cbSize = sizeof(NOTIFYICONDATA); // 璁剧疆鎵樼洏鍥炬爣鏁版嵁缁撴瀯鐨勫ぇ灏�
+ m_trayIconData.hWnd = m_hWnd; // 璁剧疆绐楀彛鍙ユ焺
+ m_trayIconData.uID = m_nTrayIconID; // 璁剧疆鎵樼洏鍥炬爣 ID
+ m_trayIconData.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP; // 璁剧疆鎵樼洏鍥炬爣鐨勬爣蹇楋紙鍥炬爣銆佹秷鎭�佹彁绀烘枃鏈級
+ m_trayIconData.uCallbackMessage = WM_TRAY_ICON_NOTIFY; // 璁剧疆鍥炶皟娑堟伅 WM_TRAY_ICON_NOTIFY
+ m_trayIconData.hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); // 鍔犺浇鎵樼洏鍥炬爣
+ lstrcpy(m_trayIconData.szTip, TRAY_ICON_TOOLTIP_TEXT); // 璁剧疆鎵樼洏鎻愮ず鏂囨湰
+
+ // 娣诲姞鎵樼洏鍥炬爣
+ Shell_NotifyIcon(NIM_ADD, &m_trayIconData);
+ m_bTrayIconCreated = TRUE;
+
+ for (int i = 0; i < 4; i++) {
+ CString str;
+ str.Format(_T("OUT%d"), i + 1);
+ m_comboOutputPort.AddString(str);
+ }
+ m_comboOutputPort.SetCurSel(0);
+
+ // 鍒濆鍖朓P鍦板潃鎺т欢锛岃缃负榛樿IP鍦板潃
+ ((CIPAddressCtrl*)GetDlgItem(IDC_IPADDRESS))->SetAddress(192, 168, 0, 10);
+
+ // 鍒濆鍖栨棩蹇楁
+ AppendLogLineRichStyled(_T("鍑嗗灏辩华..."), LOG_COLOR_SUCCESS);
+
+ return TRUE; // 闄ら潪灏嗙劍鐐硅缃埌鎺т欢锛屽惁鍒欒繑鍥� TRUE
+}
+
+void CSGMeasurementDlg::OnSysCommand(UINT nID, LPARAM lParam)
+{
+ if ((nID & 0xFFF0) == IDM_ABOUTBOX)
+ {
+ CAboutDlg dlgAbout;
+ dlgAbout.DoModal();
+ }
+ else
+ {
+ CDialogEx::OnSysCommand(nID, lParam);
+ }
+}
+
+void CSGMeasurementDlg::OnPaint()
+{
+ if (IsIconic()) {
+ CPaintDC dc(this);
+
+ SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
+
+ // 浣垮浘鏍囧湪宸ヤ綔鍖虹煩褰腑灞呬腑
+ int cxIcon = GetSystemMetrics(SM_CXICON);
+ int cyIcon = GetSystemMetrics(SM_CYICON);
+ CRect rect;
+ GetClientRect(&rect);
+ int x = (rect.Width() - cxIcon + 1) / 2;
+ int y = (rect.Height() - cyIcon + 1) / 2;
+
+ // 缁樺埗鍥炬爣
+ dc.DrawIcon(x, y, m_hIcon);
+ }
+ else {
+ CDialogEx::OnPaint();
+ }
+}
+
+//褰撶敤鎴锋嫋鍔ㄦ渶灏忓寲绐楀彛鏃剁郴缁熻皟鐢ㄦ鍑芥暟鍙栧緱鍏夋爣鏄剧ず銆�
+HCURSOR CSGMeasurementDlg::OnQueryDragIcon()
+{
+ return static_cast<HCURSOR>(m_hIcon);
+}
+
+void CSGMeasurementDlg::OnTimer(UINT_PTR nIDEvent)
+{
+ // TODO: 鍦ㄦ娣诲姞娑堟伅澶勭悊绋嬪簭浠g爜鍜�/鎴栬皟鐢ㄩ粯璁ゅ��
+ if (nIDEvent == TIMER_ID_OUTPUT_UPDATE) {
+ SGIF_FLOATVALUE_OUT value[4] = { 0 };
+ RC nRet = SGIF_GetCalcDataALL(DeviceID, value);
+ if (nRet == RC_OK) {
+ for (int i = 0; i < 4; ++i) {
+ m_dOutValues[i] = value[i].Value;
+ }
+
+ // 鏇存柊缁戝畾鎺т欢
+ UpdateData(FALSE);
+ }
+ else {
+ CString strError;
+ strError.Format(_T("鑾峰彇娴嬮噺鍊煎け璐ワ紝閿欒鐮侊細%#X"), nRet);
+ AppendLogLineRichStyled(strError, LOG_COLOR_ERROR);
+ }
+ }
+
+ CDialogEx::OnTimer(nIDEvent);
+}
+
+void CSGMeasurementDlg::OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct)
+{
+ if (lpMeasureItemStruct->CtlType == ODT_MENU) {
+ lpMeasureItemStruct->itemHeight = 24;
+ lpMeasureItemStruct->itemWidth = 140;
+ }
+}
+
+void CSGMeasurementDlg::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
+{
+ if (lpDrawItemStruct->CtlType != ODT_MENU) {
+ return;
+ }
+
+ CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
+ CRect rc = lpDrawItemStruct->rcItem;
+ UINT id = lpDrawItemStruct->itemID;
+
+ // 鑳屾櫙
+ COLORREF bgColor = (lpDrawItemStruct->itemState & ODS_SELECTED) ? RGB(200, 220, 255) : RGB(255, 255, 255);
+ pDC->FillSolidRect(rc, bgColor);
+
+ // 鍥炬爣
+ HICON hIcon = nullptr;
+ if (id == ID_TRAY_RESTORE) {
+ hIcon = AfxGetApp()->LoadIcon(IDI_ICON_RESTORE);
+ }
+
+ if (id == ID_TRAY_EXIT) {
+ hIcon = AfxGetApp()->LoadIcon(IDI_ICON_EXIT);
+ }
+
+ if (hIcon) {
+ DrawIconEx(pDC->GetSafeHdc(), rc.left + 4, rc.top + 4, hIcon, 16, 16, 0, NULL, DI_NORMAL);
+ }
+
+ // 鏂囨湰
+ CString str;
+ if (id == ID_TRAY_RESTORE) {
+ str = _T("鎭㈠鐣岄潰");
+ }
+
+ if (id == ID_TRAY_EXIT) {
+ str = _T("閫�鍑虹▼搴�");
+ }
+
+ pDC->SetBkMode(TRANSPARENT);
+ pDC->SetTextColor(RGB(0, 0, 0));
+ pDC->DrawText(str, CRect(rc.left + 28, rc.top, rc.right, rc.bottom), DT_SINGLELINE | DT_VCENTER | DT_LEFT);
+}
+
+void CSGMeasurementDlg::OnClose()
+{
+ // TODO: 鍦ㄦ娣诲姞娑堟伅澶勭悊绋嬪簭浠g爜鍜�/鎴栬皟鐢ㄩ粯璁ゅ��
+ if (m_bExitingFromTray) {
+ // 浠庢墭鐩橀��鍑烘祦绋�
+ ExitApplication();
+ }
+ else {
+ // 姝e父鍏抽棴鎸夐挳
+ int nResult = AfxMessageBox(_T("鏄惁鏈�灏忓寲鍒版墭鐩橈紵"), MB_YESNO | MB_ICONQUESTION);
+ if (nResult == IDYES) {
+ ShowWindow(SW_HIDE);
+ }
+ else {
+ ExitApplication();
+ }
+ }
+}
+
+LRESULT CSGMeasurementDlg::OnTrayIconClick(WPARAM wParam, LPARAM lParam) {
+ if (wParam == m_nTrayIconID) {
+ if (LOWORD(lParam) == WM_LBUTTONUP) {
+ // 宸﹂敭鐐瑰嚮鎭㈠绐楀彛
+ ShowWindow(SW_SHOW);
+ SetForegroundWindow();
+ }
+ else if (LOWORD(lParam) == WM_RBUTTONUP) {
+ // 鍙抽敭鐐瑰嚮寮瑰嚭鑿滃崟
+ CMenu menu;
+ menu.CreatePopupMenu();
+ 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_RESTORE, &mii);
+
+ // 閫�鍑鸿彍鍗曢」鍥炬爣
+ mii.hbmpItem = HBMMENU_CALLBACK;
+ menu.SetMenuItemInfo(ID_TRAY_EXIT, &mii);
+
+ // 鑾峰彇榧犳爣褰撳墠浣嶇疆锛屽苟鏄剧ず鑿滃崟
+ POINT pt;
+ GetCursorPos(&pt);
+ SetForegroundWindow();
+ menu.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, this);
+ }
+ }
+ return 0;
+}
+
+void CSGMeasurementDlg::OnTrayRestore()
+{
+ ShowWindow(SW_SHOW); // 鎭㈠绐楀彛
+ SetForegroundWindow(); // 灏嗙獥鍙g疆浜庡墠绔�
+}
+
+void CSGMeasurementDlg::OnTrayExit()
+{
+ // 浠庢墭鐩樺浘鏍囪彍鍗曢�夋嫨鈥滈��鍑虹▼搴忊��
+ if (AfxMessageBox(_T("纭畾瑕侀��鍑虹▼搴忓悧锛�"), MB_YESNO | MB_ICONQUESTION) == IDYES) {
+ m_bExitingFromTray = TRUE;
+ PostMessage(WM_CLOSE);
+ }
+}
+
+void CSGMeasurementDlg::OnBnClickedButtonConnect()
+{
+ // TODO: 鍦ㄦ娣诲姞鎺т欢閫氱煡澶勭悊绋嬪簭浠g爜
+ ConnectToDevice();
+}
+
+void CSGMeasurementDlg::OnBnClickedButtonDisconnect()
+{
+ // TODO: 鍦ㄦ娣诲姞鎺т欢閫氱煡澶勭悊绋嬪簭浠g爜
+ DisconnectFromDevice();
+}
+
+void CSGMeasurementDlg::OnBnClickedButtonReceiveFromCtrl()
+{
+ // TODO: 鍦ㄦ娣诲姞鎺т欢閫氱煡澶勭悊绋嬪簭浠g爜
+ if (!m_bConnected) {
+ AppendLogLineRichStyled(_T("璁惧鏈繛鎺ワ紝璇峰厛杩炴帴璁惧銆�"), LOG_COLOR_WARNING);
+ return;
+ }
+}
+
+void CSGMeasurementDlg::OnBnClickedButtonSendToCtrl()
+{
+ // TODO: 鍦ㄦ娣诲姞鎺т欢閫氱煡澶勭悊绋嬪簭浠g爜
+ if (!m_bConnected) {
+ AppendLogLineRichStyled(_T("璁惧鏈繛鎺ワ紝璇峰厛杩炴帴璁惧銆�"), LOG_COLOR_WARNING);
+ return;
+ }
+}
+
+void CSGMeasurementDlg::OnBnClickedButtonClearStore()
+{
+ // TODO: 鍦ㄦ娣诲姞鎺т欢閫氱煡澶勭悊绋嬪簭浠g爜
+ InitDataStorage();
+}
+
+void CSGMeasurementDlg::OnBnClickedButtonStartStore()
+{
+ // TODO: 鍦ㄦ娣诲姞鎺т欢閫氱煡澶勭悊绋嬪簭浠g爜
+ StartDataStorage();
+ UpdateControlStatus(m_bConnected, m_bSaving);
+}
+
+void CSGMeasurementDlg::OnBnClickedButtonStopStore()
+{
+ // TODO: 鍦ㄦ娣诲姞鎺т欢閫氱煡澶勭悊绋嬪簭浠g爜
+ StopDataStorage();
+ UpdateControlStatus(m_bConnected, m_bSaving);
+
+ int nSel = m_comboOutputPort.GetCurSel();
+ if (CB_ERR == nSel) {
+ AppendLogLineRichStyled(_T("璇烽�夋嫨涓�涓湁鏁堢殑杈撳嚭绔彛銆�"), LOG_COLOR_WARNING);
+ return;
+ }
+
+ int nOutNo = nSel + 1;
+ AnalyzeStoredData(nOutNo);
+}
+
+void CSGMeasurementDlg::OnBnClickedButtonClearLog()
+{
+ // TODO: 鍦ㄦ娣诲姞鎺т欢閫氱煡澶勭悊绋嬪簭浠g爜
+ if (::IsWindow(m_editLog.GetSafeHwnd())) {
+ m_editLog.SetWindowText(_T(""));
+ }
+}
\ No newline at end of file
--
Gitblit v1.9.3