使用CDialogResizeEx实现对话框大小持久化

在许多项目中,经常需要实现一个可以调整大小的对话框。WTL提供了一个优秀的模板类CDialogResize,通过从这个模板类派生,可以很容易地实现一个可调整大小的对话框。然而,CDialogResize类缺乏一个功能,即无法持久化对话框的大小。为了解决这个问题,引入了一个小型的扩展类CDialogResizeEx,它允许将对话框的大小存储在Windows注册表中,以确保下次显示对话框时使用之前的大小。

如何使用CDialogResizeEx

要使用这个模板类与现有的CDialogResize派生类,可以按照以下步骤进行:

  1. 从CDialogResizeEx而不是CDialogResize派生。
  2. 修改CHAIN_MSG_MAP调用,使用CDialogResizeEx。
  3. 在WM_INITDIALOG处理器中调用DlgResize_InitEx而不是DlgResize_Init。
  4. 调用LoadSize方法来指定注册表根父项和键名,对话框大小将从这里加载/保存。

例如,可能有一个对话框类如下所示:

class CMyDialog : public CDialogImpl, public CDialogResizeEx { public: enum { IDD = IDD_MYDIALOG }; BEGIN_DLGRESIZE_MAP(CMyDialog) ... END_DLGRESIZE_MAP() BEGIN_MSG_MAP(CMyDialog) MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) ... CHAIN_MSG_MAP(CDialogResizeEx) END_MSG_MAP() LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) { DlgResize_InitEx(); CenterWindow(); return TRUE; } };

接下来,显示对话框的代码可能如下:

CMyDialog dlg; dlg.LoadSize(HKEY_CURRENT_USER, _T("Software\\CodeProject\\DialogResizeEx")); dlg.DoModal();

这就是全部内容,实现起来应该只需要几分钟。

注册表条目

该类将使用以下值名将对话框大小保存到注册表中:

  • dialog_nnn_cx
  • dialog_nnn_cy

其中nnn是对话框ID。这允许在应用程序中存储任意数量的对话框大小。

CMyDialog dlg; dlg.m_size.cx = 640; dlg.m_size.cy = 480; dlg.DoModal(); #pragma once template <class T> class CDialogResizeEx : public CDialogResize<T> { public: CSize m_size; HKEY m_hKeyParent; LPCTSTR m_lpszKeyName; CDialogResizeEx(void) : m_size(0, 0), m_hKeyParent(NULL), m_lpszKeyName(NULL) {}; void DlgResize_InitEx(bool bAddGripper = true, bool bUseMinTrackSize = true, DWORD dwForceStyle = WS_CLIPCHILDREN) { DlgResize_Init(bAddGripper, bUseMinTrackSize, dwForceStyle); T* pT = static_cast<T*>(this); if (m_size.cx != 0 && m_size.cy != 0) { pT->SetWindowPos(NULL, 0, 0, m_size.cx, m_size.cy, SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE); CRect rectClient; pT->GetClientRect(&rectClient); DlgResize_UpdateLayout(rectClient.Width(), rectClient.Height()); } } void LoadSize(HKEY hKeyParent, LPCTSTR lpszKeyName) { m_hKeyParent = hKeyParent; m_lpszKeyName = lpszKeyName; ATL::CRegKey reg; if (reg.Open(hKeyParent, lpszKeyName, KEY_READ) == ERROR_SUCCESS) { DWORD dw; #if (_ATL_VER >= 0x0700) if (reg.QueryDWORDValue(FormatWidthValueName(), dw) == ERROR_SUCCESS) m_size.cx = dw; if (reg.QueryDWORDValue(FormatHeightValueName(), dw) == ERROR_SUCCESS) m_size.cy = dw; #else if (reg.QueryValue(dw, FormatWidthValueName()) == ERROR_SUCCESS) m_size.cx = dw; if (reg.QueryValue(dw, FormatHeightValueName()) == ERROR_SUCCESS) m_size.cy = dw; #endif } } void SaveSize(HKEY hKeyParent, LPCTSTR lpszKeyName) const { ATL::CRegKey reg; if (reg.Create(hKeyParent, lpszKeyName) == ERROR_SUCCESS) { #if (_ATL_VER >= 0x0700) reg.SetDWORDValue(FormatWidthValueName(), m_size.cx); reg.SetDWORDValue(FormatHeightValueName(), m_size.cy); #else reg.SetValue(m_size.cx, FormatWidthValueName()); reg.SetValue(m_size.cy, FormatHeightValueName()); #endif } } CString FormatWidthValueName(void) const { const T* pT = static_cast(this); CString strValueName; strValueName.Format(_T("dialog_%d_cx"), pT->IDD); return strValueName; } CString FormatHeightValueName(void) const { const T* pT = static_cast(this); CString strValueName; strValueName.Format(_T("dialog_%d_cy"), pT->IDD); return strValueName; } BEGIN_MSG_MAP(CDialogResizeEx) MESSAGE_HANDLER(WM_DESTROY, OnDestroy) CHAIN_MSG_MAP(CDialogResize<T>) END_MSG_MAP() LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) { T* pT = static_cast<T*>(this); CRect rect; pT->GetWindowRect(rect); m_size.cx = rect.Width(); m_size.cy = rect.Height(); if (m_hKeyParent != NULL && m_lpszKeyName != NULL) SaveSize(m_hKeyParent, m_lpszKeyName); bHandled = FALSE; return 0; } };
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485