| | |
| | | #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; |
| | |
| | | |
| | | 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; |
| | |
| | | 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) { |
| | |
| | | } |
| | | } |
| | | |
| | | 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), |
| | |
| | | } |
| | | 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)); |
| | | |
| | | // 跳过特殊控件(如 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); |
| | |
| | | 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) { |
| | |
| | | continue; |
| | | } |
| | | |
| | | // 设置默认字体 |
| | | // 设置控件的默认字体 |
| | | pWnd->SetFont(pDefaultFont); |
| | | } |
| | | pWnd = pWnd->GetNextWindow(); |
| | | } |
| | | |
| | | // 将对话框居中 |
| | | GetWindowRect(&dlgRect); |
| | | int dlgWidth = dlgRect.Width() * 2; |
| | | int dlgHeight = dlgRect.Height() * 2; |
| | |
| | | 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); |
| | | } |