WynApse Home Page
Home    Blog    Contact       
Latest Article:
Read my CoDe Magazine Article
My Tags:
Hosted by:


3 Months FREE!

Ask me how to get 6 months free.


Lifetime Member:


web tracker

Over 3200671 Pages Served


Custom MFC Base Classes in C++


Go to Page 1   Go to Page 3

The Example

As a demonstration, I built a new dialog-based project in Visual Studio 6.0 taking all the defaults. The only change I made was to add a button to the main dialog to launch the about box. This was done by placing a button on the dialog in the resource view then double-clicking the new button to add and edit the button handler code.

The code simply launches the about box that Visual Studio added:

CAboutDlg dlg;
dlg.DoModal();

Now rebuild and run the application to make sure that the about box appears when the button is pressed.

Our project now has two dialog resources to keep in sync. I'm going to demonstrate putting a bitmap in the background of a dialog, not because it's clever or new because there are plenty of resources available to show that, but because after some setup, I'm going to add it once and it appear in both our dialogs.

Building our Base Class

From the menu, select Insert->New Class. I used "CustomDialog" as the name, and selected CDialog as the base class. Take all the defaults and press OK. Visual Studio will now give you a warning that you have no resource for this class, because it is smart enough to realize that you are building a CDialog-based class. Select Yes here. If you try to rebuild at this point, you will receive an error message because of an undefined ID “_UNKNOWN_RESOURCE_ID_” in the AFX_DATA section of CustomDialog.h. This is correct so far.

Now we modify our CustomDialog.h file as follows. Change the constructor:

Change:

CCustomDialog(CWnd* pParent = NULL);

To:

CCustomDialog(UINT IDD, CWnd* pParent = NULL);

This is because we are going to pass in the IDD to our parent, and we keep the defaulted pParent variable to the right of our UINT. Remove the enum line from the AFX_DATA section. Each CCustomDialog-based class will have its own enum, and pass that value in as the IDD in the constructor. For now, that is enough for the include file. Now we modify the CustomDialog.cpp file as follows. Modify the constructor:

Change:

CCustomDialog::CCustomDialog(CWnd* pParent /*=NULL*/)
   : CDialog(CCustomDialog::IDD, pParent)

To:

CCustomDialog::CCustomDialog(UINT IDD, CWnd* pParent /*=NULL*/)
   : CDialog(IDD, pParent)

This passes the IDD that our new class was instantiated with to the CDialog base class in the same manner that it receives the member enum IDD. Rebuild at this point to ensure a clean compile, and no changes in the manner of execution.


Wiring our class into the project files

This is the most painful part of the process, and the reason for doing this when you first begin. If you are many dialog resources into the project, this next step is what will probably keep you from doing this.

We need to insert our new class between our application and the CDialog class that is now being used. Modify Customizing MFCBaseClassesDlg.h by including our new dialog class in the constructor, and changing the constructor to inherit from our new class:

// CCustomizingMFCBaseClassesDlg dialog
#include "CustomDialog.h"

class CCustomizingMFCBaseClassesDlg : public CCustomDialog
{
// Construction
public:
CCustomizingMFCBaseClassesDlg(CWnd* pParent = NULL);  // standard constructor


Next modify the CCustomizingMFCBaseClassesDlg.cpp file as follows:

class CAboutDlg : public CCustomDialog
...
CAboutDlg::CAboutDlg() : CCustomDialog(CAboutDlg::IDD)
...
BEGIN_MESSAGE_MAP(CAboutDlg, CCustomDialog)
...
CCustomizingMFCBaseClassesDlg::CCustomizingMFCBaseClassesDlg(CWnd* pParent /*=NULL*/)
   : CCustomDialog(CCustomizingMFCBaseClassesDlg::IDD, pParent)

and finally the message map for the dialog class:

BEGIN_MESSAGE_MAP(CCustomizingMFCBaseClassesDlg, CCustomDialog)

That is all that is necessary to base our dialogs on our new class. Build and run to ensure completeness at this point. Hopefully the application will run as it did before with no visible changes... that's a good thing, it means the base class is working!

Go to Page 1   Go to Page 3


RSS:  rss URL

Microsoft MVP

Member of WPF and Silverlight Insiders

Creative Commons License
Check out our book:
Our Book
Advertise on this site through Lake Quincy Media
Copyright © 2006-2010, WynApse