From 8294c107676c18538c6e06fe8eab2d209604ac6a Mon Sep 17 00:00:00 2001
From: chenluhua1980 <Chenluhua@qq.com>
Date: 星期一, 19 一月 2026 18:34:06 +0800
Subject: [PATCH] 1.完善和优化界面显示,数据懒加载,等待光标等,修复启动时界面卡的问题。 2.SVData的Push的限制和检查,因发现Glass呆在机器中时,不管机台是否运行都在不停压入数据。

---
 SourceCode/Bond/Servo/CGlass.cpp         |   36 ++++-
 SourceCode/Bond/Servo/CMaster.cpp        |  249 +++++++++++++++++++++++------------------
 SourceCode/Bond/Servo/Model.cpp          |    8 +
 SourceCode/Bond/Servo/ServoDlg.cpp       |   50 ++++++++
 SourceCode/Bond/Servo/CPageGlassList.cpp |   12 +
 5 files changed, 230 insertions(+), 125 deletions(-)

diff --git a/SourceCode/Bond/Servo/CGlass.cpp b/SourceCode/Bond/Servo/CGlass.cpp
index ae2bca0..9220291 100644
--- a/SourceCode/Bond/Servo/CGlass.cpp
+++ b/SourceCode/Bond/Servo/CGlass.cpp
@@ -1,4 +1,4 @@
-#include "stdafx.h"
+锘�#include "stdafx.h"
 #include "CGlass.h"
 #include "Log.h"
 
@@ -384,7 +384,7 @@
 		if (s.size() > maxLen) s.resize(maxLen);
 	}
 
-	// —— 时间戳 & 工具 —— 
+	// 鐘舵�佹椂闂存埑锛氭帓闃�/寮�濮�/缁撴潫
 	void CGlass::markQueued() 
 	{
 		m_state = GlsState::Queued;
@@ -432,29 +432,44 @@
 		return strOut;
 	}
 
-	// ========== SV数据管理接口实现 ==========
-
+	// ========== SV鏁版嵁鍙h ==========
+	static constexpr size_t MAX_SV_DATA_KEEP = 4800;
 	void CGlass::addSVData(int machineId, const std::string& dataType, const SVDataItem& dataItem) {
-		m_svDatas[machineId][dataType].push_back(dataItem);
+		auto& vec = m_svDatas[machineId][dataType];
+		vec.push_back(dataItem);
+		if (vec.size() > MAX_SV_DATA_KEEP) {
+			vec.erase(vec.begin(), vec.begin() + (vec.size() - MAX_SV_DATA_KEEP));
+		}
 	}
 
 	void CGlass::addSVData(int machineId, const std::string& dataType, double value) {
 		auto now = std::chrono::system_clock::now();
-		m_svDatas[machineId][dataType].emplace_back(now, value);
+		auto& vec = m_svDatas[machineId][dataType];
+		vec.emplace_back(now, value);
+		if (vec.size() > MAX_SV_DATA_KEEP) {
+			vec.erase(vec.begin(), vec.begin() + (vec.size() - MAX_SV_DATA_KEEP));
+		}
 	}
 
 	void CGlass::addSVData(int machineId, const std::string& dataType, int64_t timestamp, double value) {
-		// 将int64_t时间戳转换为system_clock::time_point
+		// int64_t鏃堕棿杞垚system_clock::time_point
 		std::chrono::system_clock::time_point timePoint{
-			std::chrono::milliseconds(timestamp)  // 假设timestamp是毫秒
-			// 如果是秒,使用:std::chrono::seconds(timestamp)
+			std::chrono::milliseconds(timestamp)  // timestamp绮惧害锛氭绉�
+			// 濡傛灉闇�瑕佺簿搴︽洿楂橈紝鍙兘瑕佷娇鐢ㄥ叾浠栨椂闂村崟浣嶏紝濡俿td::chrono::seconds(timestamp)
 		};
-		m_svDatas[machineId][dataType].emplace_back(timePoint, value);
+		auto& vec = m_svDatas[machineId][dataType];
+		vec.emplace_back(timePoint, value);
+		if (vec.size() > MAX_SV_DATA_KEEP) {
+			vec.erase(vec.begin(), vec.begin() + (vec.size() - MAX_SV_DATA_KEEP));
+		}
 	}
 
 	void CGlass::addSVData(int machineId, const std::string& dataType, const std::vector<SVDataItem>& dataItems) {
 		auto& dataList = m_svDatas[machineId][dataType];
 		dataList.insert(dataList.end(), dataItems.begin(), dataItems.end());
+		if (dataList.size() > MAX_SV_DATA_KEEP) {
+			dataList.erase(dataList.begin(), dataList.begin() + (dataList.size() - MAX_SV_DATA_KEEP));
+		}
 	}
 
 	std::vector<SVDataItem> CGlass::getSVData(int machineId, const std::string& dataType) const {
@@ -515,7 +530,6 @@
 		auto machineIt = m_svDatas.find(machineId);
 		if (machineIt != m_svDatas.end()) {
 			machineIt->second.erase(dataType);
-			// 如果该机器没有其他数据了,也清除机器条目
 			if (machineIt->second.empty()) {
 				m_svDatas.erase(machineIt);
 			}
diff --git a/SourceCode/Bond/Servo/CMaster.cpp b/SourceCode/Bond/Servo/CMaster.cpp
index 29a89f3..80ce726 100644
--- a/SourceCode/Bond/Servo/CMaster.cpp
+++ b/SourceCode/Bond/Servo/CMaster.cpp
@@ -138,128 +138,147 @@
 
 	int CMaster::init()
 	{
+		const ULONGLONG boot_master_begin = GetTickCount64();
 		LOGI("<Master>姝e湪鍒濆鍖�...");
+		LOGI("[BOOT][MASTER] init begin");
 
 
 		// 	cclink
-		if (m_cclink.Connect(CC_LINK_IE_CONTROL_CHANNEL(1)) != 0) {
+		const ULONGLONG boot_cclink_begin = GetTickCount64();
+		const int cc_ret = m_cclink.Connect(CC_LINK_IE_CONTROL_CHANNEL(1));
+		LOGI("[BOOT][MASTER] CC-Link connect ret=%d, cost=%llu ms",
+			cc_ret,
+			(unsigned long long)(GetTickCount64() - boot_cclink_begin));
+		if (cc_ret != 0) {
 			LOGE("杩炴帴CC-Link澶辫触.");
 		}
 		else {
-			LOGI("杩炴帴CC-Link鎴愬姛.");
-			BoardVersion version{};
-			int nRet = m_cclink.GetBoardVersion(version);
-			if (nRet == 0) {
-				LOGD("鐗堟湰淇℃伅锛�%s.", version.toString().c_str());
-			}
-			else {
-				LOGE("鑾峰彇CC-Link鐗堟湰淇℃伅澶辫触.");
+				LOGI("杩炴帴CC-Link鎴愬姛.");
+				BoardVersion version{};
+				int nRet = m_cclink.GetBoardVersion(version);
+				if (nRet == 0) {
+					LOGD("鐗堟湰淇℃伅锛�%s.", version.toString().c_str());
+				}
+				else {
+					LOGE("鑾峰彇CC-Link鐗堟湰淇℃伅澶辫触.");
+				}
+
+				BoardStatus status;
+				nRet = m_cclink.GetBoardStatus(status);
+				if (nRet == 0) {
+					LOGD("鐘舵�侊細%s.", status.toString().c_str());
+				}
+				else {
+					LOGE("鑾峰彇CC-Link鐘舵�佸け璐�.");
+				}
 			}
 
-			BoardStatus status;
-			nRet = m_cclink.GetBoardStatus(status);
-			if (nRet == 0) {
-				LOGD("鐘舵�侊細%s.", status.toString().c_str());
+
+			// 鍒濆鍖栨坊鍔犲悇瀛愯澶�
+			CLoadPort* pPort1, * pPort2, * pPort3, * pPort4;
+			CBonder* pBonder1, * pBonder2;
+			CEFEM* pEfem;
+			CArm* pArm;
+			CArmTray* pArmTray1, * pArmTray2;
+			CFliper* pFliper;
+			CVacuumBake* pVacuumBake;
+			CAligner* pAligner;
+			CBakeCooling* pBakeCooling;
+			CMeasurement* pMeasurement;
+
+			pPort1 = addLoadPort(0);
+			pPort2 = addLoadPort(1);
+			pPort3 = addLoadPort(2);
+			pPort4 = addLoadPort(3);
+			pEfem = addEFEM();
+			pArm = addArm();
+			pArmTray1 = addArmTray(0);
+			pArmTray2 = addArmTray(1);
+			pFliper = addFliper();
+			pVacuumBake = addVacuumBake();
+			pAligner = addAligner();
+			pBonder1 = addBonder(0);
+			pBonder2 = addBonder(1);
+			pBakeCooling = addBakeCooling();
+			pMeasurement = addMeasurement();
+
+			ASSERT(pEfem);
+			ASSERT(pFliper);
+			ASSERT(pVacuumBake);
+			ASSERT(pAligner);
+			ASSERT(pBonder1);
+			ASSERT(pBonder2);
+			ASSERT(pBakeCooling);
+			ASSERT(pMeasurement);
+
+			pEfem->setPort(0, pPort1);
+			pEfem->setPort(1, pPort2);
+			pEfem->setPort(2, pPort3);
+			pEfem->setPort(3, pPort4);
+			pEfem->setFliper(pFliper);
+			pEfem->setAligner(pAligner);
+			pEfem->setArmTray(0, pArmTray1);
+			pEfem->setArmTray(1, pArmTray2);
+			pPort1->setArm(pArm);
+			pPort2->setArm(pArm);
+			pPort3->setArm(pArm);
+			pPort4->setArm(pArm);
+			pArmTray1->setArm(pArm);
+			pArmTray2->setArm(pArm);
+			pFliper->setArm(pArm);
+			pVacuumBake->setArm(pArm);
+			pAligner->setArm(pArm);
+			pBonder1->setArm(pArm);
+			pBonder2->setArm(pArm);
+			pBakeCooling->setArm(pArm);
+			pMeasurement->setArm(pArm);
+
+			connectEquipments();
+
+
+
+			// 璇荤紦瀛樻暟鎹�
+			const ULONGLONG boot_cache_begin = GetTickCount64();
+			const ULONGLONG boot_read_begin = GetTickCount64();
+			readCache();
+			LOGI("[BOOT][MASTER] readCache finished, cost=%llu ms", (unsigned long long)(GetTickCount64() - boot_read_begin));
+
+			const ULONGLONG boot_state_begin = GetTickCount64();
+			loadState();
+			LOGI("[BOOT][MASTER] loadState finished, cost=%llu ms", (unsigned long long)(GetTickCount64() - boot_state_begin));
+			if (m_listener.onControlJobChanged) {
+				notifyControlJobChanged();
 			}
-			else {
-				LOGE("鑾峰彇CC-Link鐘舵�佸け璐�.");
-			}
+
+			LOGI("[BOOT][MASTER] cache/state loaded, cost=%llu ms (since init %llu ms)",
+				(unsigned long long)(GetTickCount64() - boot_cache_begin),
+				(unsigned long long)(GetTickCount64() - boot_master_begin));
+
+
+			// 瀹氭椂鍣�
+			g_pMaster = this;
+			SetTimer(NULL, 1, 250, (TIMERPROC)MasterTimerProc);
+
+
+			// 璋冨害绾跨▼
+			m_hDispatchThreadHandle = (HANDLE)_beginthreadex(NULL, 0, SERVO::DispatchThreadFunction, this,
+				0, &m_nDispatchThreadAddr);
+
+
+			// 鐩戞帶bit绾跨▼
+			m_hReadBitsThreadHandle = (HANDLE)_beginthreadex(NULL, 0, SERVO::ReadBitsThreadFunction, this,
+				0, &m_nReadBitsThreadAddr);
+
+
+			// 鏇茬嚎鏈嶅姟
+			CreateDAQBridgeServer();
+
+
+			LOGI("<Master>鍒濆鍖栧畬鎴�.");
+			LOGI("[BOOT][MASTER] init finished, total cost=%llu ms",
+				(unsigned long long)(GetTickCount64() - boot_master_begin));
+			return 0;
 		}
-
-
-		// 鍒濆鍖栨坊鍔犲悇瀛愯澶�
-		CLoadPort* pPort1, * pPort2, * pPort3, * pPort4;
-		CBonder* pBonder1, * pBonder2;
-		CEFEM* pEfem;
-		CArm* pArm;
-		CArmTray* pArmTray1, * pArmTray2;
-		CFliper* pFliper;
-		CVacuumBake* pVacuumBake;
-		CAligner* pAligner;
-		CBakeCooling* pBakeCooling;
-		CMeasurement* pMeasurement;
-
-		pPort1 = addLoadPort(0);
-		pPort2 = addLoadPort(1);
-		pPort3 = addLoadPort(2);
-		pPort4 = addLoadPort(3);
-		pEfem = addEFEM();
-		pArm = addArm();
-		pArmTray1 = addArmTray(0);
-		pArmTray2 = addArmTray(1);
-		pFliper = addFliper();
-		pVacuumBake = addVacuumBake();
-		pAligner = addAligner();
-		pBonder1 = addBonder(0);
-		pBonder2 = addBonder(1);
-		pBakeCooling = addBakeCooling();
-		pMeasurement = addMeasurement();
-
-		ASSERT(pEfem);
-		ASSERT(pFliper);
-		ASSERT(pVacuumBake);
-		ASSERT(pAligner);
-		ASSERT(pBonder1);
-		ASSERT(pBonder2);
-		ASSERT(pBakeCooling);
-		ASSERT(pMeasurement);
-
-		pEfem->setPort(0, pPort1);
-		pEfem->setPort(1, pPort2);
-		pEfem->setPort(2, pPort3);
-		pEfem->setPort(3, pPort4);
-		pEfem->setFliper(pFliper);
-		pEfem->setAligner(pAligner);
-		pEfem->setArmTray(0, pArmTray1);
-		pEfem->setArmTray(1, pArmTray2);
-		pPort1->setArm(pArm);
-		pPort2->setArm(pArm);
-		pPort3->setArm(pArm);
-		pPort4->setArm(pArm);
-		pArmTray1->setArm(pArm);
-		pArmTray2->setArm(pArm);
-		pFliper->setArm(pArm);
-		pVacuumBake->setArm(pArm);
-		pAligner->setArm(pArm);
-		pBonder1->setArm(pArm);
-		pBonder2->setArm(pArm);
-		pBakeCooling->setArm(pArm);
-		pMeasurement->setArm(pArm);
-
-		connectEquipments();
-
-
-
-		// 璇荤紦瀛樻暟鎹�
-		readCache();
-		loadState();
-		if (m_listener.onControlJobChanged) {
-			notifyControlJobChanged();
-		}
-
-
-		// 瀹氭椂鍣�
-		g_pMaster = this;
-		SetTimer(NULL, 1, 250, (TIMERPROC)MasterTimerProc);
-
-
-		// 璋冨害绾跨▼
-		m_hDispatchThreadHandle = (HANDLE)_beginthreadex(NULL, 0, SERVO::DispatchThreadFunction, this,
-			0, &m_nDispatchThreadAddr);
-
-
-		// 鐩戞帶bit绾跨▼
-		m_hReadBitsThreadHandle = (HANDLE)_beginthreadex(NULL, 0, SERVO::ReadBitsThreadFunction, this,
-			0, &m_nReadBitsThreadAddr);
-
-
-		// 鏇茬嚎鏈嶅姟
-		CreateDAQBridgeServer();
-
-
-		LOGI("<Master>鍒濆鍖栧畬鎴�.");
-		return 0;
-	}
 
 	int CMaster::term()
 	{
@@ -1675,6 +1694,14 @@
 			}
 		};
 		listener.onSVDataReport = [&](void* pEquipment, void* pData) {
+			const bool allowSvLog =
+				(m_state == MASTERSTATE::RUNNING ||
+					m_state == MASTERSTATE::RUNNING_CONTINUOUS_TRANSFER ||
+					m_state == MASTERSTATE::RUNNING_BATCH ||
+					m_state == MASTERSTATE::STARTING);
+			if (!allowSvLog) {
+				return;
+			}
 			CSVData* pSVData = (CSVData*)pData;
 			auto rawData = pSVData->getSVRawData();
 			std::vector<CParam> params;
diff --git a/SourceCode/Bond/Servo/CPageGlassList.cpp b/SourceCode/Bond/Servo/CPageGlassList.cpp
index 801a337..29b3b23 100644
--- a/SourceCode/Bond/Servo/CPageGlassList.cpp
+++ b/SourceCode/Bond/Servo/CPageGlassList.cpp
@@ -1088,9 +1088,10 @@
 {
     CDialogEx::OnInitDialog();
 
-    // 瀹氭椂鍣細1=鍒濆鍖栬闃咃紝2=鍛ㄦ湡鍒锋柊锛堝彧澧為噺锛�
+    // 瀹氭椂鍣細1=鍒濆鍖栬闃咃紝2=鍛ㄦ湡鍒锋柊锛堝彧澧為噺锛夛紝3=寤惰繜鍔犺浇棣栧睆鏁版嵁
     SetTimer(1, 3000, nullptr);
     SetTimer(2, 2000, nullptr);
+    SetTimer(3, 10, nullptr);
 
     // 涓嬫媺妗嗘帶浠�
     InitStatusCombo();
@@ -1140,7 +1141,6 @@
     m_listCtrl.SetPopupFullTextColumns({ 11, 12 });
 
     Resize();
-    OnBnClickedButtonSearch(); // 瑙﹀彂涓�娆℃煡璇笌棣栧睆濉厖
 
     return TRUE;  // return TRUE unless you set the focus to a control
 }
@@ -1200,6 +1200,10 @@
     else if (nIDEvent == 2) {
         UpdateWipData();  // 鍙仛澧為噺锛屼笉閲嶅缓
     }
+    else if (nIDEvent == 3) {
+        KillTimer(3);
+        OnBnClickedButtonSearch(); // 寤惰繜棣栧睆鏌ヨ锛岄伩鍏嶅崱浣� OnInitDialog
+    }
 
     CDialogEx::OnTimer(nIDEvent);
 }
@@ -1229,6 +1233,8 @@
 
 void CPageGlassList::OnBnClickedButtonSearch()
 {
+    CWaitCursor wait; // 鏄剧ず绛夊緟鍏夋爣锛屾彁绀烘鍦ㄥ姞杞�
+
     // 鑾峰彇鍏抽敭瀛楄緭鍏ユ鍐呭
     CString strKeyword;
     GetDlgItemText(IDC_EDIT_KEYWORD, strKeyword);
@@ -2059,4 +2065,4 @@
     double randomNoise = (rand() % 100 - 50) / 100.0 * variation * 0.3;  // 闅忔満鍣0
     
     return baseValue + timeTrend + randomNoise;
-}
\ No newline at end of file
+}
diff --git a/SourceCode/Bond/Servo/Model.cpp b/SourceCode/Bond/Servo/Model.cpp
index 6882783..ed29052 100644
--- a/SourceCode/Bond/Servo/Model.cpp
+++ b/SourceCode/Bond/Servo/Model.cpp
@@ -184,6 +184,7 @@
 
 int CModel::init()
 {
+	const ULONGLONG boot_model_begin = GetTickCount64();
 	CString strIniFile;
 	CString strUnitId;
 	strIniFile.Format(_T("%s\\ServoConfiguration.ini"), (LPTSTR)(LPCTSTR)m_strWorkDir);
@@ -214,6 +215,7 @@
 	CLog::GetLog()->SetLogsDir(strLogDir);
 	CLog::GetLog()->SetEquipmentId((LPTSTR)(LPCTSTR)strUnitId);
 	LOGI("\r\n\r\n~~~ Prog Start! ~~~");
+	LOGI("[BOOT][MODEL] init begin");
 
 
 	SECSListener listener;
@@ -419,6 +421,8 @@
 	}
 	strVarialbleFile.Format(_T("%s\\HsmsPassive.cache"), (LPTSTR)(LPCTSTR)m_strWorkDir);
 	m_hsmsPassive.loadCacheFromFile(strVarialbleFile);
+	LOGI("[BOOT][MODEL] HSMS config loaded, cost=%llu ms",
+		(unsigned long long)(GetTickCount64() - boot_model_begin));
 
 
 	SERVO::MasterListener masterListener;
@@ -922,6 +926,8 @@
 	char szBuffer[MAX_PATH];
 	sprintf_s(szBuffer, MAX_PATH, "%s\\AlarmList.csv", (LPTSTR)(LPCTSTR)m_strWorkDir);
 	alarmManager.readAlarmFile(szBuffer);
+	LOGI("[BOOT][MODEL] Alarm list loaded, cost=%llu ms",
+		(unsigned long long)(GetTickCount64() - boot_model_begin));
 
 
 	// Glass鏁版嵁搴�
@@ -930,6 +936,8 @@
 	GlassLogDb::Init(path);
 
 
+	LOGI("[BOOT][MODEL] init finished, total cost=%llu ms",
+		(unsigned long long)(GetTickCount64() - boot_model_begin));
 	return 0;
 }
 
diff --git a/SourceCode/Bond/Servo/ServoDlg.cpp b/SourceCode/Bond/Servo/ServoDlg.cpp
index 77e626f..7c6641f 100644
--- a/SourceCode/Bond/Servo/ServoDlg.cpp
+++ b/SourceCode/Bond/Servo/ServoDlg.cpp
@@ -363,6 +363,8 @@
 BOOL CServoDlg::OnInitDialog()
 {
 	CDialogEx::OnInitDialog();
+	const ULONGLONG boot_ui_begin = GetTickCount64();
+	CWaitCursor wait; // 鏁翠釜鍒濆鍖栨湡鏄剧ず绛夊緟鍏夋爣锛岄伩鍏嶇敤鎴疯浠ヤ负鍗℃
 
 	// 灏嗏�滃叧浜�...鈥濊彍鍗曢」娣诲姞鍒扮郴缁熻彍鍗曚腑銆�
 
@@ -398,13 +400,19 @@
 
 
 	// model init
+	const ULONGLONG boot_model_begin = GetTickCount64();
 	theApp.m_model.init();
+	LOGI("[BOOT][UI] m_model.init finished, cost=%llu ms (since OnInit start %llu ms)",
+		(unsigned long long)(GetTickCount64() - boot_model_begin),
+		(unsigned long long)(GetTickCount64() - boot_ui_begin));
 	SetTimer(TIMER_ID_LOGIN, 1500, nullptr);
+	LOGI("[BOOT][UI] after model.init, elapsed=%llu ms", (unsigned long long)(GetTickCount64() - boot_ui_begin));
 
 	// 鑿滃崟
 	CMenu menu;
 	menu.LoadMenu(IDR_MENU_APP);
 	SetMenu(&menu);
+	LOGI("[BOOT][UI] menu loaded, elapsed=%llu ms", (unsigned long long)(GetTickCount64() - boot_ui_begin));
 
 
 	// toolbar
@@ -417,23 +425,46 @@
 	ASSERT(hMenu);
 	::EnableMenuItem(hMenu, ID_OPEATOR_SWITCH, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
 	m_pTopToolbar->GetBtn(IDC_BUTTON_JOBS)->EnableWindow(TRUE);
+	LOGI("[BOOT][UI] toolbar created, elapsed=%llu ms", (unsigned long long)(GetTickCount64() - boot_ui_begin));
 
 
 	// Tab
+	const ULONGLONG boot_pages_begin = GetTickCount64();
 	m_pPageGraph1 = new CPageGraph1();
 	m_pPageGraph1->Create(IDD_PAGE_GRAPH1, this);
+	LOGI("[BOOT][UI] page Graph1 created, cost=%llu ms (elapsed=%llu ms)",
+		(unsigned long long)(GetTickCount64() - boot_pages_begin),
+		(unsigned long long)(GetTickCount64() - boot_ui_begin));
 	m_pPageGraph2 = new CPageGraph2();
 	m_pPageGraph2->Create(IDD_PAGE_GRAPH2, this);
+	LOGI("[BOOT][UI] page Graph2 created, cost=%llu ms (elapsed=%llu ms)",
+		(unsigned long long)(GetTickCount64() - boot_pages_begin),
+		(unsigned long long)(GetTickCount64() - boot_ui_begin));
 	m_pPageGlassList = new CPageGlassList();
 	m_pPageGlassList->Create(IDD_PAGE_GLASS_LIST, this);
+	LOGI("[BOOT][UI] page GlassList created, cost=%llu ms (elapsed=%llu ms)",
+		(unsigned long long)(GetTickCount64() - boot_pages_begin),
+		(unsigned long long)(GetTickCount64() - boot_ui_begin));
 	m_pPageRecipe = new CPageRecipe();
 	m_pPageRecipe->Create(IDD_PAGE_RECIPE, this);
+	LOGI("[BOOT][UI] page Recipe created, cost=%llu ms (elapsed=%llu ms)",
+		(unsigned long long)(GetTickCount64() - boot_pages_begin),
+		(unsigned long long)(GetTickCount64() - boot_ui_begin));
 	m_pPageAlarm = new CPageAlarm();
 	m_pPageAlarm->Create(IDD_DIALOG_ALARM, this);
+	LOGI("[BOOT][UI] page Alarm created, cost=%llu ms (elapsed=%llu ms)",
+		(unsigned long long)(GetTickCount64() - boot_pages_begin),
+		(unsigned long long)(GetTickCount64() - boot_ui_begin));
 	m_pPageLog = new CPageLog();
 	m_pPageLog->Create(IDD_DIALOG_LOG, this);
+	LOGI("[BOOT][UI] page Log created, cost=%llu ms (elapsed=%llu ms)",
+		(unsigned long long)(GetTickCount64() - boot_pages_begin),
+		(unsigned long long)(GetTickCount64() - boot_ui_begin));
 	m_pPageTransferLog = new CPageTransferLog();
 	m_pPageTransferLog->Create(IDD_PAGE_TRANSFER_LOG, this);
+	LOGI("[BOOT][UI] page TransferLog created, cost=%llu ms (elapsed=%llu ms)",
+		(unsigned long long)(GetTickCount64() - boot_pages_begin),
+		(unsigned long long)(GetTickCount64() - boot_ui_begin));
 
 	CHmTab* m_pTab = CHmTab::Hook(GetDlgItem(IDC_TAB1)->m_hWnd);
 	m_pTab->SetPaddingLeft(20);
@@ -448,6 +479,7 @@
 	m_pTab->SetCurSel(0);
 	m_pTab->SetBkgndColor(RGB(222, 222, 222));
 	ShowChildPage(0);
+	LOGI("[BOOT][UI] pages/tabs created, elapsed=%llu ms", (unsigned long long)(GetTickCount64() - boot_ui_begin));
 
 	// 璇诲彇闈㈡澘瀹�
 	CString strIniFile;
@@ -467,11 +499,13 @@
 	m_pPanelAttributes = new CPanelAttributes();
 	m_pPanelAttributes->Create(IDD_PANEL_ATTRIBUTES, this);
 	
+	LOGI("[BOOT][UI] panels created, elapsed=%llu ms", (unsigned long long)(GetTickCount64() - boot_ui_begin));
 
 	// statusbar
 	m_pMyStatusbar = new CMyStatusbar();
 	m_pMyStatusbar->Create(IDD_STATUSBAR, this);
 	m_pMyStatusbar->ShowWindow(SW_SHOW);
+	LOGI("[BOOT][UI] statusbar created, elapsed=%llu ms", (unsigned long long)(GetTickCount64() - boot_ui_begin));
 
 
 
@@ -488,10 +522,23 @@
 	InitRxWindows();
 	Resize();
 
+	// 鍔犺浇鍘嗗彶缂撳瓨鎻愮ず
+	{
+		CWaitCursor wait;
+		if (m_pMyStatusbar != nullptr) {
+			m_pMyStatusbar->setRunTimeText(_T("姝e湪鍔犺浇鍘嗗彶缂撳瓨..."));
+			m_pMyStatusbar->UpdateWindow();
+		}
+		LOGI("[BOOT][UI] before master.init, elapsed=%llu ms", (unsigned long long)(GetTickCount64() - boot_ui_begin));
 
 	// 鐩稿綋浜庡欢鏃惰皟鐢╩aster鐨勫垵濮嬪寲
+	const ULONGLONG boot_master_begin = GetTickCount64();
 	theApp.m_model.m_master.init();
+	LOGI("[BOOT][UI] m_master.init finished, cost=%llu ms (since OnInit start %llu ms)",
+		(unsigned long long)(GetTickCount64() - boot_master_begin),
+		(unsigned long long)(GetTickCount64() - boot_ui_begin));
 	theApp.m_model.loadPortParams();
+	}
 
 
 	// 鍒濆鍖杕aster浠ュ悗闇�瑕佹帶浠剁粦瀹氭暟鎹�
@@ -504,6 +551,9 @@
 	//SystemLogManager::getInstance.
 
 
+	LOGI("[BOOT][UI] OnInitDialog finished, total cost=%llu ms",
+		(unsigned long long)(GetTickCount64() - boot_ui_begin));
+
 	return TRUE;  // 闄ら潪灏嗙劍鐐硅缃埌鎺т欢锛屽惁鍒欒繑鍥� TRUE
 }
 

--
Gitblit v1.9.3