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 |