Using Multiple Inheritance to Enhance DDX

Environment: VC5 SP3

Overview

This article presents a technique of using one operation to set or retrieve all CDialog DDX data members. Unfortunately, this technique does this at the expense of limiting MFC Class Wizard’s ability to maintain the dialog’s DDX data members.

Background

MFC Dialog Data Exchange (DDX) makes it easier to exchange data between CDialog data members and dialog box controls. MFC Applications often use dialog boxes to obtain and store user input using code similar to the following:

  // Construct the dialog
CDerivedDlg dlg(AfxGetMainWnd());

// Set the dialog’s data members
dlg.m_fCheck = m_fCheck;
dlg.m_nRadio = m_nRadio;
// …

// Call DoModal()
if (dlg.DoModal() == IDOK)
{
// Get the dialog’s data members
m_fCheck = dlg.m_fCheck;
m_nRadio = dlg.m_nRadio;
// …
}

Using multiple inheritance the individual member assignments may be replaced with two statements:

  // Construct the dialog
CDerivedDlg dlg(AfxGetMainWnd());

// Set the dialog’s data members
static_cast<CDialogData &>(dlg) = m_dlgdata;

// Call DoModal()
if (dlg.DoModal() == IDOK)
{
// Get the dialog’s data members
m_dlgdata = dlg;
}

Design

When MFC Class Wizard is used to create DDX member variables, it makes them members of the derived CDialog. The technique presented here moves all of the dialog’s DDX data members variables into their own class (e.g. CDialogData) and the dialog is then modified to also inherit from CDialogData. For example the following CDerivedDlg:

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

// Dialog Data
//{{AFX_DATA(CDerivedDlg)
enum { IDD = IDD_DERIVED };
int m_nRadio;
BOOL m_fCheck;
CString m_strCombo;
CString m_strEdit;
CString m_strStatic;
//}}AFX_DATA

};

Becomes:

class CDialogData
{
public:
int m_nRadio;
BOOL m_fCheck;
CString m_strCombo;
CString m_strEdit;
CString m_strStatic;
};

class CDerivedDlg : public CDialog, public CDialogData
{
// Construction
public:
CDerivedDlg(CWnd* pParent = NULL); // standard constructor

// Dialog Data
//{{AFX_DATA(CDerivedDlg)

enum { IDD = IDD_DERIVED };
//}}AFX_DATA

};

Implementation

The included demo project (see picture above) has a dialog box resource i.e. IDD_OPTIONS used to implement both approaches to DDX. The project’s CTraditionalOptionsDlg class uses IDD_OPTIONS to implement the traditional approach to DDX, and the project’s CAlternativeOptionsDlg class uses IDD_OPTIONS to implement this alternative approach.

After using Class Wizard to created CAlternativeOptionsDlg, it was modified using the following steps:

  • A new class named COptions was created and CAlternativeOptionsDlg was modified to publicly derive from COptions (as well as CDialog)
  • All DDX members were moved from the AFX_DATA() section in CAlternativeOptionsDlg’s declaration to COptions’ declaration and declared public (or protected if accessor methods are used)
  • All DDX members initializations were removed from the AFX_DATA_INIT() section in CAlternativeOptionsDlg’s constructor and placed in COptions’ default constructor.
  • All DDX_*() and DDV_*() methods were moved outside of the AFX_DATA_MAP() section in CAlternativeOptionsDlg::DoDataExchange()

These modifications (especially the last step) prevent MFC Class Wizard from being used to maintain the DDX data members. This is disappointing, but can be dealt with some what by leaving the DDX data members commented out in CAlternativeOptionsDlg’s source files and moving them back into the appropriate AFX_DATA_*() section as necessary (the demo project does this).

Demo Application

The included demo application (shown in the picture above) is a CDialog based app with a menu bar. The Options Menu has two submenus, Alternative… and Traditional… which are used to demonstrate the traditional method of DDX and the alternative method presented here. Both display the same dialog (IDD_OPTIONS) which contains several different types of controls. If the user presses the OK button the application stores the dialogs data members.

Downloads

Download demo project – 22 KB

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read