MFC 实现动态控件调解和主题切换

[复制链接]
发表于 2025-11-23 19:10:21 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
在开辟桌面应用步调时,经常必要为差别的屏幕分辨率和用户界面需求动态调解控件的巨细,而且支持差别的主题(如淡色和深色模式)。在 MFC 中,固然有一些方法来实现这些功能,但实现起来每每比力繁琐。为了更好地管理控件的调解和主题切换,我们可以创建一个通用的基类来处理惩罚这些功能。
1. 需求分析

在一个范例的应用步调中,大概会遇到以下几种需求:

      
  • 动态调解控件巨细:当用户调解窗口巨细时,控件的巨细应根据窗口的变革自动调解。  
  • 主题切换:根据用户的偏好或体系设置,切换淡色(Light)或深色(Dark)主题。
为了满意这些需求,我们可以筹划一个 CBaseDlg 基类,该类继承自 CDialogEx,并提供以下功能:

      
  • 动态调解控件的巨细。  
  • 切换淡色和深色主题。
2. 筹划 CBaseDlg 基类

起首,界说 CBaseDlg 类,该类提供了管理控件结构、字体、主题切换等功能。
头文件(CBaseDlg.h)

  1. #pragma once
  2. #include <memory>
  3. #include <unordered_map>
  4. enum class ThemeType {
  5.    
  6.    
  7.         Light,  // 浅色主题
  8.         Dark    // 深色主题
  9. };
  10. struct Theme {
  11.    
  12.    
  13.         COLORREF backgroundColor;
  14.         COLORREF textColor;
  15.         COLORREF buttonColor;
  16.         COLORREF borderColor;
  17. };
  18. class CBaseDlg : public CDialogEx
  19. {
  20.    
  21.    
  22.         DECLARE_DYNAMIC(CBaseDlg)
  23. public:
  24.         CBaseDlg(UINT id, CWnd* pPage);                                // 标准构造函数
  25.         virtual ~CBaseDlg();                                                // 析构函数
  26.         // 字体管理
  27.         CFont* GetOrCreateFont(int nFontSize);                // 获取或创建字体
  28.         void SetDefaultFont();                                                // 设置默认字体
  29.         // 动态控件管理
  30.         BOOL AddControl(UINT nCtrlID, CWnd* pControl);                                        // 添加控件
  31.         BOOL RemoveControl(UINT nCtrlID);                                                                // 移除控件
  32.         BOOL UpdateControlText(UINT nCtrlID, const CString& strText);   // 更新控件文本
  33.         CWnd* GetControl(UINT nCtrlID);                                                                        // 获取控件
  34.         // 主题设置
  35.         void SwitchTheme(ThemeType themeType);                                                        // 切换主题
  36. private:
  37.         void AdjustControls(float dScaleX, float dScaleY);                                // 调整控件大小
  38.         void AdjustControlFont(CWnd* pWnd, int nWidth, int nHeight);        // 调整控件字体
  39. private:
  40.         bool m_bResizing;                                                                                        // 控件是否正在调整大小
  41.         int m_nInitialWidth;                                                                                // 对话框初始宽度
  42.         int m_nInitialHeight;                                                                                // 对话框初始高度
  43.         HBRUSH         m_hbrBackground;                                                                        // 画刷
  44.         COLORREF m_lastBackgroundColor;                                                          // 上一个背景颜色
  45.         std::unordered_map<int, CRect> m_mapCtrlLayouts;                        // 控件布局
  46.         std::map<UINT, std::unique_ptr<CWnd>> m_mapControls;                // 控件集合
  47.         std::unordered_map<int, std::shared_ptr<CFont>> m_mapFonts;        // 控件字体
  48.         DECLARE_MESSAGE_MAP()
  49. public:
  50.         virtual BOOL OnInitDialog();
  51.         afx_msg void OnSize(UINT nType, int cx, int cy);
  52.         afx_msg void OnGetMinMaxInfo(MINMAXINFO* lpMMI);
  53.         afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
  54. };
复制代码
源文件(CBaseDlg.cpp)

  1. #include "stdafx.h"
  2. #include "CBaseDlg.h"
  3. #include "GridCtrl.h"
  4. #include <windows.h>
  5. // 全局主题对象
  6. Theme g_lightTheme = {
  7.    
  8.     RGB(255, 255, 255), RGB(0, 0, 0), RGB(240, 240, 240), RGB(200, 200, 200) };
  9. Theme g_darkTheme = {
  10.    
  11.     RGB(40, 40, 40), RGB(255, 255, 255), RGB(60, 60, 60), RGB(80, 80, 80) }
复制代码
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表