Home

Dialog Boxes

 
 

Overview of Dialog Boxes

A dialog box is a rectangular window whose main role is to host or hold other Windows controls. For this reason, a dialog box is referred to as a container. It is the primary interface of user interaction with the computer. By itself, a dialog box means nothing. The controls it hosts accomplish the role of dialog between the user and the machine.

A dialog box has the following characteristics:

  • It is equipped with the system Close button System Close . As the only system button, this button allows the user to dismiss the dialog and ignore whatever the user would have done on the dialog box.
  • It cannot be minimized, maximized, or restored. A dialog box does not have any other system button but Close.
  • It is usually modal. The user is usually not allowed to continue any other operation until the dialog box is dismissed.
  • It provides a way for the user to close or dismiss the dialog. Most dialog boxes have the OK and the Cancel buttons, although this depends on the application developer. When the dialog has the OK and the Cancel buttons, the OK button is configured to behave as if the user had pressed Enter. In that case, whatever the user had done would be acknowledged and transferred to the hosting dialog box, window, or application. Pressing Esc applies the same behavior as if the user had clicked Cancel.

Practical Learning Practical Learning: Creating an Application

  1. Start Microsoft Visual C++ or Microsoft Visual Studio
  2. Create a new Win32 Project named ExoDialog1 
  3. Make sure you create the Windows Application in an Empty Project
  4. In the Solution Explorer, right-click ExoDialog1 and click Properties...
  5. In the Property Pages, specify that you want to Use MFC in a Shared DLL
  6. To create the application class of the project, on the main menu, click Project -> Add New Item...
  7. In the Templates section, click C++ File. Set the File Name to Exercise and click Finish.
  8. To create the application, change the file as follows:
     
    #include <afxwin.h>
    
    class CExerciseApp : public CWinApp
    {
    public:
    	BOOL InitInstance();
    };
    
    BOOL CExerciseApp::InitInstance()
    {
    	return TRUE;
    }
    
    CExerciseApp theApp;
  9. Save All

Dialog Box Creation

When using Win32 to create an application, a dialog is created using a text file called a resource file. The file has the extension .rc as we saw in a previous lesson. Microsoft Visual C++ makes it particularly easy to create a dialog box and, behind the scenes, it creates the appropriate section for a dialog box.

To create a dialog box in MSVC, from the Add Resources dialog box, simply select the Dialog node and the object is ready.

After creating a "physical" dialog box, you should create its class so that other objects of the application can use this control.

Practical Learning Practical Learning: Creating a Dialog Box

  1. To create a dialog box, on the main menu, click Project -> Add Resource...
     
    Add Resource
  2. In the Add Resource dialog box, click Dialog and click New
  3. To save the dialog box and the new resource, on the Standard toolbar, click the Save All button Save All  
  4. To create a class for the dialog box and display the dialog box in the application, change the file as follows:
     
    #include <afxwin.h>
    #include "Resource.h"
    
    class CExerciseApp : public CWinApp
    {
    public:
    	BOOL InitInstance();
    };
    
    class CExoDialog : public CDialog
    {
    public:
    	enum { IDD = IDD_DIALOG1 };
    
    	CExoDialog();
    };
    
    CExoDialog::CExoDialog()
    	: CDialog(CExoDialog::IDD, NULL)
    {
    }
    
    BOOL CExerciseApp::InitInstance()
    {
    	CExoDialog Dlg;
    	m_pMainWnd = &Dlg;
    	Dlg.DoModal();
    
    	return TRUE;
    }
    
    CExerciseApp theApp;
  5. Test the application
  6. Close it and return to MSVC

The MFC Wizard for a Dialog-Based Application

Microsoft Visual C++ provides an easier way to create an application that is mainly based on a dialog box. To use this technique, start a new project and specify that you want to create an MFC Application. In the 

Practical Learning: Using the Wizard to create a Dialog-Based Application

  1. On the main menu, click File -> New -> Project...
  2. In the New Project dialog box, in the Templates list, click MFC Application
  3. Set the Project Name to ExoDialog2
     
    New Project
  4. Click OK
  5. In the MFC Application Wizard dialog box, click Application Type and, on the right side, click the Dialog Based radio button
     
    MFC Application Wizard
  6. Click Finish
  7. Test the application and return to MSVC
 

Properties of a Dialog Box

Like every resource, a dialog box is recognized throughout the program by an identifier. By default, the first dialog box is identified as IDD_DIALOG1. In this name, ID stands for IDentifier. The second D stands for Dialog. In most cases, you should give an explicit identifier to each resource. For example, if a dialog box is used as an employment application, you can identify it as IDD_EMPL_APP or something like that.

The top section of a dialog box is made of a long bar that we call the title bar. The main area of this bar contains a word or a group of words forming a sentence called a caption. There are two main ways you can change it. At design time, on the Properties window, change the value of the Caption field. At run time, to change the caption, call the CWnd::SetWindowText() method and provide the necessary string as argument. Here is an example:

BOOL CExoDialog2Dlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	. . .

	// TODO: Add extra initialization here
	SetWindowText("Go Slow, Don't Rush It!!!");

	return TRUE;  // return TRUE  unless you set the focus to a control
}

By convention, a dialog box is equipped with only the system Close button Close on its title bar. The Minimize and Maximize buttons are omitted. If you want to add the Minimize button Minimize, at design time, set the Minimize Box property to True or checked. If you want the Maximize button Maximize, set its property to True or checked. Setting one of these properties to True or checked and not the other would disable the other system button. Therefore, here are the combinations you can get:

System Menu = False

System Menu = False

There is no system button

System Menu  = True Minimize Box  = False Maximize Box = True

The Minimize button is disabled

System Menu = True | Minimize Box = False | Maximize Box = True
System Menu = True | Minimize Box = True | Maximize Box = False

System Menu  = True Minimize Box  = True Maximize Box = False

The Maximize button is disabled

System Menu  = True Minimize Box  = True Maximize Box = True

Both the Minimize and Maximize buttons are enabled

System Menu = True | Minimize Box = True | Maximize Box = True
System Menu = True | Minimize Box = False | Maximize Box = False

System Menu  = True Minimize Box  = Talse Maximize Box = Talse

Only the Close button is available

All of the windows we will use in this book are created using a style set in the Win32 API as HWND and implement in MFC by the CWnd class. This class, among other things, defines the style used to control the appearance and certainly part of the behavior of an object. Based on this, a window is referred to as popup if it can be displayed on the screen. That is, if it can be "physically" located.

A window is referred to as child if its appearance is dependent of the appearance of another window. All of the Windows controls that we will be placing on our dialog boxes are child controls.

A window is called overlapped if it has the following characteristics:

  • It has a title bar equipped with a caption and at least one of the system buttons
  • It has borders

The Child, Popup, and Overlapped characteristics can be set at design time using the Style property.

Because a dialog box follows these rules, it qualifies as an overlapped window.

By design, a dialog box has thick borders and cannot be resized from its borders or corners, even if the system buttons are available. This characteristic of dialog boxes is controlled by the Border property. The default border of a dialog box is Dialog Frame. If you want he user to be able to resize a dialog box, set its Border value to Resizing:

Resizing a window

A Thin value gives a thin border to the dialog box.

If you do not want borders at all on the object, set its Border value to None. This also removes the title bar and thus the system buttons:

A window with no borders

Practical Learning: Using Dialog Box Properties

  1. To display the dialog's properties, right-click it and click Properties. If you are using MSVC 6, to maintain the Properties window on the screen, click the pushpin button Push Pin
  2. Change the IDentifier of the dialog box to IDD_DLG_MAIN and change its Caption to Credit Application
  3. Change the X Pos value to 120 and the Y Pos value to 100
     
    The Properties window of Visual C++ 6
  4. To change the dialog box into a resizable window, click the Styles property page. Set its Border to Resizing. Set its Maximize Box and its Minimize Box properties to True or checked
  5. To give a client edge to the window, (click the More Styles property page and) set the Client Edge to True or checked
  6. Test the application. After viewing the dialog box, close it and return to MSVC

Dialog Box Methods

As seen above, to create dialog box, derive a class from CDialog and use a constructor to specify the resource that holds the default characteristics of the object. The CDialog class provides three constructors as follows:

CDialog();
CDialog(UINT nIDTemplate, CWnd* pParentWnd = NULL);
CDialog(LPCTSTR lpszTemplateName, CWnd* pParentWnd = NULL);

The default constructor, CDialog() can be use to create a variable whose behavior is not yet known or, for one reason or another, cannot yet be defined.

The resources we will be using in MFC have an identifier that allow them to be recognized by other others of an application. This is why, whenever you visually create a dialog box, you also specify its identifier. This identifier can be used as the first argument, nIDTemplate, of a CDialog() constructor to create a dialog box from an existing resource.

If you are using a Win32 template to create your dialog box, pass the name of this template as a string to a CDialog() constructor, lpszTemplateName.

All or most of the window we will be creating in this book are owned and made available to the operating system by an application. The second argument of the last two constructors allow you to specify "who" owns the dialog box you are creating. If the dialog box has a parent, which is usually a CWnd type, specify its name as the pParenWnd argument. Otherwise, leave this argument at its default, which is NULL, letting the application own the dialog box.

There are two types of dialog boxes: modal and modeless. A Modal dialog box is one that the user must first close in order to have access to any other framed window or dialog box of the same application:

 
 

The Paragraph dialog box of WordPad is a modal dialog box: when it is displaying, the user cannot use any other part of WordPad unless he or she closes this object first

 

After creating a dialog box, to display it as modal, call the DoModal() method. Its syntax is:

virtual int DoModal();

This method by itself does nothing more than displaying a dialog box as modal. We will learn that you can use this method to find out how the user had closed such a dialog box.

A modeless dialog box allows the user to access the main application or any other possible object of the application even if this dialog box is displaying. The user can decide to close it when the object is not need anymore or the user can keep it on as long as necessary. Here is an example:

The Find dialog box of WordPad is an example of a modeless dialog box. Although it is displaying on this picture, the user can still click and activate any of the windows in the background

Because a modeless dialog box is closed as the user judges it necessary, making it possible to forget, the operating system needs to make sure that this object closes when its parent application closes so its memory resource can be freed and made available to other applications. Therefore, the creating of a modeless dialog is a little different. You can first create a dialog resource and associate a class to it. To formally create a modeless dialog box and make it part of the application, you can use the Create() method of the CDialog class. The MFC provides two syntaxes that are:

BOOL Create(UINT nIDTemplate, CWnd* pParentWnd = NULL);
BOOL Create(LPCTSTR lpszTemplateName, CWnd* pParentWnd = NULL);

As done with the CDialog constructor, the nIDTemplate parameter is the identifier you used when visually creating the dialog re. If you are using a dialog box from a template, specify its name as the lpszTemplateName argument. In order to effectively use a modeless dialog box, it must be called from another window. Otherwise you can just create a regular dialog box. The object from which you will be calling the dialog box is also responsible for closing it (or "cleaning" it). Therefore, the class that calls the modeless dialog box "owns" i. This means that you can specify it as the pParentWnd  argument.

When creating a modeless dialog box, declare a pointer to its class. Then call the Create() method, passing the identifier or the template being used. You can do this in the constructor of the class that will be its parent. Here is an example:

CDialog5Dlg::CDialog5Dlg(CWnd* pParent /*=NULL*/)
	: CDialog(CDialog5Dlg::IDD, pParent)
{
	CCoolMode* Cool = new CCoolMode();
	
	Cool->Create(IDD_DLG_MDLS,this);
}

To formally display the object, you have various options. When creating it, at design time, set its Visible property to True (actually you would be applying the WS_VISIBLE style). If you did not or if the modeless dialog box is hidden at a particular time, to display it, call the CWnd::ShowWindow() method. Its syntax is:

BOOL ShowWindow(int nCmdShow);

This method is used to display or hide any window that is a descendent of CWnd. Its argument, nCmdShow, specifies what to do with the appearance or disappearance of the object. Its possible values are:

  Value Description
  SW_SHOW Displays a window and makes it visible
  SW_SHOWNORMAL Displays the window in its regular size. In most circumstances, the operating system keeps track of the last location and size a window such as Internet Explorer or My Computer had the last time it was displaying. This value allows the OS to restore it.
  SW_SHOWMINIMIZED Opens the window in its minimized state, representing it as a button on the taskbar
  SW_SHOWMAXIMIZED Opens the window in its maximized state
  SW_SHOWMINNOACTIVE Opens the window but displays only its icon. It does not make it active
  SW_SHOWNA As previous
  SW_SHOWNOACTIVATE Retrieves the window's previous size and location and displays it accordingly
  SW_HIDE Used to hide a window
  SW_MINIMIZE shrinks the window and reduces it to a button on the taskbar
  SW_RESTORE If the window was minimized or maximized, it would be restored to its previous location and size

To use one of these constants, pass it to the ShowWindow() method. For example, to minimize a window, you would use code as follows:

ShowWindow(SW_SHOWMINIMIZED);

After creating a dialog box, to initialize it (or the objects it is hosting), use the OnInitDialog() method. Its syntax is:

virtual BOOL OnInitDialog( );

As you can see, this method does not do more than provide a platform to set the default values of the dialog box and/or its controls.

Practical Learning: Using Dialog Box Methods

  1. To programmatically change a dialog's property, access the OnInitDialog() event and call the SetWindowText() as follows:
     
    BOOL CDialog2aDlg::OnInitDialog()
    {
    	CDialog::OnInitDialog();
    
    	. . . 
    	// TODO: Add extra initialization here
    	this->SetWindowText("Personal Information");
    
    	return TRUE;  // return TRUE  unless you set the focus to a control
    }
  2. Test the application and return to MSVC
  3. To add another dialog box, on the main menu, click Project -> Add Resource...
  4. From the Add Resource dialog box, double-click Dialog
  5. Change its ID to IDD_DLG_FLOATER and set its Caption to Window Floater
  6. To create a class for the dialog box, right-click the dialog box and click Add Class (if using MSVC 6, right-click the dialog box and click ClassWizard).
  7. Set the Class Name as CFloatingDlg and make sure the class is based on CDialog. Also make sure the resource ID is set to IDD_DLG_FLOATER 
     
  8. Click OK
  9. Access the source file of the first dialog box. Before using the second dialog box, in the top section of the file, include its header file as follows:
     
    #include "stdafx.h"
    #include "Dialog2a.h"
    #include "Dialog2aDlg.h"
    #include "FloaterDlg.h"
  10. To create a modeless dialog box, in the OnInitDialog() event of the main dialog box type the following:
     
    BOOL CDialog2aDlg::OnInitDialog()
    {
    	CDialog::OnInitDialog();
    
    	// Add "About..." menu item to system menu.
    
    	// IDM_ABOUTBOX must be in the system command range.
    	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
    	ASSERT(IDM_ABOUTBOX < 0xF000);
    
    	CMenu* pSysMenu = GetSystemMenu(FALSE);
    	if (pSysMenu != NULL)
    	{
    		CString strAboutMenu;
    		strAboutMenu.LoadString(IDS_ABOUTBOX);
    		if (!strAboutMenu.IsEmpty())
    		{
    			pSysMenu->AppendMenu(MF_SEPARATOR);
    			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
    		}
    	}
    
    	SetIcon(m_hIcon, TRUE);			// Set big icon
    	SetIcon(m_hIcon, FALSE);		// Set small icon
    	
    	// TODO: Add extra initialization here
    	this->SetWindowText("Personal Information");
    
    	CSecondDlg *Floater = new CSecondDlg;
    	Floater->Create(IDD_DLG_FLOATER, this);
    	Floater->ShowWindow(SW_SHOW);
    
    	return TRUE;  // return TRUE  unless you set the focus to a control
    }
  11. Test the application:
     
  12. Close the main dialog box and return to MSVC

Combining Dialog Boxes

It will not be unusual to use various dialog boxes in an application. When in case, you may need to call one dialog box from another. Since a dialog box is created using a class, the first first you must do is to include the header file of the CDialog object whose box you want to call.

To call one dialog box from another window, select the event (or message) from where you would make the call. Declare a variable of the other class and use the CDialog::DoModal() method to display the other object as a modal dialog box.

Practical Learning: Adding Controls to a Dialog Box

  1. Add another dialog box. Set its ID to IDD_DLG_SECOND and its Caption to Secondary Aspect
  2. Create a class for the new dialog box. Set its name to CSecondDlg
  3. Display the main dialog box. Access its list of messages and double-click the WM_LBUTTONDBLCLK to access its event
  4. In the top section of the source file, include the header file of the second dialog box:
     
    #include "stdafx.h"
    #include "Dialog2a.h"
    #include "Dialog2aDlg.h"
    #include "FloaterDlg.h"
    #include "SecondDlg.h"
  5. In the OnDoubleClick() event, call the second dialog box as follows:
     
    void CDialog2aDlg::OnLButtonDblClk(UINT nFlags, CPoint point) 
    {
    	// TODO: Add your message handler code here and/or call default
    	CSecondDlg Dlg;
    	Dlg.DoModal();
    
    	CDialog::OnLButtonDblClk(nFlags, point);
    }
  6. Test the application. To display the secondary dialog box, double-click in the body of the main dialog box:
     
  7. Close each of the dialog boxes and return to MSVC

Home Copyright 2003-2006 FunctionX, Inc.