
Introduction
Most common solution to organize a large amount of information in a dialog box is to use a property sheet with a set of property pages. However, this approach has several problems:
- It is not easy to add controls to the property sheet (outside of property pages).
- Things become fuzzy if some background process needs to change the currently active page.
The alternative solution is to use a stacked dialog with any number of stacked pages. Stacked dialog is a simple dialog that contains any programmer defined set of controls. One of these controls is designated as a placeholder control (usually a picture control). Stacked page is a child dialog with any number and type of controls. Stacked dialog will position and resize all stacked pages according to the position and size of a placeholder control on a stacked dialog. Only one stacked page may be visible and active at any moment of time. Active stacked page is selected programmatically -- this may be done either by clicking on a dialog control (select page from a list box) or based on some event / trigger from the application.
Using stacked dialog in your application, you will achieve the following:
- Combine one of stacked pages with other controls.
- Change active page either on user action or programmatically based on application's internal state.
- Simple class interface
Each TStackedPage
derived class may implement any of the following virtual functions:
OnCreatePage
called once after the page is created
OnDestroyPage
called once before the page is destroyed
OnSetActive
called once the page becomes active
OnKillActive
called once the page becomes inactive
TStackedDialog
derived class must provide an implementation of the virtual abstract function OnPageChanged()
. This is an ideal place to modify the appearance of the stacked dialog based on the deactivated/activated page.
Pictures from a demo application show a dialog box with 3 possibilities to select a page:
- from a listbox,
- from a combobox and
- clicking on a push-like radio button.
In the middle of the dialog are 2 pages: one with a calendar control and the other with a tree control.
Step 1:
Create a dialog. Place a picture control (placeholder) where you want to have stacked pages on your dialog. This control should be invisible and disabled. Also, place a control that will enable a user to choose the active page (for example, listbox or combobox).
Using class wizard, create a class for the new dialog. This class must be derived from TStackedDialog
. Since TStackedDialog
is an abstract class, add an implementation for the following TStackedDialog
abstract virtual methods:
TStackedPage *CreatePage(UINT nId)
void OnPageChanged(UINT nId, BOOL bActivated)
Abstract virtual function CreatePage()
is called to create a stacked page dialog based on its resource ID.
Step 2:
Create a dialog for each stacked page that you need. Each dialog should have the following properties:
- Child
- No border
- Not visible
- Disabled
Using class wizard, create a class for each stacked page. Each class must be derived from TStackedPage
.
Step 3:
Within OnInitDialog()
function of the stacked dialog class, add stacked pages to the stacked dialog.
...
AddPage(IDD_PAGE_1);
AddPage(IDD_PAGE_2);
...
Each AddPage()
will execute the abstract virtual function of the base class (implemented in derived class) CreatePage()
that should have the following implementation:
TStackedPage *CreatePage(UINT nId)
{
switch (nId) {
case IDD_PAGE_1: return new CPageOneDialog;
case IDD_PAGE_2: return new CPageTwoDialog;
}
return NULL;
}
Step 4:
After adding all the pages to the stacked dialog, activate the initial page with the following line:
SetPage(IDD_PAGE_1);
Any previously activated page will be first deactivated. Use the same method to activate the page, as a response to a user action or based on internal application state.
SetPage()
function will call an abstract virtual function TStackedDialog::OnPageChanged()
implemented in the derived class. This is the best place to update the stacked dialog based on the currently active page.
Known problems
Manual movement through dialog controls (using Tab/Shift-Tab) is not working properly. I have not actually had the time to work on it. Anybody interested ...
Latest version may be downloaded here. Any comments or suggestions regarding the known problem are welcomed.