| Tenouk C & C++ | MFC Home | GDI, Colors & Fonts 3 | Modal Dialog & Windows Common Controls 2 | Download | Site Index |


 

 

 

 

 

Module 5:

The Modal Dialog and Windows Common Controls 1

 

 

 

 

 

 

Program examples compiled using Visual C++ 6.0 (MFC 6.0) compiler on Windows XP Pro machine with Service Pack 2. Topics and sub topics for this Tutorial are listed below:

  1. The Modal Dialog and Windows Common Controls

  2. Modal vs. Modeless Dialogs

  3. Resources and Controls

  4. Programming a Modal Dialog

  5. The MYMFC7 Example

  6. Building the Dialog Resource

  7. Keyboard Accelerator

 

 

 

The Modal Dialog and Windows Common Controls

 

Almost every Windows-based program uses a dialog window to interact with the user. The dialog might be a simple OK message box, or it might be a complex data entry form. Calling this powerful element a dialog "box" is an injustice. A dialog is truly a window that receives messages, that can be moved and closed, and that can even accept drawing instructions in its client area. The two kinds of dialogs are modal and modeless.

 

Modal vs Modeless Dialogs

 

The CDialog base class supports both modal and modeless dialogs. With a modal dialog, such as the Open File dialog, the user cannot work elsewhere in the same application more correctly, in the same user interface thread until the dialog is closed. With a modeless dialog, the user can work in another window in the application while the dialog remains on the screen. Microsoft Word's Find and Replace dialog is a good example of a modeless dialog; you can edit your document while the dialog is open. Your choice of a modal or a modeless dialog depends on the application. Modal dialogs are much easier to program, which might influence your decision.

 

Resources and Controls

 

So now you know a dialog is just a window. What makes the dialog different from the CView windows you've seen already? For one thing, a dialog window is almost always tied to a Windows resource that identifies the dialog's elements and specifies their layout. Because you can use the dialog editor that is one of the resource editors to create and edit a dialog resource, you can quickly and efficiently produce dialogs in a visual manner.

A dialog contains a number of elements called controls. Dialog controls include edit controls (aka text boxes), buttons, list boxes, combo boxes, static text (aka labels), tree views, progress indicators, sliders, and so forth. Windows manages these controls using special grouping and tabbing logic and that relieves you of a major programming burden. The dialog controls can be referenced either by a CWnd pointer (because they are really windows) or by an index number (with an associated #define constant) assigned in the resource. A control sends a message to its parent dialog in response to a user action such as typing text or clicking a button.

The MFC Library and ClassWizard work together to enhance the dialog logic that Windows provides. ClassWizard generates a class derived from CDialog and then lets you associate dialog class data members with dialog controls. You can specify editing parameters such as maximum text length and numeric high and low limits. ClassWizard generates statements that call the MFC data exchange and data validation functions to move information back and forth between the screen and the data members.

 

Programming a Modal Dialog

 

Modal dialogs are the most frequently used dialogs. A user action (a menu choice, for example) brings up a dialog on the screen, the user enters data in the dialog, and then the user closes the dialog. Here's a summary of the steps to add a modal dialog to an existing project:

 

  1. Use the dialog editor to create a dialog resource that contains various controls. The dialog editor updates the project's resource script (RC) file to include your new dialog resource, and it updates the project's resource.h file with corresponding #define constants.

  2. Use ClassWizard to create a dialog class that is derived from CDialog and attached to the resource created in step 1. ClassWizard adds the associated code and header file to the Microsoft Visual C++ project.

 

When ClassWizard generates your derived dialog class, it generates a constructor that invokes a CDialog modal constructor, which takes a resource ID as a parameter. Your generated dialog header file contains a class enumerator constant IDD that is set to the dialog resource ID. In the CPP file, the constructor implementation looks something like this:

 

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

{

    // initialization code here

}

 

The use of enum IDD decouples the CPP file from the resource IDs that are defined in the project's resource.h file.

 

  1. Use ClassWizard to add data members, exchange functions, and validation functions to the dialog class.

  2. Use ClassWizard to add message handlers for the dialog's buttons and other event-generating controls.

  3. Write the code for special control initialization (in OnInitDialog()) and for the message handlers. Be sure the CDialog virtual member function OnOK() is called when the user closes the dialog unless the user cancels the dialog). The OnOK() is called by default.

  4. Write the code in your view class to activate the dialog. This code consists of a call to your dialog class's constructor followed by a call to the DoModal() dialog class member function. DoModal() returns only when the user exits the dialog window.

 

Now we'll proceed with a real example, one step at a time.

 

The MYMFC7 Project Example

 

Let's not mess around with wimpy little dialogs. We'll build a monster dialog that contains almost every kind of control. The job will be easy because Visual C++'s dialog editor is there to help us. The finished product is shown in the following Figure.

 

The finished dialog of the MYMFC7 project

 

Figure 1: The finished dialog of the MYMFC7 project.

 

As you can see, the dialog supports a human resources application. These kinds of business programs are fairly boring, so the challenge is to produce something that could not have been done with 80-column punched cards. The program is brightened a little by the use of scroll bar controls for "Loyalty" and "Reliability." Here is a classic example of direct action and visual representation of data! Later on, ActiveX controls could add more interest.

 

Building the Dialog Resource

 

Here are the steps for building the dialog resource:

 

Run AppWizard to generate a project called MYMFC7. Choose New from Visual C++'s File menu, and then click the Projects tab and select MFC AppWizard (exe). Accept all the defaults but two: select Single Document and deselect Printing And Print Preview. The options and the default class names are shown here.

 

MYMFC7 project summary

 

Figure 2: MYMFC7 project summary.

 

As usual, AppWizard sets the new project as the current project.

 

Create a new dialog resource with ID IDD_DIALOG1 (the default given ID). Choose Resource from Visual C++'s Insert menu. The Insert Resource dialog appears. Click on Dialog, and then click New. Visual C++ creates a new dialog resource, as shown here.

 

Creating a new dialog resource through the Insert menu

 

Figure 3: Creating a new dialog resource through the Insert menu.

 

Inserting new dialog resource

 

Figure 4: Inserting new dialog resource.

 

 

 

 

 

Dialog resource editor

 

Figure 5: Dialog resource editor.

 

The dialog editor assigns the resource ID IDD_DIALOG1 to the new dialog. Notice that the dialog editor inserts OK and Cancel buttons for the new dialog.

 

Resize the dialog and assign a MyDialog caption. Enlarge the dialog box to about 5-by-7 inches.

When you right-click on the new dialog and choose Properties from the pop-up menu, the Dialog Properties dialog appears. Type in the caption for the new dialog as shown in the screen below.

 

Dialog’s properties

 

Figure 6: Dialog’s properties.

 

The state of the pushpin button in the upper-left corner determines whether the Dialog Properties dialog stays on top of other windows. When the pushpin is "pushed," the dialog stays on top of other windows.

 

The pushpin button, making the Dialog Properties staying on top

 

Figure 7: The pushpin button, making the Dialog Properties staying on top.

 

Click the Toggle Grid button (on the Dialog toolbar) to reveal the grid and to help align controls.

 

The dialog grid, helping the controls alignment on the dialog

 

Figure 8: The dialog grid, helping the controls alignment on the dialog.

 

Dialog with grid

Figure 9: Dialog with grid.

 

You can test your dialog during the design stage by clicking the Test switch in the Dialog toolbar.

 

The dialog Test switch, testing your dialog during the design process

 

Figure 10: The dialog Test switch, testing your dialog during the design process.

 

Similar buttons and other utilities can also be accessed through the Layout menu.

 

Accessing dialog’s editing utilities through Layout menu

 

Figure 11: Accessing dialog’s editing utilities through Layout menu.

 

Set the dialog style. Click on the Styles tab at the top of the Dialog Properties dialog, and then set the style properties as shown in the following illustration.

 

Setting the dialog style

 

Figure 12: Setting the dialog style.

 

Set additional dialog styles. Click on the More Styles tab at the top of the Dialog Properties dialog, and then set the style properties as shown here.

 

Setting additional dialog styles

 

Figure 13: Setting additional dialog styles.

 

Add the dialog's controls. Use the control palette to add each control. If the control palette is not visible, right-click any toolbar and choose Controls from the list. Drag controls from the control palette (shown below) to the new dialog and then position and size the controls, as shown in Figure 1. Here are the control palette's controls.

 

Available controls from Visual C++ control palette

Figure 14: Available controls from Visual C++ control palette.

 

 

The dialog editor displays the position and size of each control in the status bar. The position units are special "dialog units," or DLUs, not device units. A horizontal DLU is the average width of the dialog font divided by 4. A vertical DLU is the average height of the font divided by 8. The dialog font is normally 8-point MS Sans Serif.

 

Here's a brief description of the dialog's controls, use drag and drop for the controls:

 

 

Setting The static text control

 

Figure 15: Setting The static text control.

 

Keyboard Accelerator

 

A static text control (such as Name or Skill) has an ampersand (&) embedded in the text for its caption. At runtime, the ampersand will appear as an underscore under the character that follows. This keyboard accelerator or short cut key, enables the user to jump to selected controls by holding down the Alt key (or Ctrl or Shift) and pressing the key corresponding to the underlined character. The related control must immediately follow the static text in the tabbing order. Thus, Alt-N jumps to the Name edit control and Alt-K jumps to the Skill combo box. Needless to say, designated jump characters should be unique within the dialog. The Skill control uses Alt-K because the SSN control uses Alt-S. Unfortunately the keyboard accelerator not works in this example because we need extra step to make it function and will be shown in another Module. The extra step is setting the key through the Accelerator resource as shown below.

 

Assigning the keyboard accelerator through the ResourceView

 

Figure 16: Assigning the keyboard accelerator through the ResourceView.

 

Modifying the SSN edit control properties

 

Figure 17: Modifying the SSN edit control properties.

Modifying the Bio (biography) edit control properties

 

Figure 18: Modifying the Bio (biography) edit control properties.

Modifying the radio button properties

 

Figure 19: Modifying the radio button properties.

 

Modifying the second radio button properties

 

Figure 20: Modifying the second radio button properties.

 

Be sure that both buttons have the Auto property (the default) on the Styles tab set and that only the Hourly button has the Group property set. When these properties are set correctly, Windows ensures that only one of the two buttons can be selected at a time. The Category group box has no effect on the buttons' operation.

 

Modifying the Insurance group box properties

 

Figure 21: Modifying the Insurance group box properties.

 

Modifying the Life, Disability, and Medical check boxes properties

 

Figure 22: Modifying the Life, Disability, and Medical check boxes properties.

Modifying the Skill combo box properties

 

Figure 23: Modifying the Skill combo box properties.

 

Adding the listbox item

 

Figure 24: Adding the listbox item.

 

This is a combo box of type Simple. The user can type anything in the top edit control; use the mouse to select an item from the attached list box, or use the Up or Down direction key to select an item from the attached list box.

 

Modifying the Educ (education) combo box

 

Figure 25: Modifying the Educ (education) combo box.

 

 

Continue on next module...part 2

 

 

 

 

Further reading and digging:

  1. MSDN MFC 7.0 class library online documentation.

  2. MSDN MFC 9.0 class library online documentation - latest version.

  3. Porting & Migrating your older programs.

  4. MSDN Library

  5. DCOM at MSDN.

  6. COM+ at MSDN.

  7. COM at MSDN.

  8. Windows data type.

  9. Win32 programming Tutorial.

  10. The best of C/C++, MFC, Windows and other related books.

  11. Unicode and Multibyte character set: Story and program examples.

 

 


 

| Tenouk C & C++ | MFC Home | GDI, Colors & Fonts 3 | Modal Dialog & Windows Common Controls 2 | Download | Site Index |