Dialog Data Exchange

MFC application utilizes dialog and forms to display data information and also the dialog is the interface to collect the input data from users. The display of data can use static and edit boxes and other UI elements. Now you might want to display an output variable to the UI element to show the data to the user or you might require to take input in the UI and save it to the member variable. This process of inter exchanging values between variables and user interfaces is called dialog data exchange in MFC framework. Dialog data exchange can happen from variable to user interface or vice versa.

CDataExchange class

CDataexchange is a class mostly used in data exchange routines. This holds member variables and routines to utilize in the exchange process. The two most important member variables are m_bSaveAndValidate and m_pDlgWnd. The window handle of the dialog is pointed by m_pDlgWnd and it is set during the construction time. The member variable m_bSaveAndValidate tells the direction of the exchange flow. The true value indicates that the data from the user interface should be saved in the member variable. The false value of m_bSaveAndValidate says the value of the member variable should be pushed to the user interface. Know more: CDataExchange class : Explains details of the CDataExchange


CDialog has a virtual function named as DoDataExchange() to do the exchange between the variables and the user interface elements.

virtual void DoDataExchange(CDataExchange* pDX);

Win32 application APIs uses GetDlgItemXXX and SetDlgItemXXX APIs to get the values from user interface and to set the values to user interface. However these APIs are used only for Win32 C programs and not used in MFC. MFC framework uses data exchange macros to easily do this step is minimal source code.

MFC uses DDX_XXXX macros in the exchange routine and the DDX stands for Dialog Data Exchange (DDX). These macros have an uniform argument layout. The first argument is the CDataExchange pointer variable (pDX), the second argument is the identity integer of the dialog control and third argument is the member variable of the dialog class. Know more: DoDataExchange Dialog Data Exchange : Explains DoDataExchange in details. It tells more about how data exchange macros and win32 API which are used in the macros.

Implement Data Exchange in MFC

MFC uses C++ OOP style managed approach and we declare meaningful dialog member variables in the dialog class. The dialog should have corresponding UI controls like textbox, checkbox, radio button, combo dropdown etc for each of its member variables. These member variables are processed in programs and they are bridged to these UI control elements via DDX for user interactions.

One example with the student application login dialog. We have two textboxes IDC_EDITUSER and IDC_EDITPASSWORD and one checkbox IDC_CHKREMEMBER. We have taken two CString type variables named as m_strUsername and m_strPassword for handling these text fields. There is also m_bRemember member which is a BOOL type variable to exchange data between checkboxes. We implement dialog DoDataExchange() and place data exchange macros (DDX_Text, DDX_Check) inside this function.

class CStudentDlg : public CDialog
public :
   virtual void DoDataExchange(CDataExchange* pDX);
private :
    CString m_strUsername;
    CString m_strPassword;
    BOOL    m_bRemember;

void CStudentDlg::DoDataExchange(CDataExchange* pDX)
   /* Call parent function */
   /* Exchange User name field */
   DDX_Text(pDX, IDC_EDITUSER, m_strUsername);
   /* Exchange Password field */
   DDX_Text(pDX, IDC_EDITPASSWORD, m_strPassword);
   /* Exchange remnember field */
   DDX_Check(pDX, IDC_CHKREMEMBER, m_bRemember);


UpdateData and DoDataExchange

UpdateData() function is used to invoke data exchange in the dialog. UpdateData() function calls DoDataExchange() abstract function and the parameter tells the direction of the data i.e. whether to update member data from UI (with TRUE) or update UI with member data(with FALSE).

To carry out the exchange, UpdateData sets up a CDataExchange object. It constructs the object with dialog window member and the bSaveAndValidate variable from UpdateData() function. It then calls dialog class's override of CDialog's DoDataExchange member function passing the reference of the CDataExchange object as the argument. The CDataExchange object passed to UpdateData represents the context of the exchange, defining such information as the direction of the exchange. The purpose of UpdateData() function is to update member variables with the values from UI controls. This is done with an argument value of TRUE. However, a FALSE parameter to this function inverses the flow and UI controls are updated with dialog member variables.

void CStudentDlg::UpdateData(BOOL bUpdateData)
  /* Construct CDataExchange */
  CDataExchange DX(this, bUpdateData);
  /* Call DDX with the object */
void CStudentDlg::DoDataExchange(CDataExchange* pDX)
  if (pDX->m_bSaveAndValidate == TRUE)
    /* UI data saved to member data */
    /* Member data transferred to UI */

UpdateData data flow direction

mfc dodataexchange updatedata true false

Display member data to UI control

We set initial default values of data members in the dialog constructor. We have set username as user1, password as blank, and remember field as false.

After the construction of the dialog object, the MFC framework calls dialog initialization. MFC framework calls UpdateData(FALSE) on OnInitDialog event handler. Framework's DDX mechanism transfers the values of the member variables to the controls in the dialog box using virtual function DoDataExchange().

  m_strUsername = "user1";
  m_strPassword = "";
  m_bRemember = FALSE;
void OnInitDialog()
  /* Update UI controls with data */

Update member data from UI control

Now we require to save the data member from UI fields. Here is an event called OnSubmitDialog() which triggers when the user clicks or presses submit button. We need to extract user data from UI field to our dialog data member fields. We can further process these data values in the program like validating the username and password from the database or config file.

void OnSubmitDialog()
  /* Update data member from UI data */
  /* Process user name, password, remeber field */
  /* check username and password from database /file */

Data exchange macros

How to know which DDX_XXXX macro should be used in the exchange routine? The name part of the macro after DDX_ decides which dialog control will be used like edit text control should use macro DDX_Text, DDX_Check is for the exchange of checkboxes and DDX_Radio for handing radio buttons etc. Know more: All data exchange macros has been explained.

Data validation macros

DDX_XXX routines are good for exchange between UI values to data members. Now user might enter invalid values or out of the range values or unintentional values. So there should be a sanity check to validate the UI given values before is saved to member variables.

Dialog Data validation macros or DDV_XXX macros are used to validate the data before exchanging it to the member variable. These macros show a default warning message to the user if the validation fails. Know more: Data valivation and custom error messages.

Custom validation message box

MFC framework has all types of DDV_XXX macros to handle all types of variables and UI controls however they display a generic message to the user. These generic messages might not be relevant to the user and programmers might require to implement a custom validation routine and implement a message box with a relevant and appropriate warning message for the user. Know more: Custom validation message box.

About our authors: Team EQA

Further readings

What is a Window CallBack procedure and what is its utility?
What is a Window CallBack procedure? Understand application implemented WNDPROC function, DefWindowProc, message handling, example source code, diagram.

What is the utility of calling DefWindowProc() function in CALLBACK window procedure?
What is the utility of calling DefWindowProc() function in CALLBACK window procedure?

What are LPARAM and WPARAM in window proc function ? How Win32 subsystem pass parameters to this function?
Explains the parameters WPARAM and LPARAM and in window procedure function. What is this W and L stands for? How Win32 subsystem pass parameters?

How windows program handles message pump and how to exit from the loop?
How windows program handles message pump and how to exit from the loop?