LAPTOP-T815PCOQ\25526
2024-12-18 50a42e5d72e2f8cf92ff9b2273e0442977dbcefd
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);
}