?? ch02.htm
字號(hào):
a CDialog function named OnInitDialog() is called. Although the full explanation
of what you are about to do will have to wait until Chapter 3, "Messages and
Commands," follow the upcoming steps to add the function to your class.</P>
<P>In ClassView, right-click CSdiDialog and choose Add Windows Message Handler. The
New Windows Message and Event Handlers dialog box shown in Figure 2.13 appears. Choose
WM_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.</P>
<P><A HREF="javascript:popUp('02uvc13.gif')"><B>FIG. 2.13</B></A><B> </B><I>The New
Windows Message and Event Handlers dialog box helps you override OnInitDialog().</I></P>
<P>Remove the TODO comment and add calls to the member functions of the list box
so that the function is as shown in Listing 2.2.</P>
<P>
<H4>Listing 2.2  SDIDIALOG.CPP--CSdiDialog::OnInitDialog()</H4>
<PRE>BOOL CSdiDialog::OnInitDialog()
{
CDialog::OnInitDialog();
m_listbox.AddString("First String");
m_listbox.AddString("Second String");
m_listbox.AddString("Yet Another String");
m_listbox.AddString("String Number Four");
m_listbox.SetCurSel(2);
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
</PRE>
<PRE>}
</PRE>
<P>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.</P>
<BLOCKQUOTE>
<P>
<HR>
<strong>NOTE:</strong> Usually, the strings of a list box are not hardcoded like this. To
set them from elsewhere in your program, you have to add a CStringArray member variable
to the dialog box class and a function to add strings to that array. The OnInitDialog()
would use the array to fill the list box. Alternatively, you can use another one
of MFC's collection classes or even fill the list box from a database. For more about
CStringArray and other MFC collection classes, consult Appendix F. Database programming
is covered in Chapter 22, "Database Access." 
<HR>
</BLOCKQUOTE>
<P>In order to have the message box display some indication of what was selected
in the list box, you have to add another member variable to the dialog box class.
This member variable will be set as the dialog box closes and can be accessed after
it is closed. In ClassView, right-click CSdiDialog and choose Add Member Variable.
Fill in the dialog box, as shown in Figure 2.14, and then click OK. This adds the
declaration of the CString called m_selected to the header file for you. (If the
list box allowed multiple selections, you would have to use a CStringArray to hold
the list of selected items.) Strictly speaking, the variable should be private, and
you should either add a public accessor function or make CSdiApp::InitInstance()
a friend function to CSdiDialog in order to be truly object oriented. Here you take
an excusable shortcut. The general rule still holds: Member variables should be private.</P>
<P><A HREF="javascript:popUp('02uvc14.gif')"><B>FIG. 2.14</B></A><B> </B><I>Add a
CString to your class to hold the string that was selected in the list box.</I></P>
<P><I></I>
<BLOCKQUOTE>
<P>
<HR>
<strong>TIP:</strong> Object-oriented concepts (such as accessor functions), friend functions,
and the reasoning behind private member variables are discussed in Appendix A, "C++
Review and Object-Oriented Concepts."
<HR>
</BLOCKQUOTE>
<P>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:</P>
<P>
<DL>
<DT></DT>
<DD><B>1. </B>Right-click CSdiDialog in the ClassView, and choose Add Windows Message
Handler.
<P>
<DT></DT>
<DD><B>2. </B>In the New Windows Message and Event Handlers dialog box, shown in
Figure 2.15, highlight ID_OK in the list box at the lower right, labeled Class or
Object to Handle.
<P>
</DL>
<P><A HREF="javascript:popUp('02uvc15.gif')"><B>FIG. 2.15</B></A><B> </B><I>Add a
function to handle the user's clicking OK on your dialog box.</I></P>
<P><I></I>
<DL>
<DD><B>3. </B>In the far right list box, select BN_CLICKED. You are adding a function
to handle the user's clicking the OK button once.
<P>
<DT></DT>
<DD><B>4. </B>Click the Add Handler button. The Add Member Function dialog box shown
in Figure 2.16 appears.
<P>
</DL>
<P><A HREF="javascript:popUp('02uvc16.gif')"><B>FIG. 2.16</B></A><B> </B><I>ClassWizard
suggests a very good name for this event handler: Do not change it.</I></P>
<P><I></I>
<DL>
<DT><I></I></DT>
<DD><B>5. </B>Accept the suggested name, OnOK(), by clicking OK.
<P>
<DT></DT>
<DD><B>6. </B>Click the Edit Existing button to edit the code, and add lines as shown
in Listing 2.3.
<P>
</DL>
<H4>Listing 2.3  SDIDIALOG.CPP--CSdiDialog::OnOK()</H4>
<PRE>void CSdiDialog::OnOK()
{
int index = m_listbox.GetCurSel();
if (index != LB_ERR)
{
m_listbox.GetText(index, m_selected);
}
else
{
m_selected = "";
}
CDialog::OnOK();
</PRE>
<PRE>}
</PRE>
<P>This 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 m_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.</P>
<P>In a moment you will add lines to CSdiApp::InitInstance() to mention the selected
string in the message box. Those lines will execute whether the user clicks OK or
Cancel, so you need to add a function to handle the user's clicking Cancel. Simply
follow the numbered steps for adding OnOK, except that you choose ID_CANCEL from
the top-right box and agree to call the function OnCancel. The code, as shown in
Listing 2.4, resets m_selected because the user canceled the dialog box.</P>
<P>
<H4>Listing 2.4  SDIDIALOG.CPP--CSdiDialog::OnCancel()</H4>
<PRE>void CSdiDialog::OnCancel()
{
m_selected = "";
CDialog::OnCancel();
</PRE>
<PRE>}
</PRE>
<P>Add these lines to CSdiApp::InitInstance() just before the call to AfxMessageBox():</P>
<P>
<PRE> msg += ". List Selection: ";
msg += dlg.m_selected;
</PRE>
<P>Build the application, run it, and test it. Does it work as you expect? Does it
resemble Figure 2.17?</P>
<P><A HREF="javascript:popUp('02uvc17.gif')"><B>FIG. 2.17</B></A><B> </B><I>Your
application now displays strings in the list box.</I></P>
<P><I></I>
<H3><A NAME="Heading10"></A>Using Radio Buttons</H3>
<P>You may have already noticed that when the dialog box first appears onscreen,
none of the radio buttons are selected. You can arrange for one of them to be selected
by default: Simply add two lines to CSdiDialog::OnInitDialog(). These lines set the
second radio button and save the change to the dialog box:</P>
<P>
<PRE>m_radio = 1;
UpdateData(FALSE);
</PRE>
<P>You may recall that m_radio is the member variable to which the group of radio
buttons is connected. It is a zero-based index into the group of buttons, indicating
which one is selected. Button 1 is the second button. 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 m_radio you just made.</P>
<P>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 CSdiApp::InitInstance(), add the lines
in Listing 2.5 just before the call to AfxMessageBox().</P>
<P>
<H4>Listing 2.5  SDIDIALOG.CPP--Lines to Add to CSdiApp::InitInstance()</H4>
<PRE> msg += "\r\n";
msg += "Radio Selection: ";
switch (dlg.m_radio)
{
case 0:
msg += "0";
break;
case 1:
msg += "1";
break;
case 2:
msg += "2";
break;
default:
msg += "none";
break;
</PRE>
<PRE> }
</PRE>
<P>The first new line adds two special characters to the message. <I>Return</I>,
represented by \r, and <I>new line</I>, 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 dlg.m_radio.</P>
<P>Once again, build and test the application. Any surprises? It should resemble
Figure 2.18. You are going to be building and using dialog boxes throughout this
book, so take the time to understand how this application works and what it does.
You may want to step through it with the debugger and watch it in action. You can
read all about debugging in Chapter 24, "Improving Your Application's Performance,"
and in Appendix D, "Debugging."</P>
<P><A HREF="javascript:popUp('02uvc18.gif')"><B>FIG. 2.18</B></A><B> </B><I>Your
application now selects Button Two by default.</I></P>
<H1></H1>
<CENTER>
<P>
<HR>
<A HREF="../ch01/ch01.htm"><IMG SRC="../button/previous.gif" WIDTH="128" HEIGHT="28"
ALIGN="BOTTOM" ALT="Previous chapter" BORDER="0"></A><A HREF="../ch03/ch03.htm"><IMG
SRC="../button/next.gif" WIDTH="128" HEIGHT="28" ALIGN="BOTTOM" ALT="Next chapter"
BORDER="0"></A><A HREF="../index.htm"><IMG SRC="../button/contents.gif" WIDTH="128"
HEIGHT="28" ALIGN="BOTTOM" ALT="Contents" BORDER="0"></A> <BR>
<BR>
</P>
<P>© <A HREF="../copy.htm">Copyright</A>, Macmillan Computer Publishing. All
rights reserved.
</CENTER>
</BODY>
</HTML>
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -