Introduction & Disclaimer
Property Sheet Wizards can be a rather daunting task for the beginning
programmer. Their simple looking surface appearance hides a number of
complexities that make it difficult to understand exactly how they function
internally. This article will attempt to make it a little bit easier for
beginners to understand the basic functioning of a property sheet wizard. For
all those that choose to read this article, I make absolutely no claim of 100%
accuracy of the contents of this article and encourage CONSTRUCTIVE CRITICISM
with regards to it's contents. You can learn a lot more from a kind word than you
can from a flame :-)
Setting Up The Project
The first step in setting up a property sheet wizard is configuring the
project itself. For purposes of this article we will be working in Microsoft
Visual Studio 6 to construct our property sheet wizard, however I'm reasonably
certain that it is small work to port this code to other compiler environments.
First, we need to create the base Dialog. I did this using the MFC AppWizard.
These are the steps I used:
- Go to File >> New
- Select MFC AppWizard (EXE)
- Enter SimpleWizard as the project name -- You can use any name
but I selected this for simplicity
- Click the OK Button
The above steps inform Visual Studio that we want to create a MFC application
with the name SimpleWizard. On the screen we are presented with
next, we will configure the project so that it will work in a manner consistent
with wizard applications. Now we need to further configure the project.
- Select the Dialog Based radio button.
You should see the representation of our application change to appear as a
dialog box on the left hand side of the setup window. This shows us that our
application will be configured as a dialog application. You should leave the
resource language option on the default unless you have a compelling need to
change it, as most applications I've ever encountered use the english language
resources.
All items in this dialog should be left on their default settings with the
exception of Active X Control Support and support for
Windows Sockets unless you have specific reasons to need this type
of functionality in your wizard applications.
Again, I suggest leaving all settings on the default as there is nothing in
these settings that is terribly useful to use with the exception of how the MFC
Dll will be linked. If you choose Shared Dll you will get a
smaller executable, however, there are some cases where we are not certain that
the target machine has the MFC DLL installed, so it may be useful to
Static Link the application against the MFC and import the
functions we need. Please be aware that this will greatly increase the size of
your executable so, I strongly recommend against it.
The only setting that we can change here is the Class Name but
we have no useful reason to do that, so let's just finish this up by clicking
the FINISH Button
Inserting the Property Wizard Component
Now we have created a MFC Application based on a Dialog with some default
setting which will allow us to implement a Wizard. All in all this is a fairly
simple setup, but now we get to get into the fun part. Let's continue.
- Go to Projects >> Add to Project >> Components &
Controls
- Select the Directory Visual C++ Components
- Select the Property Sheet Component
- Click the Insert Button
This will bring up the configuration parameters for actually inserting the
property sheet into our dialog application. It is important that we do this
correctly, otherwise the property sheet will not be accessible to the correct
classes and we will have to go back and fix it. Better to do it right the first
time. Let's continue.
- Select the Wizard Radio button
- Click the NEXT button
On the next screen, we have the option for adding preview support to the
wizard classes which will allow our wizard to display feedback based on the
options that a user chooses. If this were a more complex wizard, we might be
interested in using this, but for our purposes., we are going to remain simple,
so leave this unchecked.
Now we are asked what class we would like to give access to our wizard pages.
We could give access to the dialog class which displays our initial dialog box
or we coudl give it to the base application class. If we give access to the
dialog box class, we have to wire up some mechanism which triggers the wizard to
appear. If we give access to teh base application class we can bypass the dialog
completely by changing a little bit of code. In this case, let's give the base
application access to it. I'll show some code to actually display the property
wizard in a little bit.
- Select the CSimpleWizardApp class from the dropdown box
- Click the NEXT button
On the next screen we can set the number of pages that will exist in our
wizard. For purposes of our wizard, we wil use four pages, so go ahead and set
that to 4 and click NEXT
On the next screen we are given the option to change the names of the classes
that will be inserted into our application. For example if we wanted to have
pages for detecting hardware, displaying what we found, changing configuration
settings, and finalizing our settings, we coudl change the class names to
reflect each respective page of the wizard. For now, we can just leave those on
the defaults. So let's just click FINISH.
There we have it, our property wizard is now inserted. One major issue
remains. How do we actually get our wizard to show up?
Wizard, Show Thyself...
Now that we have everything setup, we need to make the wizard visible. We do
this by making some alterations to the bass dialog class. Here how we do it.
Open up the the ClassView and find the class named
CSimpleWizardApp
. What we are looking for here is the
InitInstance
method of the class which looks like this:
BOOL CSimpleWizardApp::InitInstance()
{
AfxEnableControlContainer();
#ifdef _AFXDLL
Enable3dControls();
#else
Enable3dControlsStatic();
#endif
CSimpleWizardDlg dlg;
m_pMainWnd = &dlg;
int nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
}
else if (nResponse == IDCANCEL)
{
}
return FALSE;
}
In order to make our dialog appear, we need to substitute the
<CODE>DoModal()
call that the default dialog is created by, with a call
into our wizard classes, so we need to change the above code to this:
BOOL CSimpleWizardApp::InitInstance()
{
AfxEnableControlContainer();
#ifdef _AFXDLL
Enable3dControls();
#else
Enable3dControlsStatic();
#endif
CMyPropertySheet propSheet;
m_pMainWnd = &propSheet;
propSheet.DoModal();
return FALSE;
}
This simply tells the application to call DoModal()
on th
ewizard class instead of calling it on the base dialog resource. That should be
enough to get you started on creating Wizard aplications. Granted this is not a
complete solution to creating a a proper Wizard, but there are more than enough
resources out there on CodeProject and other sites that can discuss setting up
wizard buttons and other intricacies. My aim with this article was to show you
how to get the wizard to show up in your applications.
I have additionally removed the OnWizard()
function that was
inserted with the insertion of the wizard classes, since it becomes virtually
useless after this modification. Hope this article helps.