| Tenouk C & C++ | MFC Home | Modal Dialog & Windows Common Controls 1 | Modal Dialog & Windows Common Controls 3 | Download | Site Index |


 

 

 

 

 

 

Module 5a:

The Modal Dialog and Windows Common Controls 2

 

 

 

 

 

 

This is a continuation from the previous module... 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. Aligning Controls

  2. Selecting a Group of Controls

  3. ClassWizard and the Dialog Class

  4. Connecting the Dialog to the View

  5. Understanding the MYMFC7 Application

  6. Enhancing the Dialog Program

 

 

Aligning Controls

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

------------------------------------------------------------------------------------------------------------------------------------

Aligning controls on the dialog

 

Figure 26: Aligning controls on the dialog.

 

Using menus under the Layout menu for controls alignment etc

 

Figure 27: Using sub menus under the Layout menu for controls alignment etc.

 

 

Modifying the Dept (department) list box properties

 

Figure 28: Modifying the Dept (department) list box properties.

 

 

Modifying the Lang (language) combo box

 

Figure 29: Modifying the Lang (language) combo box.

 

 

Modifying the Loyalty and Reliability scroll bar properties

 

Figure 30: Modifying the Loyalty and Reliability scroll bar properties.

 

Selecting a Group of Controls

 

To quickly select a group of controls, position the mouse cursor above and to the left of the group. Hold down the left mouse button and drag to a point below and to the right of the group, as shown here.

 

How to select a group of controls on the dialog

 

Figure 31: How to select a group of controls on the dialog.

 

 

Modifying the Special pushbutton properties.

 

Figure 32: Modifying the Special pushbutton properties.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Using the Picture control to display any icon

 

Figure 33: Using the Picture control to display any icon.

 

Check the dialog's tabbing order. Choose Tab Order from the dialog editor's Layout menu. Use the mouse to set the tabbing order shown below. Click on each control in the order shown, and then press Enter.

 

Viewing and setting the tab order

 

Figure 34: Viewing and setting the tab order.

 

The tab order of the controls

 

Figure 35: The tab order of the controls.

 

If you mess up the tab sequence partway through, you can recover with a Ctrl-left mouse click on the last correctly sequenced control. Subsequent mouse clicks will start with the next sequence number.

 

Save the resource file on disk. For safety, choose Save from the File menu or click the Save button on the toolbar to save mymfc7.rc. Keep the dialog editor running, and keep the newly built dialog on the screen.

 

ClassWizard and the Dialog Class

 

You have now built a dialog resource, but you can't use it without a corresponding dialog class. (The section titled "Understanding the MYMFC7 Application" explains the relationship between the dialog window and the underlying classes.) ClassWizard works in conjunction with the dialog editor to create that class as follows:

 

Choose ClassWizard from Visual C++'s View menu (or press Ctrl-W). Be sure that you still have the newly built dialog, IDD_DIALOG1, selected in the dialog editor and that MYMFC7 is the current Visual C++ project.

 

Add the CMymfc7Dialog class. ClassWizard detects the fact that you've just created a dialog resource without an associated C++ class. It politely asks whether you want to create a class, as shown below.

 

A new class creation dialog prompt

 

Figure 36: A new class creation dialog prompt.

 

Accept the default selection of Create A New Class, and click OK. Fill in the top field of the New Class dialog, as shown here.

 

New class information dialog

 

Figure 37: New class information dialog.

 

Add the CMymfc7Dialog variables. After ClassWizard creates the CMymfc7Dialog class, the MFC ClassWizard dialog appears. Click on the Member Variables tab, and the Member Variables page appears, as shown here.

 

Adding the CMymfc7Dialog variables through the Member Variables page of the ClassWizard

 

Figure 38: Adding the CMymfc7Dialog variables through the Member Variables page of the ClassWizard.

 

You need to associate data members with each of the dialog's controls. To do this, click on a control ID and then click the Add Variable button. The Add Member Variable dialog appears, as shown in the following illustration.

 

Adding member variable’s category and type

 

Figure 39: Adding member variable’s category and type.

 

 

Type in the member variable name, and choose the variable type according to the following table. Be sure to type in the member variable name exactly as shown; the case of each letter is important. For the Category, select Value for all the member variable. When you're done, click OK to return to the MFC ClassWizard dialog. Repeat this process for each of the listed controls.

 

Control ID

Data Member

Type

IDC_BIO

m_strBio

CString

IDC_CAT

m_nCat

int

IDC_DEPT

m_strDept

CString

IDC_DIS

m_bInsDis

BOOL

IDC_EDUC

m_strEduc

CString

IDC_LANG

m_nLang

int

IDC_LIFE

m_bInsLife

BOOL

IDC_LOYAL

m_nLoyal

int

IDC_MED

m_bInsMed

BOOL

IDC_NAME

m_strName

CString

IDC_RELY

m_nRely

int

IDC_SKILL

m_strSkill

CString

IDC_SSN

m_nSsn

int

 

Table 1: Member variables for MYMFC7 controls

 

 

Member variables added when seen through the ClassWizard’s Member Variables page

 

Figure 40: Member variables added when seen through the ClassWizard’s Member Variables page.

 

As you select controls in the MFC ClassWizard dialog, various edit boxes appear at the bottom of the dialog. If you select a CString variable, you can set its maximum number of characters; if you select a numeric variable, you can set its high and low limits. Set the minimum value for IDC_SSN to 0 and the maximum value to 999999999.

 

Setting the minimum and maximum value of the member variable for data validation

 

Figure 41: Setting the minimum and maximum value of the member variable for data validation.

 

Most relationships between control types and variable types are obvious. The way in which radio buttons correspond to variables is not so intuitive, however. The CDialog class associates an integer variable with each radio button group, with the first button corresponding to value 0, the second to 1, and so forth.

 

Add the message-handling function for the Special button. CMymfc7Dialog doesn't need many message-handling functions because the CDialog base class, with the help of Windows, does most of the dialog management. When you specify the ID IDOK for the OK button (ClassWizard's default), for example, the virtual CDialog function OnOK() gets called when the user clicks the button. For other buttons, however, you need message handlers.

Click on the Message Maps tab. The ClassWizard dialog should contain an entry for IDC_SPECIAL in the Object IDs list box. Click on this entry, and double-click on the BN_CLICKED message that appears in the Messages list box. ClassWizard invents a member function name, OnSpecial(), and opens the Add Member Function dialog, as shown here.

 

Adding the message-handling function for the Special button

 

Figure 42: Adding the message-handling function for the Special button.

 

You could type in your own function name here, but this time accept the default and click OK. Click the Edit Code button in the MFC ClassWizard dialog. This opens the file mymfc7Dialog.cpp and moves to the OnSpecial() function. Insert a TRACE statement in the OnSpecial() function by typing in the code shown below, which replaces the existing code:

 

void CMymfc7Dialog::OnSpecial()

{

    TRACE("CMymfc7Dialog::OnSpecial\n");

}

 

MFC, Visual C++ code segment

 

Listing 1.

 

Use ClassWizard to add an OnInitDialog() message-handling function. As you'll see in a moment, ClassWizard generates code that initializes a dialog's controls. This DDX (Dialog Data Exchange) code won't initialize the list-box choices, however, so you must override the CDialog::OnInitDialog function. Although OnInitDialog() is a virtual member function, ClassWizard generates the prototype and skeleton if you map the WM_INITDIALOG message in the derived dialog class.

To do so, click on CMymfc7Dialog in the Object IDs list box and then double-click on the WM_INITDIALOG message in the Messages list box. Click the Edit Code button in the MFC ClassWizard dialog to edit the OnInitDialog() function.

 

Adding an OnInitDialog() message-handling function through the ClassWizard

 

Figure 43: Adding an OnInitDialog() message-handling function through the ClassWizard.

 

 Type in the following code, which replaces the existing code:

 

BOOL CMymfc7Dialog::OnInitDialog()

{

    // Be careful to call CDialog::OnInitDialog

    // only once in this function

    CListBox* pLB = (CListBox*) GetDlgItem(IDC_DEPT);

    pLB->InsertString(-1, "Documentation");

    pLB->InsertString(-1, "Accounting");

    pLB->InsertString(-1, "Human Relations");

    pLB->InsertString(-1, "Security");

 

    // Call after initialization

    return CDialog::OnInitDialog();

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

MFC, Visual C++ code segment

 

Listing 2.

 

You could also use the same initialization technique for the combo boxes, in place of the initialization in the resource.

 

Connecting the Dialog to the View

 

Now we've got the resource and the code for a dialog, but it's not connected to the view. In most applications, you would probably use a menu choice to activate a dialog, but we haven't studied menus yet. Here we'll use the familiar mouse-click message WM_LBUTTONDOWN to start the dialog. The steps are as follows:

 

  1. In ClassWizard, select the CMymfc7View class. At this point, be sure that MYMFC7 is Visual C++'s current project.

  2. Use ClassWizard to add the OnLButtonDown() member function. You've done this in the examples in earlier Modules. Simply select the CMymfc7View class name, click on the CMymfc7View object ID, and then double-click on WM_LBUTTONDOWN.

 

Mapping a WM_LBUTTONDOWN (clicking the left mouse button) message to object’s ID

 

Figure 44: Mapping a WM_LBUTTONDOWN (clicking the left mouse button) message to object’s ID.

 

  1. Write the code for OnLButtonDown() in file mymfc7View.cpp by clicking the Edit Code button. Add the following code below. Most of the code consists of TRACE statements to print the dialog data members after the user exits the dialog. The CMymfc7Dialog constructor call and the DoModal() call are the critical statements, however:

 

void CMymfc7View::OnLButtonDown(UINT nFlags, CPoint point)

{

    CMymfc7Dialog dlg;

    dlg.m_strName  = "Porter, Harry";

    dlg.m_nSsn     = 12345678;

    dlg.m_nCat     = 1;  // 0 = hourly, 1 = salary

    dlg.m_strBio   = "Like to do programming for fun";

    dlg.m_bInsLife = FALSE;

    dlg.m_bInsDis  = TRUE;

    dlg.m_bInsMed  = TRUE;

    dlg.m_strDept  = "Documentation";

    dlg.m_strSkill = "Executive";

    dlg.m_nLang    = 1;

    dlg.m_strEduc  = "High School";

    dlg.m_nLoyal   = dlg.m_nRely = 50;

 

   int ret = dlg.DoModal();

 

    TRACE("DoModal return = %d\n", ret);

    TRACE("name = %s, ssn = %d, cat = %d\n", dlg.m_strName, dlg.m_nSsn, dlg.m_nCat);

    TRACE("dept = %s, skill = %s, lang = %d, educ = %s\n",

          dlg.m_strDept, dlg.m_strSkill, dlg.m_nLang, dlg.m_strEduc);

    TRACE("life = %d, dis = %d, med = %d, bio = %s\n",

          dlg.m_bInsLife, dlg.m_bInsDis, dlg.m_bInsMed, dlg.m_strBio);

    TRACE("loyalty = %d, reliability = %d\n", dlg.m_nLoyal, dlg.m_nRely);

}

 

MFC, Visual C++ code segment

 

Listing 3.

 

Add code to the virtual OnDraw() function in file mymfc7View.cpp. To prompt the user to press the left mouse button, code the CMymfc7View::OnDraw function. The skeleton was generated by AppWizard. The following code (which you type in) replaces the existing code:

 

void CMymfc7View::OnDraw(CDC* pDC)

{

    pDC->TextOut(50, 50, "Press the left mouse button to launch the funny dialog box.");

}

 

MFC, Visual C++ code segment

 

Listing 4.

 

To mymfc7View.cpp, add the dialog class include statement. The OnLButtonDown() function above depends on the declaration of class CMymfc7Dialog. You must insert the following  #include statement:

 

#include "mymfc7Dialog.h"

 

at the top of the CMymfc7View class source code file (mymfc7View.cpp), after the statement:

 

#include "mymfc7View.h"

 

MFC, Visual C++ code segment

 

Listing 5.

 

Build and test the application. If you have done everything correctly, you should be able to build and run the MYMFC7 application through Visual C++. Try entering data in each control, and then click the OK button and observe the TRACE results in the Debug window. Notice that the scroll bar controls don't do much yet; we'll attend to them later. Notice what happens when you press Enter while typing in text data in a control: the dialog closes immediately.

 

 

MYMFC7 program output

 

Figure 45: MYMFC7 program output.

 

MYMFC7 program output when the left mouse button is clicked, full of controls

 

Figure 46: MYMFC7 program output when the left mouse button is clicked, full of controls.

 

Notice that our horizontal scroll bar is not working at this moment. Don’t worry, it is our next task.

 

Understanding the MYMFC7 Application

 

When your program calls DoModal(), control is returned to your program only when the user closes the dialog. If you understand that, you understand modal dialogs. When you start creating modeless dialogs, you'll begin to appreciate the programming simplicity of modal dialogs. A lot happens "out of sight" as a result of that DoModal() call, however. Here's a "what calls what" summary:

 

CDialog::DoModal

    CMymfc7Dialog::OnInitDialog

        …additional initialization…

        CDialog::OnInitDialog

            CWnd::UpdateData(FALSE)

                CMymfc7Dialog::DoDataExchange

    user enters data…

    user clicks the OK button

    CMymfc7Dialog::OnOK

        …additional validation…

        CDialog::OnOK

            CWnd::UpdateData(TRUE)

                CMymfc7Dialog::DoDataExchange

            CDialog::EndDialog(IDOK)

 

OnInitDialog() and DoDataExchange() are virtual functions overridden in the CMymfc7Dialog class. Windows calls OnInitDialog() as part of the dialog initialization process, and that results in a call to DoDataExchange(), a CWnd virtual function that was overridden by ClassWizard. Here is a listing of that function:

 

MFC, Visual C++ code segment

 

Listing 6.

 

The DoDataExchange() function and the DDX_ (exchange) and DDV_ (validation) functions are "bidirectional." If UpdateData() is called with a FALSE parameter, the functions transfer data from the data members to the dialog controls. If the parameter is TRUE, the functions transfer data from the dialog controls to the data members. DDX_Text is overloaded to accommodate a variety of data types. The EndDialog() function is critical to the dialog exit procedure. DoModal() returns the parameter passed to EndDialog(). IDOK accepts the dialog's data, and IDCANCEL cancels the dialog. You can write your own "custom" DDX function and wire it into Visual C++. This feature is useful if you're using a unique data type throughout your application.

 

Enhancing the Dialog Program

 

The MYMFC7 program required little coding for a lot of functionality. Now we'll make a new version of this program that uses some hand-coding to add extra features. We'll eliminate MYMFC7's rude habit of dumping the user in response to a press of the Enter key, and we'll hook up the scroll bar controls.

 

 

Continue on next module...part 3

 

 

 

 

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 | Modal Dialog & Windows Common Controls 1 | Modal Dialog & Windows Common Controls 3 | Download | Site Index |