📄 ch16.htm
字号:
the OnDraw function in the view class. In this function, you need to get a pointer
to the drawing object and then call its Draw function, as in Listing 16.14.</P>
<P>
<H4>LISTING 16.14. THE CTestAppView OnDraw FUNCTION.</H4>
<PRE>1: void CTestAppView::OnDraw(CDC* pDC)
2: {</PRE>
<PRE>3: CModTestAppDoc* pDoc = GetDocument();
4: ASSERT_VALID(pDoc);
5:
6: // TODO: add draw code for native data here
7:
8: // Get the drawing object
9: CModArt* m_maDrawing = pDoc->GetDrawing();
10: // Draw the drawing
11: m_maDrawing->Draw(pDC);
12: }
</PRE>
<P>Once you add all this functionality, you can compile and run your application
to test the functionality of your library module. Each time you select File | New
from your application menu, a new drawing is created, as in Figure 16.5.</P>
<P><A HREF="javascript:popUp('16fig05.gif')"><B>FIGURE 16.5.</B></A><B> </B><I>Creating
random squiggle drawings.</I></P>
<P><I></I>
<H3><A NAME="Heading10"></A>Updating the Library Module</H3>
<P>Now that you have a working application, let's go back to the library module and
make some changes. Whenever you make any changes to the library module code, no matter
how minor, you need to relink all applications that use the module in order to get
the updates into those applications. This is because the library module is linked
into the EXE of the application. It does not remain in a separate file.</P>
<P>To see how this works, reopen the library module project. You will make three
changes to this module. First, you'll increase the number of squiggles that may be
included in a single drawing. Second, you'll increase the number of line segments
that may make up a single squiggle. Third, you'll generate random colors, beyond
just the eight colors included in the color table. Once you make these changes, you'll
recompile your library module. Once you generate a new module, you'll relink your
test application so that you can incorporate these changes into the application.</P>
<P>To make the first change in your module, increasing the number of squiggles that
can be in a drawing, edit the NewDrawing function in the drawing class, increasing
the modulus value in line 7 of the function, as in Listing 16.15. This will increase
the number of possible squiggles in a single drawing from a maximum of 10 to a maximum
of 50. There may still be an occasional drawing that doesn't have any squiggles,
but you can ignore this possibility for now.</P>
<P>
<H4>LISTING 16.15. THE MODIFIED CModArt NewDrawing FUNCTION.</H4>
<PRE>1: void CModArt::NewDrawing()
2: {
3: int lNumLines;
4: int lCurLine;
5:
6: // Determine how many lines to create
7: lNumLines = rand() % 50;
8: // Are there any lines to create?
9: if (lNumLines > 0)
10: {
11: // Loop through the number of lines
12: for (lCurLine = 0; lCurLine < lNumLines; lCurLine++)
13: {
14: // Create the new line
15: NewLine();
16: }
17: }
18: }
</PRE>
<P>With the increased number of squiggles that can be included in a drawing, next
you want to increase the number of line segments that may be in a squiggle. To do
this, edit the NewLine function and increase the modulus number on line 20 in Listing
16.16 from 100 to 200. While you're in this function, you can also increase the number
of colors that may be generated for use in each drawing. First, add three integer
variable declarations, one for each of the three additive colors (red, green, and
blue, as in lines 9 through 11 in Listing 16.16). Next, generate random values for
each of these integers between the values of 0 and 255 (lines 26 through 28). Finally,
when creating the CLine object, pass these colors through the RGB function to create
the actual color that will be used in the drawing, as in line 41 of Listing 16.16.</P>
<P>
<H4>LISTING 16.16. THE MODIFIED CModArt NewLine FUNCTION.</H4>
<PRE>1: void CModArt::NewLine()
2: {
3: int lNumLines;
4: int lCurLine;
5: // int nCurColor;
6: UINT nCurWidth;
7: CPoint pTo;
8: CPoint pFrom;
9: int cRed;
10: int cBlue;
11: int cGreen;
12:
13: // Normalize the rectangle before determining the width and height
14: m_rDrawArea.NormalizeRect();
15: // get the area width and height
16: int lWidth = m_rDrawArea.Width();
17: int lHeight = m_rDrawArea.Height();
18:
19: // Determine the number of parts to this squiggle
20: lNumLines = rand() % 200;
21: // Are there any parts to this squiggle?
22: if (lNumLines > 0)
23: {
24: // Determine the color
25: // nCurColor = rand() % 8;
26: cRed = rand() % 256;
27: cBlue = rand() % 256;
28: cGreen = rand() % 256;
29: // Determine the pen width
30: nCurWidth = (rand() % 8) + 1;
31: // Determine the starting point for the squiggle
32: pFrom.x = (rand() % lWidth) + m_rDrawArea.left;
33: pFrom.y = (rand() % lHeight) + m_rDrawArea.top;
34: // Loop through the number of segments
35: for (lCurLine = 0; lCurLine < lNumLines; lCurLine++)
36: {
37: // Determine the end point of the segment
38: pTo.x = ((rand() % 20) - 10) + pFrom.x;
39: pTo.y = ((rand() % 20) - 10) + pFrom.y;
40: // Create a new CLine object
41: CLine *pLine = new CLine(pFrom, pTo, nCurWidth,
ÂRGB(cRed, cGreen, cBlue));
42: try
43: {
44: // Add the new line to the object array
45: m_oaLines.Add(pLine);
46: }
47: // Did we run into a memory exception?
48: catch (CMemoryException* perr)
49: {
50: // Display a message for the user, giving him the
51: // bad news
52: AfxMessageBox("Out of memory", MB_ICONSTOP | MB_OK);
53: // Did we create a line object?
54: if (pLine)
55: {
56: // Delete it
57: delete pLine;
58: pLine = NULL;
59: }
60: // Delete the exception object
61: perr->Delete();
62: }
63: // Set the starting point to the end point
64: pFrom = pTo;
65: }
66: }
67: }
</PRE>
<P>Now that you've made all the necessary changes to the library module, compile
it so that it's ready for use in the test application. If you run your test application
from the Start | Run Taskbar option, as in Figure 16.6, you'll notice that there
is no noticeable difference in how your application behaves. This is because the
application hasn't changed. The application is still using the old version of your
library module. To get the test application to use the new version of the library
module, reopen the test application project in Visual C++. Build the project, which
should not do anything other than relink the project, and then run the application.
You should see a significant difference in the drawings that your application is
now generating, as shown in Figure 16.7.</P>
<P><A HREF="javascript:popUp('16fig06.gif')"><B>FIGURE 16.6.</B></A><B> </B><I>Run
the test application from the Start menu.</I></P>
<P><A HREF="javascript:popUp('16fig07.gif')"><B>FIGURE 16.7.</B></A><B> </B><I>The
updated test application.</I></P>
<P><I></I>
<H2><A NAME="Heading11"></A>Summary</H2>
<P>Today you learned about how to approach creating and designing new classes for
your applications. You learned the differences between the different types of classes
that are available to you through the New Class Wizard in Visual C++. You also learned
how you can create a library module with a set of your functionality that you can
hand to other programmers for including in their applications. You learned how this
module will be linked into the actual applications, thus not requiring a separate
file to be distributed along with the applications.</P>
<P>Tomorrow you will learn about a different approach to creating reusable packaged
functionality that you can give to other programmers. You will learn how to create
DLLs using Visual C++, what the differences are between creating library modules
and DLL, and how you need to approach each task.</P>
<P>
<H2><A NAME="Heading12"></A>Q&A</H2>
<DL>
<DT></DT>
<DD><B>Q Isn't most functionality packaged in DLLs now? Why would I want to create
library modules instead of DLLs?</B>
<P>
<DT><B></B></DT>
<DD><B>A</B> Yes, the trend toward packaging functionality modules has been to create
DLLs instead of library modules for a number of years now. However, there are still
instances where library modules are preferable. If you are creating a module that
contains proprietary functionality that you do not want to risk exposing to others,
but that is needed for any applications that you or another programmer in your company
is building, then you would probably want all that functionality packaged in a library
module so that it is internal to the application. Using library modules makes it
effectively inaccessible to your competition without significant disassembly and
reverse engineering efforts.
<P>
<DT></DT>
<DD><B>Q Why does the header file need to be included in the application that is
using my library file?</B>
<P>
<DT><B></B></DT>
<DD><B>A</B> The application needs to know about the objects that are in the library
file. In the sample application, you didn't need to include the header file for the
CLine class because the application didn't directly use or reference the CLine class.
However, the application did use the drawing object that was in your library module,
so it did need to know about that object, how it is defined, and what functions are
available for it. If you don't want the other programmers to know all of the internal
structure of your classes, then you can create another header file to be distributed
with your library module. This header would contain definitions of all of the same
classes that are in the library module but would only provide the public functions
and variables that the other programmers can actually access.
<P>
</DL>
<H2><A NAME="Heading13"></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="Heading14"></A>Quiz</H3>
<DL>
<DT></DT>
<DD><B>1. </B>When do you want to create a new MFC class?
<P>
<DT></DT>
<DD><B>2. </B>When you make changes to a library file, what do you have to do to
the applications that use the library file?
<P>
<DT></DT>
<DD><B>3. </B>What are the different types of classes that you can create?
<P>
<DT></DT>
<DD><B>4. </B>When you package some functionality in a library file, what do you
need to give to other programmers who want to use your library module?
<P>
<DT></DT>
<DD><B>5. </B>What are two of the basic principles in object-oriented software design?
<P>
</DL>
<H3><A NAME="Heading15"></A>Exercise</H3>
<P>Separate the CLine class into a different library module from the drawing class
so that you have two library modules instead of one. Link them into the test application.</P>
<H1></H1>
<CENTER>
<P>
<HR>
<A HREF="../ch15/ch15.htm"><IMG SRC="../button/previous.gif" WIDTH="128" HEIGHT="28"
ALIGN="BOTTOM" ALT="Previous chapter" BORDER="0"></A><A HREF="../ch17/ch17.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>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -