在许多项目中,经常需要实现一个可以调整大小的对话框。WTL提供了一个优秀的模板类CDialogResize
要使用这个模板类与现有的CDialogResize派生类,可以按照以下步骤进行:
例如,可能有一个对话框类如下所示:
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();
这就是全部内容,实现起来应该只需要几分钟。
该类将使用以下值名将对话框大小保存到注册表中:
其中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;
}
};