Creating an Expanding Dialog


Expanding dialogs are useful if you want to present users with lots of options, but only if they select an appropriate option, or show results of a task only when the task has started. Expanding dialogs expand and contract according to states of controls, usually push buttons or check boxes.

An example of an expanding dialog is the Windows colour picker dialog which expands to give you more control over your choice of colour, but only if you click "Define Custom Colors". The example below expands when the Find button is clicked to show the progress of the search, but all you need to do is to change the list box with another control you wish to be there.

To start with, in order for the expanding dialog to work automatically, the dialog must contain two special controls that will control the expansion. Below is the finished dialog in design mode which shows the important controls, and the tab order, which is also important:

The important controls are related to by their tab order number here:

3: The Expand - Contract control which controls this process. This can be any type of push button control such as a check box, a push button, or what-ever. Call this control IDC_EXPAND.

5: The expand border marker which shows where the expansion will take place. The best control I have found for this is the picture control stretched thin, and left in frame mode, but with the sunken style. This control does not have to be visible, but it must be on the border where the expansion will take place. Call this control IDC_EXPAND_BORDER.

Important: The tab order must be as shown above, with the controls in the expanded section of the dialog after the expand border marker.

When you have completed this, create a class for the dialog called CExpandDialog, derived from the usual CDialog class, and add a handler for the dialog's WM_INITDIALOG message, and add an entry for the IDC_EXPAND control BN_CLICKED, or what-ever is appropriate for the control. Then add a member variable of control type for IDC_EXPAND_BORDER. The default class is CStatic, although we need CWnd, but we will change it later. Call this member m_Devide.

Close ClassWizard, and open the include file for the dialog(ExpandDialog.h). Under the // Dialog Data label, you should find CStatic m_Devide. Change this to CWnd m_Devide.

Note: From now on, type in italics only has to be added. Other code shown should already exist.

Under the protected Implementation section, add these lines:

void ContractDialog();
void EnableExpandedControls(BOOL bEnabled);

int m_nNormalHeight; int m_nExpandedHeight; BOOL m_bExpanded;

We've now finished with the include file, so close it and save it.

Open the implementation file for the dialog (ExpandDialog.cpp), and in the class constructor

CExpandDialog::CExpandDialog(CWnd* pParent /*=NULL*) : CDialog(CExpandDialog::IDD, pParent) { m_nNormalHeight = 0; m_nExpandedHeight = 0; m_bExpanded = TRUE; //{{AFX_DATA_INIT(CExpandDialog) //}}AFX_DATA_INIT }

When the dialog is initialized, we want the dialog to be in its contracted state, so that the advanced controls are hidden.

So to do that, we add the code below:

BOOL CExpandDialog::OnInitDialog()


 return TRUE;

The IDC_EXPAND button's OnExpand() message handler now needs to contain this code to toggle the dialog between the expanded and normal states:

void CExpandDialog::OnExpand()
 CRect rcDlg;


 if (m_bExpanded)
   rcDlg.left + rcDlg.Width(), + m_nNormalHeight);
  rcDlg.SetRect( rcDlg.left,, 
   rcDlg.left + rcDlg.Width(), + m_nExpandedHeight);

 MoveWindow(rcDlg, TRUE);

 m_bExpanded = !m_bExpanded;


This function uses the m_bExpanded flag to determine whether the dialog should be in its expanded or contracted state. It then uses MoveWindow appropriately to modify the height of the dialog. After re-sizing, the extra controls are either enabled or disabled, again, depending on the state the dialog is in.

Now we have to implement the EnableExtraControls() function. We have already defined the function in the include file, so we just need to add the code below in its entirety:

void CExpandDialog::EnableExpandedControls(BOOL bEnabled)
 HWND hWndChild = ::GetDlgItem(m_hWnd, IDC_EXPAND_BORDER);

 while (hWndChild != NULL)
  ::EnableWindow(hWndChild, bEnabled);
  hWndChild = ::GetNextWindow(hWndChild, GW_HWNDNEXT);

This is why the tab order is so important. It enables or disables all the controls after the expand border.

The ContractDialog() function initializes the dialog in its contracted state, so that the advanced or extra controls aren't visible. Again, as we have already defined the function, we just have to add this code:

void CExpandDialog::ContractDialog()
 CRect rcDlg, rcMarker;
 m_nExpandedHeight = rcDlg.Height();

 m_nNormalHeight = ( -;

 rcDlg.SetRect( rcDlg.left,, 
  rcDlg.left + rcDlg.Width(), + m_nNormalHeight);
 MoveWindow(rcDlg, TRUE);

 m_bExpanded = FALSE;


The code is now complete, so you can now compile and run it.

When you click IDC_EXPAND, the dialog should expand.

This code does not change the button caption of IDC_EXPAND, accordingly to the state of the dialog which is probably preferably, and it also does not change the caption of the dialog, which could show what state the dialog is in.


Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Lenovo recommends Windows 8 Pro. "I dropped my laptop getting out of the taxi." This probably sounds familiar to most IT professionals. If your employees are traveling, you know their devices are in for a rough go. Whether it's a trip to the conference room or a convention out of town, any time equipment leaves a user's desk it is at risk of being put into harm's way. Stay connected at all times, whether at the office or on the go, with agile, durable, and flexible devices like the Lenovo® …

  • U.S. companies are desperately trying to recruit and hire skilled software engineers and developers, but there is simply not enough quality talent to go around. Tiempo Development is a nearshore software development company. Our headquarters are in AZ, but we are a pioneer and leader in outsourcing to Mexico, based on our three software development centers there. We have a proven process and we are experts at providing our customers with powerful solutions. We transform ideas into reality.

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date