#include "stdafx.h" #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), m_bResizing(false) { m_nInitialWidth = 0; m_nInitialHeight = 0; } CBaseDlg::~CBaseDlg() { // 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.get(); } // ʹÓà shared_ptr À´¹ÜÀí×ÖÌå¶ÔÏó auto font = std::make_shared(); LOGFONT logFont = { 0 }; _tcscpy_s(logFont.lfFaceName, _T("Segoe UI")); logFont.lfHeight = -nFontSize; logFont.lfQuality = CLEARTYPE_QUALITY; font->CreateFontIndirect(&logFont); m_mapFonts[nFontSize] = font; return font.get(); } void CBaseDlg::SetDefaultFont() { CFont* defaultFont = GetOrCreateFont(12); CWnd* pWnd = GetWindow(GW_CHILD); while (pWnd) { TCHAR szClassName[256]; GetClassName(pWnd->m_hWnd, szClassName, sizeof(szClassName)); if (_tcsicmp(szClassName, _T("MFCGridCtrl")) == 0) { pWnd = pWnd->GetNextWindow(); continue; } pWnd->SetFont(defaultFont, TRUE); pWnd = pWnd->GetNextWindow(); } } BOOL CBaseDlg::AddControl(UINT nCtrlID, CWnd* pControl) { // È·±£¿Ø¼þ²»Öظ´Ìí¼Ó if (m_mapControls.find(nCtrlID) != m_mapControls.end()) { return FALSE; // ¿Ø¼þÒѾ­´æÔÚ } m_mapControls[nCtrlID] = std::unique_ptr(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 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()) { CRect originalRect = m_mapCtrlLayouts[nCtrlID]; CRect newRect( static_cast(originalRect.left * dScaleX), static_cast(originalRect.top * dScaleY), static_cast(originalRect.right * dScaleX), static_cast(originalRect.bottom * dScaleY)); TCHAR szClassName[256]; GetClassName(pWnd->m_hWnd, szClassName, sizeof(szClassName)); if (_tcsicmp(szClassName, _T("ComboBox")) == 0) { CComboBox* pComboBox = (CComboBox*)pWnd; pComboBox->SetItemHeight(-1, newRect.Height()); // -1 ±íʾËùÓÐÏîµÄ¸ß¶È } if (_tcsicmp(szClassName, _T("MFCGridCtrl")) == 0) { CGridCtrl* pGridCtrl = (CGridCtrl*)pWnd; pGridCtrl->SetDefCellHeight(newRect.Height() / 21); pGridCtrl->ExpandColumnsToFit(TRUE); pGridCtrl->ExpandLastColumn(); pGridCtrl->Invalidate(); pGridCtrl->UpdateWindow(); } pWnd->MoveWindow(&newRect); AdjustControlFont(pWnd, newRect.Width(), newRect.Height()); } pWnd = pWnd->GetNextWindow(); } m_bResizing = false; } void CBaseDlg::AdjustControlFont(CWnd* pWnd, int nWidth, int nHeight) { TCHAR szClassName[256]; GetClassName(pWnd->m_hWnd, szClassName, sizeof(szClassName)); 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); pWnd->Invalidate(); // ˢпؼþÏÔʾ } BEGIN_MESSAGE_MAP(CBaseDlg, CDialogEx) ON_WM_SIZE() ON_WM_GETMINMAXINFO() ON_WM_CTLCOLOR() END_MESSAGE_MAP() BOOL CBaseDlg::OnInitDialog() { CDialogEx::OnInitDialog(); // »ñÈ¡µ±Ç°ÓïÑÔ 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; // Åųý²»ÐèÒª²Ù×÷µÄ¿Ø¼þ£¨Èç×Ô¶¨Òå¿Ø¼þ GridCtrl£© TCHAR szClassName[256]; GetClassName(pWnd->m_hWnd, szClassName, sizeof(szClassName)); if (_tcsicmp(szClassName, _T("MFCGridCtrl")) == 0) { pWnd = pWnd->GetNextWindow(); continue; } // ÉèÖÿؼþµÄĬÈÏ×ÖÌå pWnd->SetFont(pDefaultFont); } pWnd = pWnd->GetNextWindow(); } // ½«¶Ô»°¿ò¾ÓÖÐ GetWindowRect(&dlgRect); int dlgWidth = dlgRect.Width() * 2; int dlgHeight = dlgRect.Height() * 2; if (dlgWidth > screenRect.Width()) { dlgWidth = screenRect.Width(); } if (dlgHeight > screenRect.Height()) { dlgHeight = screenRect.Height(); } int centerX = screenRect.left + (screenRect.Width() - dlgWidth) / 2; int centerY = screenRect.top + (screenRect.Height() - dlgHeight) / 2; MoveWindow(centerX, centerY, dlgWidth, dlgHeight); return TRUE; } void CBaseDlg::OnSize(UINT nType, int cx, int cy) { CDialogEx::OnSize(nType, cx, cy); 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(cx) / m_nInitialWidth; float dScaleY = static_cast(cy) / m_nInitialHeight; AdjustControls(dScaleX, dScaleY); } void CBaseDlg::OnGetMinMaxInfo(MINMAXINFO* lpMMI) { 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); }