Introduction
Since I once created an re-sizable property sheet implementation in plain C, I decided also to do so in WTL. My goal
during implementation was to stay as close as possible on WTL original source.
This leads to an implementation which could 1 by 1 replaced by conventional source.
Features
- Resizable Property Sheet window class
- Resizable Property Sheet Page class (see
CDialogResize
for more information about usage)
- Double buffered redraw is possible using
WS_EX_COMPOSITED
(Sheet window only)
CDialogResize
extension called CDialogResizeDynamic
to support runtime resize map manipulation
Background
Since the property sheet class implements Wizard (97) style dialogs and default property sheets, and since I want to derive my new class from CDialogResize
, I was forced to create a WTL modifications.
Instead of using static GetDlgResizeMap()
I decided to use a dynamic Implementation to support runtime resize manipulation
. I derived a new class from CDialogResize
and added methods for adding and removing resize map entries.
BEGIN_DLGRESIZE_MAP_EX(CResizablePropertySheetImpl)
DLGRESIZE_CONTROL_EX(ID_PSHEET_OK, DLSZ_MOVE_X | DLSZ_MOVE_Y)
DLGRESIZE_CONTROL_EX(ID_PSHEET_APPLY, DLSZ_MOVE_X | DLSZ_MOVE_Y)
DLGRESIZE_CONTROL_EX(ID_PSHEET_CANCEL, DLSZ_MOVE_X | DLSZ_MOVE_Y)
DLGRESIZE_CONTROL_EX(ID_PSHEET_HELP, DLSZ_MOVE_X | DLSZ_MOVE_Y)
DLGRESIZE_CONTROL_EX(ID_PSHEET_TAB, DLSZ_SIZE_X | DLSZ_SIZE_Y)
END_DLGRESIZE_MAP_EX()
Above declaration will be evaluated as
void StaticResizeMap() {
InitialMap.Add(ID_PSHEET_OK, DLSZ_MOVE_X | DLSZ_MOVE_Y);
...
InitialMap.Add(ID_PSHEET_TAB, DLSZ_SIZE_X | DLSZ_SIZE_Y);
InitialMap.Add(-1, 0);
}
Please note, the use of the old BEGIN_DLGRESIZE_MAP
has no effect and will be ignored. StaticResizeMap
method will be called within CDialogResizeDynamic
constructor.
Using the code
There is not much need of code modification on your existing source code. You have to replace CPropertySheetImpl
with CResizablePropertySheetImpl
class CMyPropertySheet :
public CResizablePropertySheetImpl<CMyPropertySheet> {
public:
CMyPropertySheet(ATL::_U_STRINGorID title = (LPCTSTR) NULL,
UINT uStartPage = 0, HWND hWndParent = NULL,
bool EnableDoubleBuffering = false, bool IsWizard = false)
: CResizablePropertySheetImpl<CMyPropertySheet>(title,
uStartPage, hWndParent, EnableDoubleBuffering, IsWizard) {
}
...
As you may note constructor is extended by two additional parameters. EnableDoubleBuffering
will enable double buffering (no flickering) as the name implies.
IsWizard
will create an wizard style property sheet. However, you should use double buffering with care because it may slow down rendering and may cause unpredictable behaviour in some circumstances.
class CMyResizablePropertyPage :
public CResizablePropertyPageImpl<CMyResizablePropertyPage> {
public:
enum { IDD = IDD_0 };
CMyResizablePropertyPage(ATL::_U_STRINGorID title = (LPCTSTR) NULL,
bool IsExterior = false) :
CResizablePropertyPageImpl<CMyResizablePropertyPage>(title,
IsExterior) {
}
...
As you may note, I extended property page constructor. If IsExterior
is true, an exterior page will be created i.e. that page that usually is used for welcome and completion page.
To add, remove or change resize map items at runtime you may use one of the new CDialogResizeDynamic
methods:
void AddToResizeMap(int ControlId, DWORD ResizeFlags);
void RemoveFromResizeMap(int ControlId);
void ChangeResizeMapEntry(int ControlId, DWORD ResizeFlags);
Adding new resize map groups after DlgResize_Init
is called is currently not possible.
History
- 2007/03/07: Added some extensions, resize map is dynamic now.
- 2004/02/24: Initial release