C++ Course Listing

 

Exercise:

Creating a Dialogue Box


A dialogue box resource is created using the resource editor, which allows for the creation of controls in the dialogue box. Once this has been done, the class wizard is used to create a dialogue box class.

As you create more components for the dialogue box, Visual C++ will assign them default names. These are not always helpful, so change the names to something meaningful that will help you remember what they are sued for.

In order to follow the steps below, you need to have already created a simple Windows application (.exe), as shown in the previous class (using the App Wizard).

1. Choose Insert, Resource.
2. Double-click Dialog in the Resource Type box. This invokes the dialogue box editor. To the right of this is a palette of controls that may be added to a dialogue box.
3. Choose View, Properties. This causes the properties dialog box for the new dialog box to appear. Change the caption to My Dialogue 01. As the properties dialog box will be used a lot, it can be kept in view by pinning it to the screen using the pin in the top left corner.
4. Create an edit box in the upper portion of the dialogue box.
5. Add a check box directly under the edit box.
6. Add three radio button down the left side of the dialogue box. Label the radio buttons 1, 2 and 3. To align these radio buttons, click one, then while holding down the Ctrl key, click each of the rest. Choose Layout, Align, Left, if necessary drag the stack of controls over with the mouse while they are all selected. Then choose Layout, Space Evenly, Down, to adjust the vertical spacing.
7. Click the 1 radio button and bring up the properties dialog box. Select the Group check box. This indicates that this is the first of a group of buttons.
8. Add a list box to the dialog box, to the right of the radio buttons. Highlight the list box and choose View, Properties to bring up the Properties dialog box if it is not still pinned in place. Select the Styles tab and make sure that the Sort box is not selected. When this box is selected, the strings in your list box are automatically presented in alphabetical order.
This completes the basic resource design. Now the dialogue box class must be created.
9. Select View, ClassWizard. The ClassWizard recognizes that this new dialog box resource does not have a class associated with it. Leave the Create a New Class radio button selected, and click OK.
10. The New Class dialog box appears. Enter the classname as MyDialog01 and click OK. ClassWizard creates a new class, prepares the source file (MyDialog01.cpp) & header file (MyDialog01.h) and adds them to your project. Resource files are the source code, i.e. the C++ code and in Visual C++ these have the extension cpp. Header files contain links to the resources used by the compiler to locate these resources and in Visual C++ these have the extension h.
11. Dialog box resources are connected to the code using the Member Variables tab of the ClassWizard. Click IDC_CHECK1 and then click the Add Variable button. This brings up the Add Member Variable dialog box. The Member Variables tab of the ClassWizard connects dialog box controls to dialog box class member variables. For IDC_CHECK1, fill in the variable name as n_check, and make sure that the category drop-down box has the Value selected. In the Variable Type drop-down box the only possible choice is BOOL, for Boolean. Because a check box can be either selected or not selected, it can be connected only to a BOOL variable. Click OK to complete the connection.
12. Connect IDC_EDIT1 in the same way, to a member variable called n_edit of type CString as a Value. For user entry validation set the maximum number of characters the user can enter into the edit box to 10. If the user makes an invalid entry, MFC will automatically generate an error message informing the user of their error (this requires no programming by you).
13. Connect IDC_LIST1 as a Control to a member variable called n_listbox of type CListBox. Connect IDC_RADIO_1, the first of the group of radio buttons, as a Value to an int member variable called n_radio.
14. Since this is a simple program, the dialogue box will be displayed when the program starts by the DoModal() member function of the dialog box class. Select the ClassView in the project workspace pane, expand the "My class name" (use the class name you assigned earlier) Classes item, then expand C"My class name"App. Double-click the InitInstance() member function. This function is called whenever the application starts. Scroll to the top of the file and after the other #include statements, add the following:
#include ""My class name"dialog.h"
This ensures that the compiler knows what a C"My class name"Dialog class is when it compiles this file.
Double-click InitInstance() in the ClassView again to bring the cursor to the beginning of the function. Scroll down to the end of the function and before the return at the end of the function add the lines of code shown below.

C"My class name"Dialog "Mydialoguename";
"Mydialoguename".n_check = TRUE;
"Mydialoguename".n_edit = "hi there";
CString msg;
if ("Mydialoguename".DoModal() == IDOK)
{


msg = "You clicked OK. ";


}
else
{

msg = "You cancelled. ";


}
msg += "Edit box is: ";
msg += "Mydialoguename".n_edit;
AfxMessageBox (msg);


This code first creates an instance of the dialog box class. It sets the check box and edit box to simple default values. The dialog box displays onscreen by calling its DoModal() function, which returns a number represented by IDOK if the user clicks OK and IDCANCEL if the user clicks Cancel. The code then builds a message and displays it with the AfxMessageBox function.
15. Now build your program. If there are any errors, correct them.
16. Now run your program.
17. Experiment by entering different values into the working program and seeing the results. try to generate an error by being a stupid user. A clever programmer will prevent the user from crashing the program.
18. Dealing with the list box is more difficult because only while the dialog box is onscreen is the list box control a real window. You cannot call a member function of the list box control class unless the dialog box is onscreen. (This is true of any control that you access as a control rather than as a value.) This means that you must initialize the list box (fill it with strings) and use it (determine which string is selected) in functions that are called by MFC while the dialog box is onscreen. When it is time to initialize the dialog box, just before it displays onscreen, a CDialog function named OnInitDialog() is called. In ClassView, right-click C"My class name"Dialog and choose Add Windows Message Handler. The New Windows Message and Event Handlers dialog box will appear. Choose Wn_INITDIALOG from the list and click Add Handler. The message name disappears from the left list and appears in the right list. Click it and then click Edit Existing to see the code.
19. Remove the TODO comment and add calls to the member functions of the list box, as below:


BOOL C"My class name"Dialog::OnInitDialog()
{


CDialog::OnInitDialog();

n_listbox.AddString("First String");
n_listbox.AddString("Second String");
n_listbox.AddString("Yet Another String");
n_listbox.AddString("String Number Four");
n_listbox.SetCurSel(2);

return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE


}


This function starts by calling the base class version of OnInitDialog() to do whatever behind-the-scenes work MFC does when dialog boxes are initialized. Then it calls the list box member function AddString() which, as you can probably guess, adds a string to the list box. The strings will be displayed to the user in the order that they were added with AddString(). The final call is to SetCurSel(), which sets the current selection. As you see when you run this program, the index you pass to SetCurSel() is zero based, which means that item 2 is the third in the list, counting 0, 1, 2.
20. In ClassView, right-click C"My class name"Dialog and choose Add Member Variable. Fill in the dialog box, entering CString and n_selected in the variable type and variable name respectively. Make it public. Click OK. This adds the declaration of the CString called n_selected to the header file for you. Strictly speaking, the variable should be private and you should either add a public accessor function or make C"My class name"App::InitInstance() a friend function to C"My class name"Dialog in order to be truly object oriented. Here we will just do it a quick and dirty way by making it public.
This new member variable is used to hold the string that the user selected. It is set when the user clicks OK or Cancel. To add a function that is called when the user clicks OK, follow these steps:


a. Right-click C"My class name"Dialog in the ClassView, and choose Add Windows Message Handler.
b . In the New Windows Message and Event Handlers dialog box, highlight ID_OK in the list box at the lower right, labeled Class or Object to Handle.
c . In the far right list box, select Bn_CLICKED. You are adding a function to handle the user's clicking the OK button once.
d . Click the Add Handler button. The Add Member Function dialog box appears.
e . Accept the suggested name, OnOK(), by clicking OK.
f . Click the Edit Existing button to edit the code, and add

void C"My class name"Dialog::OnOK()
{


int index = n_listbox.GetCurSel();
if (index != LB_ERR)


{


n_listbox.GetText(index, n_selected);


}
else
{


n_selected = "";


}


CDialog::OnOK();


}


The above code calls the list box member function GetCurSel(), which returns a constant represented by LB_ERR if there is no selection or if more than one string has been selected. Otherwise, it returns the zero-based index of the selected string. The GetText() member function fills n_selected with the string at position index. After filling this member variable, this function calls the base class OnOK() function to do the other processing required.
21. Follow the numbered steps for adding OnOK (as above), except that you choose ID_CANCEL from the top-right box and agree to call the function OnCancel. The code below resets n_selected because the user cancelled the dialog box.

void C"My class name"Dialog::OnCancel()
{


n_selected = "";
CDialog::OnCancel();


}


Add these lines to C"My class name"App::InitInstance() just before the call to AfxMessageBox():
msg += ". List Selection: ";
msg += "Mydialoguename".n_selected;
22. Now build your program. If there are any errors, correct them.
23. Now run your program.
24. The radio buttons must be set so that one is selected by default. Add two lines to C"My class name"Dialog::OnInitDialog(). These lines set the second radio button and save the change to the dialog box:
n_radio = 1;
UpdateData(FALSE);
The call to UpdateData() refreshes the dialog box controls with the member variable values. The parameter indicates the direction of transfer: UpdateData(TRUE) would refresh the member variables with the control values, wiping out the setting of n_radio.

25. Unlike list boxes, a group of radio buttons can be accessed after the dialog box is no longer onscreen, so you won't need to add code to OnOK() or OnCancel(). However, you have a problem: how to convert the integer selection into a string to tack on the end of msg. There are lots of approaches, including the Format() function of CString, but in this case, because there are not many possible selections, a switch statement is readable and quick. At the end of C"My class name"App::InitInstance(), add the lines below just before the call to AfxMessageBox().

msg += "\r\n";
msg += "Radio Selection: ";
switch ("Mydialoguename".n_radio)
{


case 0:
msg += "0";
break;
case 1:
msg += "1";
break;
case 2:
msg += "2";
break;
default:
msg += "none";
break;


}


The first new line adds two special characters to the message. Return, represented by \r, and new line, represented by \n, combine to form the Windows end-of-line marker. This adds a line break after the part of the message you have built so far. The rest of msg will appear on the second line of the message box. The switch statement is an ordinary piece of C++ code, which was also present in C. It executes one of the case statements, depending on the value of "Mydialoguename".n_radio.
26. Now build your program. If there are any errors, correct them.
27. Now run your program.


Congratulations! You have completed for first real Windows program in C++.

by Matthew Martin

top of page