Click here to Skip to main content
14,970,019 members
Articles / Desktop Programming / MFC
Posted 23 May 2000


74 bookmarked

Windows 2000 Style Wizards

Rate me:
Please Sign up or sign in to vote.
4.88/5 (18 votes)
23 May 2000
Create Windows 2000 style Wizards with white backgrounds
  • Download demo project - 107 Kb
  • Download source files - 7 Kb
  • Sample Image

    A Page from the Windows 2000 Style Wizard


    There are two main differences between the traditional MFC-CPropertySheet wizards and the Windows 2000 wizards:

    1. The Windows 2000 wizard has a white background.
    2. The "page" portion of the Windows 2000 wizard extends all the way to the edge of the dialog.
    The Microsoft GUI designers are fickle. I remember developing for Windows 3.1 and going through a lot of trouble to make grey dialog backgrounds instead of white backgrounds. Now we go through a lot of trouble to make white backgrounds instead of grey ones.

    This article presents two classes that allows you to create Windows 2000 style wizards relatively easily. Both classes are actually derived from CDialog, rather than CPropertySheet or CPropertyPage. The classes make use of some techniques presented in Zoran M.Todorovic's CodeProject article on stacked dialog boxes, however there are extensive code changes from Zoran's work.

    Another big advantage of this method of creating wizards is that you have total control over the placement and text of the wizard buttons, and you can even add other control outside of the wizard pages.

    The Classes

    The CNewWizDialog Class

    CNewWizDialog is derived from CDialog, but it is analagous to CPropertySheet when creating a standard MFC wizard. You create a dialog template with Back, Next, Cancel, and Finish buttons. You create a CNewWizDialog-derived class for your dialog resource.

    The CNewWizPage Class

    CNewWizPage is also derived from CDialog, however it is analagous to CPropertyPage when creating a standard MFC wizard. You create a dialog resource for each page of the wizard. You create a CNewWizPage-derived class for each wizard page.

    CNewWizDialog and CNewWizPage have very similar class interfaces to CPropertySheet and CPropertyPage respectively, so it should not be too difficult to convert your existing wizards to windows 2000 style wizards.

    Creating the Main Dialog

    1. In the Visual C++ resource editor, create a dialog template for the main wizard window. Be sure to give it Next, Back, Finish, and Cancel buttons. Buttons should have the following identifiers to match the standard MFC wizard:

    Cancel -- IDCANCEL
    Finish -- ID_WIZFINISH
    Back -- ID_WIZBACK
    Next -- ID_WIZNEXT

    Placing the Cancel and Finish Buttons

    In the traditional MFC wizards, The Finish button and the Cancel button are in the same position. One is hidden when the other is shown. If you want to mimic that behavior in these classes, it is simple enough, but you will have to make changes to the CNewWizDialog::EnableFinish(BOOL bEnable) function to show are hide the proper buttons.

    The Wizard Page Placeholder Control

    You will also need to give your main wizard dialog a frame rectangle (picture) control to act as a placeholder. If you make the frame "etched", you will get a nicer appearance. Your dialog should look something like the one below.

    Sample Image

    2. Using ClassWizard, create a CDialog-derived class for your dialog resource. Change the base class from CDialog to CNewWizDialog. It is very important that you also change your message map to call the base class CNewWizDialog instead of CDialog as shown below. Otherwise, your wizards buttons will not work!

    BEGIN_MESSAGE_MAP(CMasterDlg, CNewWizDialog)

    3. Override WM_INITDIALOG. Before calling the base class implementation of OnInitDialog, you must call CNewWizDialog::SetPlaceholderID() passing the control ID of the place holder rectangle as a parameter.

    Be sure to call the base class implementation CNewWizDialog::OnInitDialog and not CDialog::OnInitDialog as show below:

    BOOL CMasterDlg::OnInitDialog() 
    	// you must call this function in OnInitDialog before you call the base class!
    	// make sure to call the proper base class
    	return TRUE;  // return TRUE unless you set the focus to a control
    	              // EXCEPTION: OCX Property Pages should return FALSE

    Creating the Wizard Pages

    Follow the these steps for each page in your wizard.

    1. Create a dialog resource for the page. The dialog should have the following properties:

    • Child Style
    • No Border
    • Not Visible
    • Disabled
    Place the desired contols on the dialog.

    Note: You should make each wizard page the same size as the placeholder on your main wizard dialog.

    2. Use ClassWizard to create a CDialog-derived class for the dialog resource. Add any handlers for controls that you may require.

    3. Change the base class from CDialog to CNewWizPage. It is very important that you change the base classes for OnInitDialog, the constructor, and the message map.

    BEGIN_MESSAGE_MAP(CSetupPage, CNewWizPage)
    4. Override any of the following functions to add functionality and data validation to your wizard page:
    // these functions behave the same as CPropertyPage
    virtual void CNewWizPage::OnCancel();
    virtual BOOL CNewWizPage::OnKillActive();
    virtual void CNewWizPage::OnSetActive();
    virtual BOOL CNewWizPage::OnQueryCancel( );
    virtual LRESULT CNewWizPage::OnWizardBack();
    virtual LRESULT CNewWizPage::OnWizardNext();
    virtual BOOL CNewWizPage::OnWizardFinish();

    Putting it All Together

    Once you have created all of your dialog classes as described above, you put the wizard together just as you would with a standard MFC CPropertySheet-based wizard. The only difference is that you must pass the ID of each pages's dialog resource to CNewWizDialog::AddPage().
    CMasterDlg Dlg(this);
    CSetupPage SetupPage;
    CHardwarePage HardwarePage;
    CPrinterPage PrinterPage;
    Dlg.AddPage(&HardwarePage, CHardwarePage::IDD);
    Dlg.AddPage(&SetupPage, CSetupPage::IDD);
    Dlg.AddPage(&PrinterPage, CPrinterPage::IDD);
    if (Dlg.DoModal() == ID_WIZFINISH)
    	AfxMessageBox("Finished Wizard");
    	AfxMessageBox("Cancelled Wizard");

    Implementing the White Background

    One of the new features in the Windows 2000 style wizards is a white background. This is pretty easy to implement, and it is also easy to disable if you do not like it.

    1. In the declaration for CNewWizPage, we give the page it's own brush.

    class CNewWizPage : public CDialog
    	CBrush m_Brush;
    2. Override WM_INITDIALOG and create a white brush.
    BOOL CNewWizPage::OnInitDialog() 
    	// create the white brush for the background
    	m_Brush.CreateSolidBrush(RGB(255, 255, 255));
    	return TRUE;  // return TRUE unless you set the focus to a control
    	              // EXCEPTION: OCX Property Pages should return FALSE

    3. Override the WM_CTLCOLOR message, and return the white brush and set text background colors as appropriate.

    HBRUSH CNewWizPage::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 
    	HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
    	switch (nCtlColor)
    			pDC->SetTextColor(RGB(0, 0, 0));
    		case CTLCOLOR_EDIT:
    			pDC->SetTextColor(RGB(0, 0, 0));
    			pDC->SetTextColor(RGB(0, 0, 0));
    			pDC->SetTextColor(RGB(0, 0, 0));
    		case CTLCOLOR_BTN:
    			pDC->SetTextColor(RGB(0, 0, 0));
    		case CTLCOLOR_DLG:	    
    			return m_Brush;
    	// TODO: Return a different brush if the default is not desired
    	return m_Brush;

    Potential Problems

    Many of the data validation functions for CNewWizPage return FALSE if the dialog data is not validated as desired. I did not spend a lot of time checking to make sure the classes worked as required when FALSE is returned from these functions. If you are doing a lot of data validation, be sure to test your wizard with invalid data so that it behaves as desired.


    This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

    A list of licenses authors might use can be found here


    About the Author

    Robert Pittenger, MCPD-EAD
    President Starpoint Software Inc.
    United States United States
    Bob Pittenger is founder and President of Starpoint Software Inc. He holds a B.A. degree from Miami University, M.S. and Ph.D. degrees from Purdue University, and an MBA from Xavier University. He has been programming since 1993, starting with Windows application development in C++/MFC and moving to C# and .NET around 2005 and is a .NET Microsoft Certified Professional Developer.

    Bob is the author of two books:
    Billionaire: How the Ultra-Rich Built Their Fortunes Through Good and Evil and What You Can Learn from Them
    Wealthonomics: The Most Important Economic and Financial Concepts that Can Make You Rich Fast.
    Visit for more information.

    Comments and Discussions

    GeneralMy vote of 5 Pin
    Richchu10-Mar-13 21:41
    MemberRichchu10-Mar-13 21:41 
    GeneralMy vote of 5 Pin
    bondukanthikiran22-Jul-10 20:32
    Memberbondukanthikiran22-Jul-10 20:32 
    GeneralPlease Help Me !! Pin
    Le@rner27-Nov-08 0:47
    MemberLe@rner27-Nov-08 0:47 
    GeneralHelp me in design Windows Explorer in VC++ Pin
    Van Phuong Nguyen16-May-07 0:56
    MemberVan Phuong Nguyen16-May-07 0:56 
    GeneralMemory Assertion Pin
    Aarif Mohammad23-Apr-06 23:46
    MemberAarif Mohammad23-Apr-06 23:46 
    GeneralWindows 200 style already supported! Pin
    Mark Werner18-Apr-05 8:50
    MemberMark Werner18-Apr-05 8:50 
    GeneralRe: Windows 200 style already supported! Pin
    Mark Werner18-Apr-05 9:03
    MemberMark Werner18-Apr-05 9:03 
    QuestionHow do I change the master caption? Pin
    bearded17-Dec-04 4:29
    Memberbearded17-Dec-04 4:29 
    Generalpassing data Pin
    Wendy Moore17-Oct-04 2:35
    MemberWendy Moore17-Oct-04 2:35 
    GeneralRe: passing data Pin
    #realJSOP15-Nov-04 4:21
    mva#realJSOP15-Nov-04 4:21 
    Generaldynamic combobox in a OCX Pin
    edgar32528-Apr-04 21:41
    Memberedgar32528-Apr-04 21:41 
    GeneralSimple Querry Pin
    spidey82023-Feb-04 3:43
    Memberspidey82023-Feb-04 3:43 
    GeneralRe: Simple Querry Pin
    antadam25-Feb-04 11:03
    Memberantadam25-Feb-04 11:03 
    QuestionHow do you automatically advance to the next page Pin
    v1ncent30-Jan-04 4:09
    Memberv1ncent30-Jan-04 4:09 
    AnswerRe: How do you automatically advance to the next page Pin
    v1ncent30-Jan-04 10:12
    Memberv1ncent30-Jan-04 10:12 
    QuestionHow do I skip few pages ? Pin
    Dillip Kumar Kara8-Jan-04 15:24
    MemberDillip Kumar Kara8-Jan-04 15:24 
    AnswerRe: How do I skip few pages ? Pin
    v1ncent27-Jan-04 8:35
    Memberv1ncent27-Jan-04 8:35 
    General"Do not show this screen in future" Pin
    NotProfessional22-Dec-03 10:32
    MemberNotProfessional22-Dec-03 10:32 
    GeneralBlank screen Pin
    Mr. J.3-Dec-03 22:15
    MemberMr. J.3-Dec-03 22:15 
    GeneralRe: Blank screen Pin
    v1ncent30-Jan-04 4:11
    Memberv1ncent30-Jan-04 4:11 
    GeneralRe: Blank screen Pin
    Mr. J.30-Jan-04 5:45
    MemberMr. J.30-Jan-04 5:45 
    GeneralRe: Blank screen Pin
    v1ncent30-Jan-04 10:01
    Memberv1ncent30-Jan-04 10:01 
    Questioncan't disable Finish button? Pin
    michael thomas31-Aug-03 13:25
    Membermichael thomas31-Aug-03 13:25 
    AnswerRe: can't disable Finish button? Pin
    michael thomas31-Aug-03 13:33
    Membermichael thomas31-Aug-03 13:33 
    QuestionModeless Wizard? Pin
    Lindenbluete5-Jul-02 23:13
    MemberLindenbluete5-Jul-02 23:13 

    General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

    Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.