📄 ch16.htm
字号:
the OnDraw function in the view class. In this function, you need to get a pointerto 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 here7:8: // Get the drawing object9: CModArt* m_maDrawing = pDoc->GetDrawing();10: // Draw the drawing11: m_maDrawing->Draw(pDC);12: }</PRE><P>Once you add all this functionality, you can compile and run your applicationto test the functionality of your library module. Each time you select File | Newfrom 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>Creatingrandom 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 andmake some changes. Whenever you make any changes to the library module code, no matterhow minor, you need to relink all applications that use the module in order to getthe updates into those applications. This is because the library module is linkedinto 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 threechanges to this module. First, you'll increase the number of squiggles that may beincluded in a single drawing. Second, you'll increase the number of line segmentsthat may make up a single squiggle. Third, you'll generate random colors, beyondjust the eight colors included in the color table. Once you make these changes, you'llrecompile your library module. Once you generate a new module, you'll relink yourtest 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 thatcan be in a drawing, edit the NewDrawing function in the drawing class, increasingthe modulus value in line 7 of the function, as in Listing 16.15. This will increasethe number of possible squiggles in a single drawing from a maximum of 10 to a maximumof 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 create7: lNumLines = rand() % 50;8: // Are there any lines to create?9: if (lNumLines > 0)10: {11: // Loop through the number of lines12: for (lCurLine = 0; lCurLine < lNumLines; lCurLine++)13: {14: // Create the new line15: NewLine();16: }17: }18: }</PRE><P>With the increased number of squiggles that can be included in a drawing, nextyou want to increase the number of line segments that may be in a squiggle. To dothis, edit the NewLine function and increase the modulus number on line 20 in Listing16.16 from 100 to 200. While you're in this function, you can also increase the numberof colors that may be generated for use in each drawing. First, add three integervariable declarations, one for each of the three additive colors (red, green, andblue, as in lines 9 through 11 in Listing 16.16). Next, generate random values foreach 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 createthe 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 height14: m_rDrawArea.NormalizeRect();15: // get the area width and height16: int lWidth = m_rDrawArea.Width();17: int lHeight = m_rDrawArea.Height();18:19: // Determine the number of parts to this squiggle20: lNumLines = rand() % 200;21: // Are there any parts to this squiggle?22: if (lNumLines > 0)23: {24: // Determine the color25: // nCurColor = rand() % 8;26: cRed = rand() % 256;27: cBlue = rand() % 256;28: cGreen = rand() % 256;29: // Determine the pen width30: nCurWidth = (rand() % 8) + 1;31: // Determine the starting point for the squiggle32: pFrom.x = (rand() % lWidth) + m_rDrawArea.left;33: pFrom.y = (rand() % lHeight) + m_rDrawArea.top;34: // Loop through the number of segments35: for (lCurLine = 0; lCurLine < lNumLines; lCurLine++)36: {37: // Determine the end point of the segment38: pTo.x = ((rand() % 20) - 10) + pFrom.x;39: pTo.y = ((rand() % 20) - 10) + pFrom.y;40: // Create a new CLine object41: CLine *pLine = new CLine(pFrom, pTo, nCurWidth, ÂRGB(cRed, cGreen, cBlue));42: try43: {44: // Add the new line to the object array45: 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 the51: // bad news52: AfxMessageBox("Out of memory", MB_ICONSTOP | MB_OK);53: // Did we create a line object?54: if (pLine)55: {56: // Delete it57: delete pLine;58: pLine = NULL;59: }60: // Delete the exception object61: perr->Delete();62: }63: // Set the starting point to the end point64: pFrom = pTo;65: }66: }67: }</PRE><P>Now that you've made all the necessary changes to the library module, compileit so that it's ready for use in the test application. If you run your test applicationfrom the Start | Run Taskbar option, as in Figure 16.6, you'll notice that thereis no noticeable difference in how your application behaves. This is because theapplication hasn't changed. The application is still using the old version of yourlibrary module. To get the test application to use the new version of the librarymodule, reopen the test application project in Visual C++. Build the project, whichshould 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 isnow generating, as shown in Figure 16.7.</P><P><A HREF="javascript:popUp('16fig06.gif')"><B>FIGURE 16.6.</B></A><B> </B><I>Runthe test application from the Start menu.</I></P><P><A HREF="javascript:popUp('16fig07.gif')"><B>FIGURE 16.7.</B></A><B> </B><I>Theupdated 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 foryour applications. You learned the differences between the different types of classesthat are available to you through the New Class Wizard in Visual C++. You also learnedhow you can create a library module with a set of your functionality that you canhand to other programmers for including in their applications. You learned how thismodule will be linked into the actual applications, thus not requiring a separatefile to be distributed along with the applications.</P><P>Tomorrow you will learn about a different approach to creating reusable packagedfunctionality that you can give to other programmers. You will learn how to createDLLs using Visual C++, what the differences are between creating library modulesand 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 ofthe material covered and exercises to provide you with experience in using what you'velearned. The answers to the quiz questions and exercises are provided in AppendixB, "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 classso 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"><IMGSRC="../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. Allrights reserved.</CENTER></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -