WTLVisual C++ 7.1Visual Studio 6Visual C++ 7.0Visual Studio .NET 2003Windows 2003Windows 2000Visual C++ 6.0Windows XP中级开发Visual StudioWindowsC++
WTL CDialogResize 扩展






4.98/5 (16投票s)
2004年4月30日
2分钟阅读

59677

1969
对 WTL CDialogResize 模板的扩展,
引言
我很多项目中都使用的一个优秀的 WTL 模板是 CDialogResize<T>
。从这个模板派生你的对话框类,可以非常容易地实现一个可调整大小的对话框。但是,它缺少一个功能,即保存对话框大小,而我的小型扩展类就是为此目的而设计的。
CDialogResizeEx<T>
允许将对话框的大小存储在 Windows 注册表中,存储位置由你选择,确保下次显示对话框时,它使用之前的大小。
本文不介绍 WTL CDialogResize
类——有关其工作原理的优秀解释,请参阅 Michael Dunn 的文章。
使用 CDialogResizeEx
要将此模板与现有的 CDialogResize 派生类一起使用,请执行以下步骤:
- 从
CDialogResizeEx
而不是CDialogResize
派生。 - 将
CHAIN_MSG_MAP
调用更改为使用CDialogResizeEx
。 - 在你的 WM_INITDIALOG 处理程序中,调用
DlgResize_InitEx
而不是DlgResize_Init
。 - 调用
LoadSize
方法以指定根注册表父项和键名,对话框大小将从该位置加载/保存。
例如,你的对话框类可能如下所示:
class CMyDialog : public CDialogImpl<CAnotherDialog>, public CDialogResizeEx<CAnotherDialog> { 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<CMyDialog>) 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。这允许你在应用程序中存储任意数量的对话框的大小。
请注意,如果你不想将这些值存储在注册表中,可以简单地在显示对话框之前设置 m_size
成员。当对话框关闭时,m_size
将包含新的对话框大小。例如:
CMyDialog dlg; dlg.m_size.cx = 640; dlg.m_size.cy = 480; dlg.DoModal();
CDialogResizeEx
这是类
#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); // Size the dialog and update the control layout 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()); } } // Load the dialog size from the registry. Base the registry // value on the dialog ID. void LoadSize(HKEY hKeyParent, LPCTSTR lpszKeyName) { m_hKeyParent = hKeyParent; m_lpszKeyName = lpszKeyName; ATL::CRegKey reg; if (reg.Open(hKeyParent, lpszKeyName, KEY_READ) == ERROR_SUCCESS) { // Format the value name using the dialog ID 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 } } // Save the dialog size to the registry. 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<const T*>(this); CString strValueName; strValueName.Format(_T("dialog_%d_cx"), pT->IDD); return strValueName; } CString FormatHeightValueName(void) const { const T* pT = static_cast<const T*>(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); // Save the window size 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; } };