📄 ch12.htm
字号:
Cancel. The <U>B</U>ack button is disabled, because there is no previous page to go back to. The Cancel button enables the user to dismiss the wizard at any time, canceling whatever process the wizard was guiding the user through. The Next button causes
the next page in the wizard to be displayed.</P>
<P>You can change whatever is displayed in the edit control if you like. However, the magic really starts when you click the Next button, which displays Page 2 of the wizard, as shown in Figure 12.19. Page 2 contains a check box and the <U>B</U>ack, Next,
and Cancel buttons. Now, the <U>B</U>ack button is enabled, so that you can return to Page 1 if you want to. Go ahead and click the <U>B</U>ack button. The wizard tells you that the check box must be checked, as shown in Figure 12.20. As you'll soon see,
this feature of a wizard enables you to verify the contents of a specific page before allowing the user to advance to another step.</P>
<A HREF="Nfigs19.gif" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/figs/ch12/Nfigs19.gif"><b>Fig. 12.19</b></A>
<P><I>In Page 2 of the wizard, the </I><I><U>B</U></I><I>ack button is enabled.</I></P>
<A HREF="Nfigs20.gif" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/figs/ch12/Nfigs20.gif"><b>Fig. 12.20</b></A>
<P><I>You must select the check box before the wizard will let you leave Page </I><I>2.</I></P>
<P>After checking the check box, you can click the Back button to move back to Page 1 or click the Next button to advance to Page 3. Assuming you advance to Page 3, you see the display shown in Figure 12.21. Here, the Next button has changed to the Finish
button, because you are on the wizard's last page. If you click the Finish button, the wizard disappears.</P>
<A HREF="Nfigs21.gif" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/figs/ch12/Nfigs21.gif"><b>Fig. 12.21</b></A>
<P><I>This is the last page of the Wizard Demo Application's wizard.</I></P>
<P><B>Creating Wizard Pages</B></P>
<P>As far as your application's resources go, you create wizard pages exactly as you create property sheet pages; by creating dialog boxes and changing the dialog box styles. (The dialog titles—Page 1 of 3, Page 2 of 3, and Page 3 of 3—are
hardcoded onto each dialog box. You associate each dialog box resource with an object of the <font color="#008000">CPropertyPage</font> class. Then, in order to take control of the pages in your wizard and keep track of what the user is doing with the
wizard, you override the <font color="#008000">OnSetActive()</font>, <font color="#008000">OnWizardBack()</font>, <font color="#008000">OnWizardNext()</font>, and <font color="#008000">OnWizardFinish() </font><font color="#008000">functions of</font> your
property page classes. Read on to see how to do this.</P>
<P><B>Displaying a Wizard</B></P>
<P>The File, Wizard command is caught by CWizView's OnFileWizard() function. It is very similar to the OnPropSheet function in the Property Sheet demo, as you can see from Listing 12.4. The first difference is the call to <font
color="#008000">SetWizardMode()</font> before the call to <font color="#008000">DoModal()</font>. This function call tells MFC that it should display the property sheet as a wizard rather than as a conventional property sheet. The only other difference is
that the user arranges for property sheet changes to be accepted by clicking Finish, not OK, so this code checks for <font color="#008000">ID_WIZFINISH </font>rather than <font color="#008000">IDOK</font> as a return from <font
color="#008000">DoModal()</font>.</P>
<P><I>Listing 12.4 CWizView::OnFileWizard()</I></P>
<pre><font color="#008000">void CWizView::OnFileWizard() </font></pre>
<pre><font color="#008000">{</font></pre>
<pre><font color="#008000"> CWizSheet wizSheet("Sample Wizard", this, 0);</font></pre>
<pre><font color="#008000"> wizSheet.m_page1.m_edit = m_edit;</font></pre>
<pre><font color="#008000"> wizSheet.m_page2.m_check = m_check;</font></pre>
<pre><font color="#008000"> wizSheet.SetWizardMode();</font></pre>
<pre><font color="#008000"> int result = wizSheet.DoModal();</font></pre>
<pre><font color="#008000"> if (result == ID_WIZFINISH)</font></pre>
<pre><font color="#008000"> {</font></pre>
<pre><font color="#008000"> m_edit = wizSheet.m_page1.m_edit;</font></pre>
<pre><font color="#008000"> m_check = wizSheet.m_page2.m_check;</font></pre>
<pre><font color="#008000"> Invalidate();</font></pre>
<pre><font color="#008000"> }</font></pre>
<pre><font color="#008000">}</font></pre>
<P><B>Setting the Wizard's Buttons</B></P>
<P>MFC automatically calls the <font color="#008000">OnSetActive()</font> member function immediately upon displaying a specific page of the wizard. So, when the program displays Page 1 of the wizard, the <font color="#008000">CPage1</font> class's <font
color="#008000">OnSetActive()</font> function gets called. You add code to this function that makes the wizard behave as you wish. <font color="#008000">CPage1::OnSetActive()</font> looks like Listing 12.5.</P>
<P><I>Listing 12.5— CPage1::OnSetActive()</I></P>
<pre><font color="#008000">BOOL CPage1::OnSetActive() </font></pre>
<pre><font color="#008000">{</font></pre>
<pre><font color="#008000"> CPropertySheet* parent = (CPropertySheet*)GetParent();</font></pre>
<pre><font color="#008000"> parent->SetWizardButtons(PSWIZB_NEXT);</font></pre>
<pre><font color="#008000"> return CPropertyPage::OnSetActive();</font></pre>
<pre><font color="#008000">}</font></pre>
<p><font color="#008000">OnSetActive()</font> first gets a pointer to the wizard's property sheet window, which is the page's parent window. Then the program calls the wizard's <font color="#008000">SetWizardButtons()</font> function, which determines the
state of the wizard's buttons. <font color="#008000">SetWizardButtons()</font> takes a single argument, which is a set of flags indicating how the page should display its buttons. These flags are <font color="#008000">PSWIZB_BACK</font>, <font
color="#008000">PSWIZB_NEXT</font>, <font color="#008000">PSWIZB_FINISH</font>, and <font color="#008000">PSWIZB_DISABLEDFINISH</font>. Because the call to <font color="#008000">SetWizardButtons()</font> in Listing 12.4 includes only the <font
color="#008000">PSWIZB_NEXT</font> flag, only the Next button in the page will be enabled.</P>
<P>Because the <font color="#008000">CPage2</font> class represents Page 2 of the wizard, its call to <font color="#008000">SetWizardButtons()</font> enables both the Back and Next buttons, by combining the appropriate flags with the bitwise <I>or</I>
operator (<font color="#008000">|</font>), like this:</P>
<pre><font color="#008000">parent->SetWizardButtons(PSWIZB_BACK | PSWIZB_NEXT);</font></pre>
<P>Because Page 3 of the wizard is the last page, the <font color="#008000">CPage3</font> class calls <font color="#008000">SetWizardButtons()</font> like this:</P>
<pre><font color="#008000">parent->SetWizardButtons(PSWIZB_BACK | PSWIZB_FINISH);</font></pre>
<P>This set of flags enables the Back button and provides a Finish button instead of a Next button.</P>
<P><B>Responding to the Wizard's Buttons</B></P>
<P>In the simplest case, MFC takes care of everything that needs to be done in order to flip from one wizard page to the next. That is, when the user clicks a button, MFC springs into action and performs the Back, Next, Finish, or Cancel command. However,
you'll often want to perform some action of your own when the user clicks a button. For example, you may want to verify that the information that the user entered into the currently displayed page is correct. If there's a problem with the data, you can
force the user to fix it before moving on.</P>
<P>To respond to the wizard's buttons, you override the <font color="#008000">OnWizardBack()</font>, <font color="#008000">OnWizardNext()</font>, and <font color="#008000">OnWizardFinish()</font> member functions. Use the Message Maps tab of ClassWizard
to do this: you will find the names of these functions in the Messages window when a property page class is selected in the Class name box. When the user clicks a wizard button, MFC calls the matching function in which you can do whatever is needed to
process that page. An example is the way the wizard in the Wizard Demo application won't let you leave Page 2 until you've checked the check box. This is accomplished by overriding the functions shown in Listing 12.6.</P>
<P><I>Listing 12.6 Responding to Wizard Buttons</I></P>
<pre><font color="#008000">LRESULT CPage2::OnWizardBack() </font></pre>
<pre><font color="#008000">{</font></pre>
<pre><font color="#008000"> CButton *checkBox = (CButton*)GetDlgItem(IDC_CHECK1);</font></pre>
<pre><font color="#008000"> if (!checkBox->GetCheck())</font></pre>
<pre><font color="#008000"> {</font></pre>
<pre><font color="#008000"> MessageBox("You must check the box.");</font></pre>
<pre><font color="#008000"> return -1;</font></pre>
<pre><font color="#008000"> }</font></pre>
<pre><font color="#008000"> return CPropertyPage::OnWizardBack();</font></pre>
<pre><font color="#008000">}</font></pre>
<pre><font color="#008000">LRESULT CPage2::OnWizardNext() </font></pre>
<pre><font color="#008000">{</font></pre>
<pre><font color="#008000"> UpdateData();</font></pre>
<pre><font color="#008000"> if (!m_check)</font></pre>
<pre><font color="#008000"> {</font></pre>
<pre><font color="#008000"> MessageBox("You must check the box.");</font></pre>
<pre><font color="#008000"> return -1;</font></pre>
<pre><font color="#008000"> }</font></pre>
<pre><font color="#008000"> return CPropertyPage::OnWizardNext();</font></pre>
<pre><font color="#008000">}</font></pre>
<P>These functions demonstrate two ways to examine the check box on Page 2. <font color="#008000">OnWizardBack()</font> gets a pointer to the page's check box by calling the <font color="#008000">GetDlgItem()</font> function. With the pointer in hand, the
program can call the check-box class's <font color="#008000">GetCheck()</font> function, which returns a 1 if the check box is checked. <font color="#008000">OnWizardNext()</font> calls <font color="#008000">UpdateData()</font> to fill all the CPage2
member variables with values from the dialog box controls, then looks at m_check. In both functions, if the box is not checked, the program displays a message box and returns -1 from the function. Returning -1 tells MFC to ignore the button click and not
change pages. As you can see, it is simple to arrange for different conditions to leave the page in the <font color="#008000">Back</font> or <font color="#008000">Next</font> directions.</P>
<H3><B>From Here...</B></H3>
<P>Whether you're creating property sheets or wizards, Visual C++'s many classes enable you to get the job done easily. Property sheets are great for organizing many options and controls, whereas wizards (which are a special type of property sheet) are
best used for guiding the user step-by-step through a complex task. To learn more about related topics, check out the following chapters:</P>
<ul>
<li> <A HREF="index01.htm" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/index01.htm" target="text">Chapter 1</A>, "Building Your First Application," tells you what you need to know to create your own projects using Visual C++'s development tools.</P>
<li> <A HREF="index02.htm" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/index02.htm" target="text">Chapter 2</A>, " Dialog Boxes and Controls," gives you background in programming dialog boxes and the controls they can contain.</P>
<li> <A HREF="index04.htm" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/index04.htm" target="text">Chapter 4</A>, "Messages and Commands," describes MFC's message-mapping system, which enables you to respond to Windows messages.</P>
<li> <A HREF="index06.htm" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/index06.htm" target="text">Chapter 6</A>, "Drawing on the Screen," describes how to display information in a window.</P>
</ul>
<p><hr></p>
<center>
<p><font size=-2>
© 1997, QUE Corporation, an imprint of Macmillan Publishing USA, a
Simon and Schuster Company.</font></p>
</center>
</BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -