xref: /MusicPlayer2/MusicPlayer2/BaseDialog.h (revision 6c7c104acdae990ed2acfcc80776176faf337a71)
1 #pragma once
2 #include "IconMgr.h"
3 
4 // CBaseDialog 对话框
5 
6 class CBaseDialog : public CDialog
7 {
8     DECLARE_DYNAMIC(CBaseDialog)
9 
10 public:
11     CBaseDialog(UINT nIDTemplate, CWnd* pParent = NULL);   // 标准构造函数
12     virtual ~CBaseDialog();
13 
14     // 复制自CDialogEx,与其功能相同(新增滑动条控件和超链接控件的处理)
15     void SetBackgroundColor(COLORREF color, BOOL bRepaint = TRUE);
16 
17     static HWND GetUniqueHandel(LPCTSTR dlg_name);          //获指定窗口唯一的句柄
18     static const std::map<CString, HWND>& AllUniqueHandels();   //获取所有窗口的句柄
19     static void CloseAllWindow();
20 
21     //将对话框以非模态对话框的模式显示
22     void ShowModelessDialog(UINT id);
23 
24 private:
25     void LoadConfig();
26     void SaveConfig() const;
27     // 重新应用布局管理器参数,这会使控件的基础大小/位置以当前为准
28     void ReLoadLayoutResource();
29 
30 private:
31     UINT m_nDialogID;                                   // 成员变量用于保存资源 ID
32     CSize m_min_size{};
33     CSize m_window_size{ -1, -1 };
34     CBrush m_brBkgr;    // 在CDialogEx是保护,我改成了私有,我想集中在CBaseDialog处理,如果有需求可以改回去
35     CDC* m_pDC = nullptr;                               // InitializeControls期间有效,用于测量文本长度
36 
37     static std::map<CString, HWND> m_unique_hwnd;        //针对每一个派生类的唯一的窗口句柄
38 
39     bool m_is_modeless_dialog{};                        //是否为非模态对话框(仅当调用了ShowModelessDialog时会变为true)
40 
41 public:
42     void SetIcon(IconMgr::IconType type, BOOL bBigIcon);
43     void SetButtonIcon(UINT id, IconMgr::IconType type);
44     void ShowDlgCtrl(UINT id, bool show);
45     void EnableDlgCtrl(UINT id, bool enable);
46 
47 protected:
48     // 仅在InitializeControls期间可用,测量控件文本长度
49     CRect GetTextExtent(const CString& text);
50 
51     struct CtrlTextInfo
52     {
53         // 这里的枚举作为能够类型检查的int使用,三个数字太容易打错很难用,如果要修改请重命名统一修改
54         // Col具体值大小无意义,只表示列之间的相对顺序以及哪些控件同一列,实际上没有数量限制,需要的话可以增加
55         enum Col { L4 = -4, L3 = -3, L2 = -2, L1 = -1, C0 = 0, R1 = 1, R2 = 2, R3 = 3, R4 = 4, UN_USE = 100 };
56         // 按钮因为可能有图标推荐W32,超链接控件因为有额外的<a></a>所以使用W_50抵消
57         enum Width { W_50 = -50, W0 = 0, W16 = 16, W32 = 32, W40 = 40, W60 = 60, W64 = 64, W96 = 96, W128 = 128, W256 = 256 };
58 
59         Col col_index{ UN_USE };    // 指示控件的位置 ,从左向右递增,小于0左贴靠,大于0右贴靠,等于0使用剩余空间
60         UINT id{ 0 };               // 控件ID
61         Width ext_width{ W0 };      // 控件宽度至少需要“文字宽度+ext_width”(内部会执行DPI转换 theApp.DPI(ext_width))
62     };
63     // 仅在InitializeControls期间可用,根据文本长度重排控件,不会进行任何垂直方向调整,不会改变控件间距
64     // 只会增加控件宽度故推荐在资源中设置更小的宽度,使用此方法调整到合适的状态
65     // 优先保证中间的剩余宽度(或col_index为0的控件宽度)至少为center_min_width
66     // 空间不足时其他控件文字会无法完全显示(此时应重新设计窗口)(此方法仅适用于文字不可能太长的情况)
67     void RepositionTextBasedControls(const vector<CtrlTextInfo>& items, CtrlTextInfo::Width center_min_width = CtrlTextInfo::W16);
68 
69     // 设置窗口的最小大小,如果未设置,则使用窗口的初始大小作为最小大小
70     // 请在返回true的InitializeControls调用,使布局管理器能够重新获取新的窗口最小大小
71     // CMFCDynamicLayout::SetMinSize的参数与GetWindowRect(含边框)对应,不是m_min_size(不含边框),不通用
72     void SetMinSize(int cx, int cy);
73 
74     // 此方法返回空字符串时不启用相关功能
75     // 返回字符串非空时此字符串作为标识实现记住对话框大小 / 窗口单例 / 统一关闭
76     virtual CString GetDialogName() const = 0;
77     // 当设置DialogName时通过重载此方法返回false实现不保存对话框大小
IsRememberDialogSizeEnable()78     virtual bool IsRememberDialogSizeEnable() const { return true; };
79     // 由CBaseDialog::OnInitDialog在还原配置中窗口大小前调用
80     // 派生类执行部分控件初始化,比如设置控件文本,重排控件RepositionTextBasedControls
81     // 返回true会重新应用布局管理器参数,这会使控件动态布局管理器的基础大小/位置以当前为准
82     // 与实际窗口大小相关的初始化(比如表格列宽)应在派生类的OnInitDialog进行
InitializeControls()83     virtual bool InitializeControls() { return false; };   // 此处最好是纯虚方法但迁移需要时间
84 
85     void SetDlgControlText(int id, const wchar_t* key);
86 
87     virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
88 
89     DECLARE_MESSAGE_MAP()
90 public:
91     virtual BOOL OnInitDialog();
92     afx_msg void OnDestroy();
93     afx_msg void OnGetMinMaxInfo(MINMAXINFO* lpMMI);
94     afx_msg void OnSize(UINT nType, int cx, int cy);
95     virtual INT_PTR DoModal();
96     afx_msg BOOL OnEraseBkgnd(CDC* pDC);
97     afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
98     afx_msg void OnClose();
99     virtual void OnOK();
100     virtual void OnCancel();
101 };
102