From 50a42e5d72e2f8cf92ff9b2273e0442977dbcefd Mon Sep 17 00:00:00 2001
From: LAPTOP-T815PCOQ\25526 <mr.liuyang@126.com>
Date: 星期三, 18 十二月 2024 18:28:02 +0800
Subject: [PATCH] 1. 对话框基类添加动态控件管理 2. 对话框基类主题切换功能

---
 SourceCode/Bond/BondEq/CBaseDlg.cpp |  166 +++++++++++++++++++++++++++++++++++++++++++++----------
 1 files changed, 135 insertions(+), 31 deletions(-)

diff --git a/SourceCode/Bond/BondEq/CBaseDlg.cpp b/SourceCode/Bond/BondEq/CBaseDlg.cpp
index d424513..2ddd896 100644
--- a/SourceCode/Bond/BondEq/CBaseDlg.cpp
+++ b/SourceCode/Bond/BondEq/CBaseDlg.cpp
@@ -2,9 +2,16 @@
 #include "CBaseDlg.h"
 #include "GridCtrl.h"
 
+// 全局主题对象
+Theme g_lightTheme = { RGB(255, 255, 255), RGB(0, 0, 0), RGB(240, 240, 240), RGB(200, 200, 200) };
+Theme g_darkTheme = { RGB(40, 40, 40), RGB(255, 255, 255), RGB(60, 60, 60), RGB(80, 80, 80) };
+
+CFont g_defaultFont;
+Theme* g_currentTheme = &g_lightTheme;
+
 IMPLEMENT_DYNAMIC(CBaseDlg, CDialogEx)
 
-CBaseDlg::CBaseDlg(UINT id, CWnd* pPage) : CDialogEx(id, pPage)
+CBaseDlg::CBaseDlg(UINT id, CWnd* pPage) : CDialogEx(id, pPage), m_bResizing(false)
 {
 	m_nInitialWidth = 0;
 	m_nInitialHeight = 0;
@@ -12,23 +19,21 @@
 
 CBaseDlg::~CBaseDlg()
 {
-	for (auto& pair : m_mapFonts) {
-		if (pair.second) {
-			pair.second->DeleteObject();
-			delete pair.second;
-		}
-	}
+	// shared_ptr会自动清理内存,不需要手动删除
 	m_mapFonts.clear();
+	m_mapCtrlLayouts.clear();
+	m_mapControls.clear();
 }
 
 CFont* CBaseDlg::GetOrCreateFont(int nFontSize)
 {
 	auto it = m_mapFonts.find(nFontSize);
 	if (it != m_mapFonts.end()) {
-		return it->second;
+		return it->second.get();
 	}
 
-	CFont* font = new CFont();
+	// 使用 shared_ptr 来管理字体对象
+	auto font = std::make_shared<CFont>();
 	LOGFONT logFont = { 0 };
 	_tcscpy_s(logFont.lfFaceName, _T("Segoe UI"));
 	logFont.lfHeight = -nFontSize;
@@ -36,17 +41,15 @@
 	font->CreateFontIndirect(&logFont);
 	m_mapFonts[nFontSize] = font;
 
-	return font;
+	return font.get();
 }
 
 void CBaseDlg::SetDefaultFont()
 {
 	CFont* defaultFont = GetOrCreateFont(12);
 
-	// 遍历所有控件,应用默认字体
 	CWnd* pWnd = GetWindow(GW_CHILD);
 	while (pWnd) {
-		// 跳过特殊控件(如 MFCGridCtrl)
 		TCHAR szClassName[256];
 		GetClassName(pWnd->m_hWnd, szClassName, sizeof(szClassName));
 		if (_tcsicmp(szClassName, _T("MFCGridCtrl")) == 0) {
@@ -59,13 +62,87 @@
 	}
 }
 
+BOOL CBaseDlg::AddControl(UINT nCtrlID, CWnd* pControl)
+{
+	// 确保控件不重复添加
+	if (m_mapControls.find(nCtrlID) != m_mapControls.end()) {
+		return FALSE;  // 控件已经存在
+	}
+
+	m_mapControls[nCtrlID] = std::unique_ptr<CWnd>(pControl);
+	return TRUE;
+}
+
+BOOL CBaseDlg::RemoveControl(UINT nCtrlID)
+{
+	auto it = m_mapControls.find(nCtrlID);
+	if (it != m_mapControls.end()) {
+		m_mapControls.erase(it);
+		return TRUE;
+	}
+	return FALSE;
+}
+
+BOOL CBaseDlg::UpdateControlText(UINT nCtrlID, const CString& strText)
+{
+	auto it = m_mapControls.find(nCtrlID);
+	if (it != m_mapControls.end()) {
+		CWnd* pWnd = it->second.get();
+		if (pWnd->GetSafeHwnd() != nullptr)
+		{
+			pWnd->SetWindowText(strText);
+			return TRUE;
+		}
+	}
+	return FALSE;
+}
+
+CWnd* CBaseDlg::GetControl(UINT nCtrlID)
+{
+	auto it = m_mapControls.find(nCtrlID);
+	if (it != m_mapControls.end()) {
+		return it->second.get();
+	}
+	return nullptr;
+}
+
+void CBaseDlg::SwitchTheme(ThemeType themeType)
+{
+	// 使用 map 来根据 themeType 查找主题
+	static const std::unordered_map<ThemeType, Theme*> themeMap = {
+		{ ThemeType::Light, &g_lightTheme },
+		{ ThemeType::Dark, &g_darkTheme }
+	};
+
+	// 设置当前主题
+	auto it = themeMap.find(themeType);
+	if (it != themeMap.end()) {
+		g_currentTheme = it->second;
+	}
+	else {
+		g_currentTheme = &g_lightTheme;
+	}
+
+	// 更新控件的外观
+	CWnd* pWnd = GetWindow(GW_CHILD);
+	while (pWnd) {
+		pWnd->Invalidate(); // 重绘控件
+		pWnd = pWnd->GetNextWindow();
+	}
+
+	// 更新对话框背景颜色
+	SetBackgroundColor(g_currentTheme->backgroundColor);
+}
+
 void CBaseDlg::AdjustControls(float dScaleX, float dScaleY)
 {
+	if (m_bResizing) return; // 防止在调整过程中重复调整
+
+	m_bResizing = true;
 	CWnd* pWnd = GetWindow(GW_CHILD);
 	while (pWnd) {
 		int nCtrlID = pWnd->GetDlgCtrlID();
-		if (nCtrlID != -1 && m_mapCtrlLayouts.find(nCtrlID) != m_mapCtrlLayouts.end())
-		{
+		if (nCtrlID != -1 && m_mapCtrlLayouts.find(nCtrlID) != m_mapCtrlLayouts.end()) {
 			CRect originalRect = m_mapCtrlLayouts[nCtrlID];
 			CRect newRect(
 				static_cast<int>(originalRect.left * dScaleX),
@@ -95,6 +172,7 @@
 		}
 		pWnd = pWnd->GetNextWindow();
 	}
+	m_bResizing = false;
 }
 
 void CBaseDlg::AdjustControlFont(CWnd* pWnd, int nWidth, int nHeight)
@@ -102,17 +180,14 @@
 	TCHAR szClassName[256];
 	GetClassName(pWnd->m_hWnd, szClassName, sizeof(szClassName));
 
-	// 跳过特殊控件(如 MFCGridCtrl)
 	if (_tcsicmp(szClassName, _T("MFCGridCtrl")) == 0) {
 		return;
 	}
 
-	// 根据控件高度动态调整字体大小
 	int fontSize = nHeight / 2;
 	if (fontSize < 8) fontSize = 8;
 	if (fontSize > 32) fontSize = 32;
 
-	// 获取或创建字体
 	CFont* pFont = GetOrCreateFont(fontSize);
 
 	pWnd->SetFont(pFont);
@@ -122,35 +197,44 @@
 BEGIN_MESSAGE_MAP(CBaseDlg, CDialogEx)
 	ON_WM_SIZE()
 	ON_WM_GETMINMAXINFO()
+	ON_WM_CTLCOLOR()
 END_MESSAGE_MAP()
 
 BOOL CBaseDlg::OnInitDialog()
 {
 	CDialogEx::OnInitDialog();
 
-	// TODO:  在此添加额外的初始化
+	// 获取当前语言
+	LANGID langId = GetUserDefaultLangID();
+	if (langId == LANG_CHINESE) {
+		// 加载中文资源
+	}
+	else {
+		// 加载英文资源
+	}
+
+	// 获取对话框的工作区(屏幕可用区域)
 	CRect screenRect, dlgRect, clientRect;
 	SystemParametersInfo(SPI_GETWORKAREA, 0, &screenRect, 0);
-
 	GetClientRect(&clientRect);
 	m_nInitialWidth = clientRect.Width();
 	m_nInitialHeight = clientRect.Height();
 
-	// 初始化默认字体
+	// 设置默认字体
 	CFont* pDefaultFont = GetOrCreateFont(12);
 
-	// 遍历所有子控件,记录初始位置并设置默认字体
+	// 遍历子窗口(控件)
 	CWnd* pWnd = GetWindow(GW_CHILD);
 	while (pWnd) {
 		int nCtrlID = pWnd->GetDlgCtrlID();
 		if (nCtrlID != -1) {
-			// 记录控件初始布局
+			// 保存控件的初始布局
 			CRect ctrlRect;
 			pWnd->GetWindowRect(&ctrlRect);
 			ScreenToClient(&ctrlRect);
 			m_mapCtrlLayouts[nCtrlID] = ctrlRect;
 
-			// 跳过特殊控件(如 MFCGridCtrl)
+			// 排除不需要操作的控件(如自定义控件 GridCtrl)
 			TCHAR szClassName[256];
 			GetClassName(pWnd->m_hWnd, szClassName, sizeof(szClassName));
 			if (_tcsicmp(szClassName, _T("MFCGridCtrl")) == 0) {
@@ -158,12 +242,13 @@
 				continue;
 			}
 
-			// 设置默认字体
+			// 设置控件的默认字体
 			pWnd->SetFont(pDefaultFont);
 		}
 		pWnd = pWnd->GetNextWindow();
 	}
 
+	// 将对话框居中
 	GetWindowRect(&dlgRect);
 	int dlgWidth = dlgRect.Width() * 2;
 	int dlgHeight = dlgRect.Height() * 2;
@@ -179,31 +264,50 @@
 	int centerY = screenRect.top + (screenRect.Height() - dlgHeight) / 2;
 	MoveWindow(centerX, centerY, dlgWidth, dlgHeight);
 
-	return TRUE;  // return TRUE unless you set the focus to a control
-	// 异常: OCX 属性页应返回 FALSE
+	return TRUE;
 }
 
 void CBaseDlg::OnSize(UINT nType, int cx, int cy)
 {
 	CDialogEx::OnSize(nType, cx, cy);
 
-	// TODO: 在此处添加消息处理程序代码
 	if (nType == SIZE_MINIMIZED || m_mapCtrlLayouts.empty()) {
 		return;
 	}
 
+	// 检查尺寸变化是否足够大,避免频繁调整
+	//static int lastWidth = 0, lastHeight = 0;
+	//if (abs(cx - lastWidth) < 10 && abs(cy - lastHeight) < 10) {
+	//	return;
+	//}
+
+	//lastWidth = cx;
+	//lastHeight = cy;
+
+	// 计算比例并调整布局
 	float dScaleX = static_cast<float>(cx) / m_nInitialWidth;
 	float dScaleY = static_cast<float>(cy) / m_nInitialHeight;
 
-	// 遍历对话框中的所有控件
 	AdjustControls(dScaleX, dScaleY);
 }
 
 void CBaseDlg::OnGetMinMaxInfo(MINMAXINFO* lpMMI)
 {
-	// TODO: 在此添加消息处理程序代码和/或调用默认值
-	lpMMI->ptMinTrackSize.x = 400; // 最小宽度
-	lpMMI->ptMinTrackSize.y = 300; // 最小高度
+	lpMMI->ptMinTrackSize.x = 400;
+	lpMMI->ptMinTrackSize.y = 300;
 
 	CDialogEx::OnGetMinMaxInfo(lpMMI);
+}
+
+HBRUSH CBaseDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
+{
+	if (g_currentTheme) {
+		pDC->SetBkColor(g_currentTheme->backgroundColor);
+		pDC->SetTextColor(g_currentTheme->textColor);
+
+		// 返回背景画刷
+		return CreateSolidBrush(g_currentTheme->backgroundColor);
+	}
+
+	return CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
 }
\ No newline at end of file

--
Gitblit v1.9.3