Windows Vista for Developers – Part 1 – Aero Wizards
Aero wizards represent the evolution of the wizard interface first popularized by the Windows 95 family of operating systems. They provide a fresh new look to the common wizard interface and are designed to provide a more focused experience for users. In this first part of the Windows Vista for Developers series, I will show you how you can take a simple wizard and turn it into an Aero wizard with a minimal amount of code.
Property Sheets
To recap, wizards are just a variation of property sheets defined by the PROPSHEETHEADER structure and implemented by the PropertySheet function. ATL provides the CPropertySheetImpl class template to generate much of the code involved with using the PropertySheet function. Let us start with a simple property sheet and see how it evolves into an Aero wizard:
class SampleWizard :
public CPropertySheetImpl<SampleWizard>
{
public:
BEGIN_MSG_MAP(SampleWizard)
CHAIN_MSG_MAP(__super)
END_MSG_MAP()
SampleWizard() :
CPropertySheetImpl<SampleWizard>(IDS_TITLE)
{
VERIFY(AddPage(m_page));
}
private:
SamplePage m_page;
};
The SampleWizard class derives from the aforementioned CPropertySheetImpl class template that provides most of the functionality. A message map simply directs messages to the base class. The constructor calls the base class’ constructor to set the wizard’s title and adds a single page to the wizard using the AddPage method inherited from CPropertySheetImpl. The SamplePage class is defined as follows:
class SamplePage :
public CPropertyPageImpl<SamplePage>
{
public:
BEGIN_MSG_MAP(SamplePage)
CHAIN_MSG_MAP(__super)
END_MSG_MAP()
enum { IDD = IDD_SAMPLE_PAGE };
};
The SamplePage class derives from the CPropertyPageImpl class template providing most of the functionality for a property page. It too has a simple message map directing messages to the base class. An enum defines the IDD constant expected by the base class to identify the dialog resource used for the property page.
At this point, you can create and display a modal property sheet with the following simple code:
SampleWizard sampleWizard;
sampleWizard.DoModal();
The first line creates the SampleWizard object and the various base classes, among other things, take care of populating the structures necessary to call the PropertySheet function. The DoModal method that SampleWizard inherits from the CPropertySheetImpl class template takes care of calling the PropertySheet function. The result is a simple property sheet:
Classic Wizards
To turn the property sheet into a classic wizard all you need to do is add the following statement to the SampleWizard constructor:
m_psh.dwFlags |= PSH_WIZARD97;
What this does is combine the PSH_WIZARD97 flag with the flags already set in the PROPSHEETHEADER structure. Since wizards provide an additional heading area, you should also update the SamplePage class to specify the header text for the page:
class SamplePage :
public CPropertyPageImpl<SamplePage>
{
public:
BEGIN_MSG_MAP(SamplePage)
CHAIN_MSG_MAP(__super)
END_MSG_MAP()
enum { IDD = IDD_BLANK_PAGE };
SamplePage()
{
VERIFY(m_title.LoadString(IDS_PAGE_TITLE));
SetHeaderTitle(m_title);
}
private:
CString m_title;
};
The SamplePage constructor uses the SetHeaderTitle method inherited from CPropertyPageImpl to set the header title for the page. Keep in mind that a pointer to the string is stored in the page’s PROPSHEETPAGE structure so the string’s lifetime must extend beyond the constructor.
With those small changes in place, the results are quite dramatically different:
As you might notice, the text that previously appeared on the tab has replaced the window title.
Aero Wizards
Now replace PSH_WIZARD97 in the SampleWizard constructor with PSH_AEROWIZARD and you finally have the new Aero wizard interface:
You should notice that the window title is back and the dialog caption, originally appearing on the property sheet tab, is no longer in use.
New Messages
Aero wizards support a few new messages that provide greater control over the standard controls provided by the wizard.
The PSM_SHOWWIZBUTTONS message shows or hides any of the standard buttons adorning a wizard. The PropSheet_ShowWizButtons macro simplifies posting this message. Using it is not especially intuitive but once you get the hang of it, you should not have any problems. Although just a macro, it is useful to imagine that it’s a function defined as follows (the macro is misleading):
void PropSheet_ShowWizButtons(HWND handle,
DWORD buttons,
DWORD mask);
The handle parameter identifies the wizard window, the buttons parameter indicates which buttons to show and the mask parameter indicates which buttons to operate on. If a button flag appears in both the buttons and masks parameters then it is shown. If a button flag appears only in the mask parameter then it is hidden. The following button flags are available:
PSWIZB_BACK
PSWIZB_NEXT
PSWIZB_FINISH
PSWIZB_CANCEL
For example, the following call will show the Next button and hide the Back button:
PropSheet_ShowWizButtons(handle,
PSWIZB_NEXT,
PSWIZB_BACK | PSWIZB_NEXT);
The PSM_ENABLEWIZBUTTONS message enables or disables any of the standard buttons. The PropSheet_EnableWizButtons macro simplifies posting this message:
void PropSheet_EnableWizButtons(HWND handle,
DWORD buttons,
DWORD mask);
This message works in the same was as PSM_SHOWWIZBUTTONS in terms of how buttons are identified. The buttons parameter indicates which buttons to enable or disable and the mask parameter indicates which buttons to operate on. For example, the following call will enable the Next button and disable the Back button.
PropSheet_EnableWizButtons(handle,
PSWIZB_NEXT,
PSWIZB_BACK | PSWIZB_NEXT);
The PSM_SETBUTTONTEXT message modifies the text for the Next, Finish and Cancel buttons. The PropSheet_SetButtonText macro simplifies sending this message:
void PropSheet_SetButtonText(HWND handle,
DWORD button,
PCWSTR text);
Sample
To allow you to easily experiment with the various options provided by Aero wizards, I created a sample wizard project that you can download and experiment with:
Read part 2 now: Task Dialogs in Depth
© 2006 Kenny Kerr