📄 ch16.htm
字号:
9: {10: // Loop through the array, drawing each object11: for (liPos = 0; liPos < liCount; liPos++)12: ((CLine*)m_oaLines[liPos])->Draw(pDC);13: }14: }</PRE><P><B>Serializing the Drawing</B></P><P>Because you are using the line segment class that you created earlier and havealready made serializable, you do not need to add the serialization macros to thedrawing class. What you do need to add is a Serialize function that passes the archiveobject on to the object array, letting the object array and line segment objectsdo all the serialization work. To add this function to your project, add a new memberfunction to the drawing class. Specify the function type as void, the declarationas Serialize(CArchive &ar), and the access as public. Edit the function as inListing 16.5.</P><P><H4>LISTING 16.5. THE CModArt Serialize FUNCTION.</H4><PRE>1: void CModArt::Serialize(CArchive &ar)2: {3: // Pass the archive object on to the array4: m_oaLines.Serialize(ar);5: }</PRE><P><B>Clearing the Drawing</B></P><P>To provide full functionality, you need to be able to delete a drawing from thedrawing class so that a new drawing can be created or an existing drawing can beloaded. This is a simple matter of looping through the object array and destroyingevery line segment object and then resetting the object array. To add this functionalityto your project, add a new member function to the drawing class. Specify the typeas void, the declaration as ClearDrawing, and the access as public. Edit the functionas in Listing 16.6.</P><P><H4>LISTING 16.6. THE CModArt ClearDrawing FUNCTION.</H4><PRE>1: void CModArt::ClearDrawing()2: {3: // Get the number of lines in the object array4: int liCount = m_oaLines.GetSize();5: int liPos;6:7: // Are there any objects in the array?8: if (liCount)9: {10: // Loop through the array, deleting each object11: for (liPos = 0; liPos < liCount; liPos++)12: delete m_oaLines[liPos];13: // Reset the array14: m_oaLines.RemoveAll();15: }16: }</PRE><P><B>Completing the Class</B></P><P>Finally, to wrap up your drawing class, you need to initialize the random numbergenerator. The random number generator function, rand, generates a statisticallyrandom number sequence based on a series of mathematical calculations. If the numbergenerator starts with the same number each time, then the sequence of numbers isthe same each time. To get the random number generator to produce a different sequenceof numbers each time your application runs, you need to seed it with a value thatis different each time. The typical way to do this is to feed the current systemtime into the srand function, which seeds the random number generator with a differenttime each time that the application runs. This seeding of the number generator mustbe done only once each time the application is run, so you can add this functionalityby editing the drawing class constructor with the code in Listing 16.7.</P><P><H4>LISTING 16.7. THE CModArt CONSTRUCTOR.</H4><PRE>1: CModArt::CModArt()2: {3: // Initialize the random number generator4: srand((unsigned)time(NULL));5: }</PRE><P>To complete the class, you need to include all of the necessary header files forthe functionality that you've added to this class. The random number generator needsthe stdlib.h and time.h header files, and the object array needs the header filefor the CLine class. You also need to populate the color table for use when generatingsquiggles. You can add all of these finishing touches by scrolling to the top ofthe source code file for the drawing class and adding lines 5, 6, 9, and 12 through21 in Listing 16.8.</P><P><H4>LISTING 16.8. THE CModArt INCLUDES AND COLOR TABLE.</H4><PRE>1: // ModArt.cpp: implementation of the CModArt class.2: //3: //////////////////////////////////////////////////////////////////////4:5: #include <stdlib.h>6: #include <time.h>7:8: #include "stdafx.h"9: #include "Line.h"10: #include "ModArt.h"11:12: const COLORREF CModArt::m_crColors[8] = {13: RGB( 0, 0, 0), // Black14: RGB( 0, 0, 255), // Blue15: RGB( 0, 255, 0), // Green16: RGB( 0, 255, 255), // Cyan17: RGB( 255, 0, 0), // Red18: RGB( 255, 0, 255), // Magenta19: RGB( 255, 255, 0), // Yellow20: RGB( 255, 255, 255) // White21: };</PRE><P>You have now completed your library module. Before you go any further, you needto compile your project. Once you compile your project, you cannot run anything becauseyou need to create an application that uses your library module in order to run andtest your code. To get ready for creating this test application, close the entireworkspace so that you will start with a clean workspace for the test application.</P><P><H3><A NAME="Heading8"></A>Creating a Test Application</H3><P>To be able to test your module, you need to create a test application that usesthe module. This plain application can contain just enough functionality to thoroughlytest the module. All you want to do at this point is test all the functionality inthe module; you don't have to create a full-blown application.</P><P>When you create your test application, you need to include the header file forthe drawing class in the relevant classes in your application. In a typical SDI orMDI application, this means including the header file in the document class at aminimum and probably the view and application class source files also. You also haveto add the library file that your module created in the application project so thatit will be linked into your appli-cation.</P><P><H4>Creating the Test App Shell</H4><P>Creating a test application shell is a simple matter of creating a standard SDIor MDI application shell. For the purposes of keeping the test application as simpleas possible, it's probably advisable to use an SDI application. However, if you'vegot some functionality in your module that is intended for use in an MDI application,then that application style might be a better selection as your test application.</P><P>For the test application for the sample module you created, create a standardSDI application shell using the AppWizard. Give the project a name such as TestAppor some other suitable name. Specify a file extension on the advanced button on thefourth AppWizard step. Otherwise, just go ahead and use the default settings foreverything else.</P><P>Once you create the application shell, you need to add the library module to theproject. You can do this by selecting Project | Add To Project | Files. Once in theInsert Files dialog, specify the file types as library files, as shown in Figure16.3. Navigate to the debug directory of the module project to find the library modulethat you created with the previous project. This typically requires moving up onedirectory level, finding the project directory for the module, and then navigatingthrough it to the debug directory. (If you are building the release version of themodule and application, you want to navigate down to the release directory of themodule project.) You should be able to find the library file for the module you created,as shown in Figure 16.4. Select this module and click OK to add it to the project.</P><P><A HREF="javascript:popUp('16fig03.gif')"><B>FIGURE 16.3.</B></A><B> </B><I>Specifyinglibrary files.</I></P><P><A HREF="javascript:popUp('16fig04.gif')"><B>FIGURE 16.4.</B></A><B> </B><I>Addinga library file to the project.</I></P><P>Once you add the library file to the project, you also need to add the headerfiles for any of the classes in the module that will be used into the appropriateapplication source code files. For the test application that you are building, thisentails adding line 7 in Listing 16.9. You want to add the same line in the includesections of the source code files for the view and application classes as well.</P><P><H4>LISTING 16.9. THE CTestAppDoc INCLUDES.</H4><PRE>1: // TestAppDoc.cpp : implementation of the CTestAppDoc class2: //3:4: #include "stdafx.h"5: #include "TestApp.h"6:7: #include "..\ModArtMod\ModArt.h"8: #include "TestAppDoc.h"</PRE><P>The last thing that you need to do in preparing the application shell is add avariable for any classes from the library module that need to be included in anyof the application classes. In the case of the test application that you are building,this is a variable in the document class of the drawing class that you created inthe library module project. To add this variable to your application, add a new membervariable to the document class. Specify the variable type as the drawing class fromthe library module (in this instance, CModArt) and specify the name as m_maDrawingand the access as private.</P><P><H4>Creating a New Drawing</H4><P>The first place where you want to put some of the functionality of your moduleis when you are creating a new document. This is the time to be generating a newdrawing. As a result, you want to do two things. First, get the drawing area of theview class, passing it along to the drawing object. Second, tell the drawing objectto generate a new drawing. This is all fairly straightforward. To add this functionalityto your application, edit the OnNewDocument function in the document class, addingthe lines 9-23 in Listing 16.10.</P><P><H4>LISTING 16.10. THE CTestAppDoc OnNewDocument FUNCTION.</H4><PRE>1: BOOL CTestAppDoc::OnNewDocument()2: {3: if (!CDocument::OnNewDocument())4: return FALSE;5:6: // TODO: add reinitialization code here7: // (SDI documents will reuse this document)8:9: // Get the position of the view10: POSITION pos = GetFirstViewPosition();11: // Did we get a valid position?12: if (pos != NULL)13: {14: // Get a pointer to the view15: CView* pView = GetNextView(pos);16: RECT lWndRect;17: // Get the display area rectangle18: pView->GetClientRect(&lWndRect);19: // Set the drawing area20: m_maDrawing.SetRect(lWndRect);21: // Create a new drawing22: m_maDrawing.NewDrawing();23: }24:25: return TRUE;26: }</PRE><H4>Saving and Deleting a Drawing</H4><P>The other functionality that you want to add to the document class is to saveand restore the drawing and to delete the current drawing. These tasks are the lastof the document-related functionality of your library module.</P><P>To add the functionality to save and restore drawings to your application, editthe Serialize function in the document class. Delete all the current contents ofthe function, replacing it with a call to the drawing object's Serialize function,as in Listing 16.11.</P><P><H4>LISTING 16.11. THE CTestAppDoc Serialize FUNCTION.</H4><PRE>1: void CTestAppDoc::Serialize(CArchive& ar)2: {3: // Serialize the drawing4: m_maDrawing.Serialize(ar);5: }</PRE><P>To add the functionality to delete the current drawing so that a new drawing canbe generated or a saved drawing can be loaded, you need to add the event handlerfor the DeleteContents function to the document class. In this function, you callthe drawing object's ClearDrawing function. To add this functionality to your application,use the Class Wizard to add the event handler for the DeleteContents event to thedocument class. Edit this function, adding line 5 in Listing 16.12.</P><P><H4>LISTING 16.12. THE CTestAppDoc DeleteContents FUNCTION.</H4><PRE>1: void CTestAppDoc::DeleteContents()2: {3: // TODO: Add your specialized code here and/or call the base class4: // Delete the drawing5: m_maDrawing.ClearDrawing();6:7: CDocument::DeleteContents();8: }</PRE><H4>Viewing a Drawing</H4><P>You need to add one final set of functionality to your test application beforeyou can test your library module: the drawing functionality to the application. Thisfunctionality belongs in the view class because it is the object that knows whenit needs to redraw itself. Before you can add this functionality to the view class,you need some way for the view class to get access to the drawing object. The easiestway to add this capability is to add another function to the document class thatcan be called to get a pointer to the drawing object. Once the view has this pointer,it can call the drawing object's own Draw function.</P><P>To add the capability to get a pointer to the drawing object to your documentclass, add a new member function to the document class. Specify the function typeas a pointer to the drawing object, in this case, CModArt*, and specify the functiondeclaration as GetDrawing and the access as public. Edit the function, adding thecode in Listing 16.13.</P><P><H4>LISTING 16.13. THE CTestAppDoc GetDrawing FUNCTION.</H4><PRE>1: CModArt* CTestAppDoc::GetDrawing()2: {3: // Return the drawing object4: return &m_maDrawing;5: }</PRE><P>Adding the drawing functionality to the view class is a simple matter of editing
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -