📄 ch10.htm
字号:
Color menu as designed.</I></P>
<P>
<H4>TABLE 10.2. MENU PROPERTY SETTINGS.</H4>
<P>
<TABLE BORDER="1">
<TR ALIGN="LEFT" VALIGN="TOP">
<TD ALIGN="LEFT"><I>Object</I></TD>
<TD ALIGN="LEFT"><I>Property</I></TD>
<TD ALIGN="LEFT"><I>Setting</I></TD>
</TR>
<TR ALIGN="LEFT" VALIGN="TOP">
<TD ALIGN="LEFT">Menu Entry</TD>
<TD ALIGN="LEFT">ID</TD>
<TD ALIGN="LEFT">ID_COLOR_BLACK</TD>
</TR>
<TR ALIGN="LEFT" VALIGN="TOP">
<TD ALIGN="LEFT"></TD>
<TD ALIGN="LEFT">Caption</TD>
<TD ALIGN="LEFT">&Black</TD>
</TR>
<TR ALIGN="LEFT" VALIGN="TOP">
<TD ALIGN="LEFT">Menu Entry</TD>
<TD ALIGN="LEFT">ID</TD>
<TD ALIGN="LEFT">ID_COLOR_BLUE</TD>
</TR>
<TR ALIGN="LEFT" VALIGN="TOP">
<TD ALIGN="LEFT"></TD>
<TD ALIGN="LEFT">Caption</TD>
<TD ALIGN="LEFT">B&lue</TD>
</TR>
<TR ALIGN="LEFT" VALIGN="TOP">
<TD ALIGN="LEFT">Menu Entry</TD>
<TD ALIGN="LEFT">ID</TD>
<TD ALIGN="LEFT">ID_COLOR_GREEN</TD>
</TR>
<TR ALIGN="LEFT" VALIGN="TOP">
<TD ALIGN="LEFT"></TD>
<TD ALIGN="LEFT">Caption</TD>
<TD ALIGN="LEFT">&Green</TD>
</TR>
<TR ALIGN="LEFT" VALIGN="TOP">
<TD ALIGN="LEFT">Menu Entry</TD>
<TD ALIGN="LEFT">ID</TD>
<TD ALIGN="LEFT">ID_COLOR_CYAN</TD>
</TR>
<TR ALIGN="LEFT" VALIGN="TOP">
<TD ALIGN="LEFT"></TD>
<TD ALIGN="LEFT">Caption</TD>
<TD ALIGN="LEFT">&Cyan</TD>
</TR>
<TR ALIGN="LEFT" VALIGN="TOP">
<TD ALIGN="LEFT">Menu Entry</TD>
<TD ALIGN="LEFT">ID</TD>
<TD ALIGN="LEFT">ID_COLOR_RED</TD>
</TR>
<TR ALIGN="LEFT" VALIGN="TOP">
<TD ALIGN="LEFT"></TD>
<TD ALIGN="LEFT">Caption</TD>
<TD ALIGN="LEFT">&Red</TD>
</TR>
<TR ALIGN="LEFT" VALIGN="TOP">
<TD ALIGN="LEFT">Menu Entry</TD>
<TD ALIGN="LEFT">ID</TD>
<TD ALIGN="LEFT">ID_COLOR_MAGENTA</TD>
</TR>
<TR ALIGN="LEFT" VALIGN="TOP">
<TD ALIGN="LEFT"></TD>
<TD ALIGN="LEFT">Caption</TD>
<TD ALIGN="LEFT">&Magenta</TD>
</TR>
<TR ALIGN="LEFT" VALIGN="TOP">
<TD ALIGN="LEFT">Menu Entry</TD>
<TD ALIGN="LEFT">ID</TD>
<TD ALIGN="LEFT">ID_COLOR_YELLOW</TD>
</TR>
<TR ALIGN="LEFT" VALIGN="TOP">
<TD ALIGN="LEFT"></TD>
<TD ALIGN="LEFT">Caption</TD>
<TD ALIGN="LEFT">&Yellow</TD>
</TR>
<TR ALIGN="LEFT" VALIGN="TOP">
<TD ALIGN="LEFT">Menu Entry</TD>
<TD ALIGN="LEFT">ID</TD>
<TD ALIGN="LEFT">ID_COLOR_WHITE</TD>
</TR>
<TR ALIGN="LEFT" VALIGN="TOP">
<TD ALIGN="LEFT"></TD>
<TD ALIGN="LEFT">Caption</TD>
<TD ALIGN="LEFT">&White</TD>
</TR>
</TABLE>
</P>
<DL>
<DT></DT>
<DD><B>5. </B>Open the Class Wizard. Select the CDay10Doc in the Class Name combo
box.
<P>
<DT></DT>
<DD><B>6. </B>Add functions for both the COMMAND and UPDATE_COMMAND_UI event messages
for all the color menu entries.
<P>
<DT></DT>
<DD><B>7. </B>After the final menu entry function has been added, click Edit Code.
<P>
<DT></DT>
<DD><B>8. </B>Edit the Black menu functions as in Listing 10.21.
<P>
</DL>
<H4>LISTING 10.21. THE BLACK MENU FUNCTIONS.</H4>
<PRE> 1: void CDay10Doc::OnColorBlack()
2: {
3: // TODO: Add your command handler code here
4:
5: ///////////////////////
6: // MY CODE STARTS HERE
7: ///////////////////////
8:
9: // Set the current color to black
10: m_nColor = ID_COLOR_BLACK - ID_COLOR_BLACK;
11:
12: ///////////////////////
13: // MY CODE ENDS HERE
14: ///////////////////////
15: }
16:
17: void CDay10Doc::OnUpdateColorBlack(CCmdUI* pCmdUI)
18: {
19: // TODO: Add your command update UI handler code here
20:
21: ///////////////////////
22: // MY CODE STARTS HERE
23: ///////////////////////
24:
</PRE>
<PRE>25: // Determine if the Black menu entry should be checked
</PRE>
<PRE>26: pCmdUI->SetCheck(GetColor() == ID_COLOR_BLACK ? 1 : 0);
27:
28: ///////////////////////
29: // MY CODE ENDS HERE
30: ///////////////////////
31: }
</PRE>
<DL>
<DT></DT>
<DD><B>9. </B>Edit the Blue menu functions as in Listing 10.22. Edit the remaining
menu functions in the same way, substituting their menu IDs for ID_COLOR_BLUE.
<P>
</DL>
<H4>LISTING 10.22. THE BLUE MENU FUNCTIONS.</H4>
<PRE> 1: void CDay10Doc::OnColorBlue()
2: {
3: // TODO: Add your command handler code here
4:
5: ///////////////////////
6: // MY CODE STARTS HERE
7: ///////////////////////
8:
9: // Set the current color to blue
10: m_nColor = ID_COLOR_BLUE - ID_COLOR_BLACK;
11:
12: ///////////////////////
13: // MY CODE ENDS HERE
14: ///////////////////////
15: }
16:
17: void CDay10Doc::OnUpdateColorBlue(CCmdUI* pCmdUI)
18: {
19: // TODO: Add your command update UI handler code here
20:
21: ///////////////////////
22: // MY CODE STARTS HERE
23: ///////////////////////
24:
25: // Determine if the Blue menu entry should be checked
26: pCmdUI->SetCheck(GetColor() == ID_COLOR_BLUE ? 1 : 0);
27:
28: ///////////////////////
29: // MY CODE ENDS HERE
30: ///////////////////////
31: }
</PRE>
<P>In the first of the two menu functions, the COMMAND function, the current color
variable is set to the new color. If you add the menu entries in the correct order,
their ID numbers are sequential, starting with ID_COLOR_BLACK. Subtracting ID_COLOR_BLACK
from the menu ID should always result in the correct position in the color table
for the selected color. For example, the Black color is position 0 in the color table.
ID_COLOR_BLACK - ID_COLOR_BLACK = 0. Blue is position 1 in the color table. Because
ID_COLOR_BLUE should be one greater than ID_COLOR_BLACK, ID_COLOR_BLUE -- ID_COLOR_BLACK
= 1.</P>
<P>The second function, the UPDATE_COMMAND_UI function, may need a little explaining.
The UPDATE_COMMAND_UI event is called for each menu entry just before it is displayed.
You can use this event message function to check or uncheck the menu entry, based
on whether it is the current color. You can also use this event to enable or disable
menu entries or make other modifications as necessary. The code in this function</P>
<P>
<PRE>pCmdUI->SetCheck(GetColor() == ID_COLOR_BLUE ? 1 : 0);
</PRE>
<P>does several things. First, the pCmdUI object that is passed in as the only argument
is a pointer to a menu object. The SetCheck function can check or uncheck the menu
entry, depending on whether the argument passed is 1 or 0 (1 checks, 0 unchecks).
The argument portion for the SetCheck function is a flow-control construct that can
be somewhat confusing if you haven't spent a large amount of time programming in
C/C++. The first half</P>
<P>
<PRE>GetColor() == ID_COLOR_BLUE
</PRE>
<P>is a simple boolean conditional statement. It results in a true or false result.
The portion following this conditional statement</P>
<P>
<PRE>? 1 : 0
</PRE>
<P>is basically an if...else statement in shorthand. If the conditional statement
is true, then the value is 1, and if the statement is false, the value is 0. This
is a fancy way of placing an if..else flow control within the argument to another
function.</P>
<P>If you compile and run your application, you should be able to change the color
that you are drawing with. When you pull down the color menu, you should see the
current drawing color checked on the menu, as in Figure 10.8.</P>
<P><A HREF="javascript:popUp('10fig12.gif')"><B>FIGURE 10.8.</B></A><B> </B><I>Specifying
the current color on the menu.</I></P>
<P>
<H2><A NAME="Heading14"></A>Summary</H2>
<P>Whew! What a day! You learned quite a bit today because this was a packed chapter.
You initially learned about the SDI style application and about a couple of standard
applications that you have probably used that are SDI applications. You next learned
about the Document/View architecture that Visual C++ uses for SDI applications. You
learned to create a simple class of your own for use in your drawing application.
You created a drawing application that can maintain the images drawn using it. You
learned how you can save and restore documents in the Document/View architecture.
You also learned about the CObArray object array class and how you can use it to
create a dynamic object array for storing various classes. Finally, you learned how
you can check and uncheck menu entries in MFC applications.</P>
<P>
<H2><A NAME="Heading15"></A>Q&A</H2>
<DL>
<DT></DT>
<DD><B>Q Is there any way that you can reduce the number of COMMAND and UPDATE_ COMMAND_UI
functions for the menus?</B>
<P>
<DT></DT>
<DD><B>A</B> Yes, you can send all the color COMMAND events to the same function.
From there, you can examine the nID value (which is passed as an argument) and compare
it to the menu IDs to determine which menu is calling the function. As a result,
you can write the COMMAND function for the color menus as follows:
<P>
</DL>
<PRE>void CDay10Doc::OnColorCommand(UINT nID)
{
// TODO: Add your command handler code here
///////////////////////
// MY CODE STARTS HERE
///////////////////////
// Set the current color to blue
m_nColor = nID - ID_COLOR_BLACK;
///////////////////////
// MY CODE ENDS HERE
///////////////////////
}
</PRE>
<DL>
<DT></DT>
<DD>For the UPDATE_COMMAND_UI functions, you can do the same thing, only slightly
differently. In this case, you can examine the pCmdUI->m_nID value to determine
which menu the function is being called for. This makes the UPDATE_COMMAND_UI function
look like the following:
<P>
</DL>
<PRE>void CDay10Doc::OnUpdateColor(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
///////////////////////
// MY CODE STARTS HERE
///////////////////////
// Determine if the Blue menu entry should be checked
pCmdUI->SetCheck(GetColor() == pCmdUI->m_nID ? 1 : 0);
///////////////////////
// MY CODE ENDS HERE
///////////////////////
}
</PRE>
<DL>
<DT></DT>
<DD><B>Q What's the difference between SDI and MDI applications?</B>
<P>
<DT></DT>
<DD><B>A</B> Although SDI applications can perform only one task, MDI (Multiple Document
Interface) applications can have multiple documents open at the same time. Plus,
in an MDI application, not all document types need be the same. You'll learn more
about MDI applications tomorrow.
<P>
</DL>
<H2><A NAME="Heading16"></A>Workshop</H2>
<P>The Workshop provides quiz questions to help you solidify your understanding of
the material covered and exercises to provide you with experience in using what you've
learned. The answers to the quiz questions and exercises are provided in Appendix
B, "Answers."</P>
<P>
<H3><A NAME="Heading17"></A>Quiz</H3>
<DL>
<DT></DT>
<DD><B>1. </B>What does SDI stand for?
<P>
<DT></DT>
<DD><B>2. </B>What functionality is in the view class?
<P>
<DT></DT>
<DD><B>3. </B>What function is called to redraw the document if the window has been
hidden behind another window?
<P>
<DT></DT>
<DD><B>4. </B>Where do you place code to clear out the current document before starting
a new document?
<P>
<DT></DT>
<DD><B>5. </B>What is the purpose of the document class?
<P>
</DL>
<H3><A NAME="Heading18"></A>Exercise</H3>
<P>Add another pull-down menu to control the width of the pen used for drawing. Give
it the following settings:</P>
<P>
<TABLE BORDER="1">
<TR ALIGN="LEFT" VALIGN="TOP">
<TD ALIGN="LEFT"><I>Menu Entry</I></TD>
<TD ALIGN="LEFT"><I>Width Setting</I></TD>
</TR>
<TR ALIGN="LEFT" VALIGN="TOP">
<TD ALIGN="LEFT">Very Thin</TD>
<TD ALIGN="LEFT">1</TD>
</TR>
<TR ALIGN="LEFT" VALIGN="TOP">
<TD ALIGN="LEFT">Thin</TD>
<TD ALIGN="LEFT">8</TD>
</TR>
<TR ALIGN="LEFT" VALIGN="TOP">
<TD ALIGN="LEFT">Medium</TD>
<TD ALIGN="LEFT">16</TD>
</TR>
<TR ALIGN="LEFT" VALIGN="TOP">
<TD ALIGN="LEFT">Thick</TD>
<TD ALIGN="LEFT">24</TD>
</TR>
<TR ALIGN="LEFT" VALIGN="TOP">
<TD ALIGN="LEFT">Very Thick</TD>
<TD ALIGN="LEFT">32</TD>
</TR>
</TABLE>
<BLOCKQUOTE>
<P>
<HR>
<STRONG>TIP:</STRONG> In the pen constructor, the second argument is the width.
<HR>
</P>
</BLOCKQUOTE>
<CENTER>
<P>
<HR>
<A HREF="../ch09/ch09.htm"><IMG SRC="../button/previous.gif" WIDTH="128" HEIGHT="28"
ALIGN="BOTTOM" ALT="Previous chapter" BORDER="0"></A><A HREF="../ch11/ch11.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></P>
<P>© <A HREF="../copy.htm">Copyright</A>, Macmillan Computer Publishing. All
rights reserved.
</CENTER>
</BODY>
</HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -