⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch16.htm

📁 VC 21天 学习VC 的好东西
💻 HTM
📖 第 1 页 / 共 4 页
字号:
9:      {
10:         // Loop through the array, drawing each object
11:         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 have
already made serializable, you do not need to add the serialization macros to the
drawing class. What you do need to add is a Serialize function that passes the archive
object on to the object array, letting the object array and line segment objects
do all the serialization work. To add this function to your project, add a new member
function to the drawing class. Specify the function type as void, the declaration
as Serialize(CArchive &amp;ar), and the access as public. Edit the function as in
Listing 16.5.</P>
<P>
<H4>LISTING 16.5. THE CModArt Serialize FUNCTION.</H4>
<PRE>1: void CModArt::Serialize(CArchive &amp;ar)
2: {
3:     // Pass the archive object on to the array
4:     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 the
drawing class so that a new drawing can be created or an existing drawing can be
loaded. This is a simple matter of looping through the object array and destroying
every line segment object and then resetting the object array. To add this functionality
to your project, add a new member function to the drawing class. Specify the type
as void, the declaration as ClearDrawing, and the access as public. Edit the function
as 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 array
4:      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 object
11:         for (liPos = 0; liPos &lt; liCount; liPos++)
12:             delete m_oaLines[liPos];
13:         // Reset the array
14:         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 number
generator. The random number generator function, rand, generates a statistically
random number sequence based on a series of mathematical calculations. If the number
generator starts with the same number each time, then the sequence of numbers is
the same each time. To get the random number generator to produce a different sequence
of numbers each time your application runs, you need to seed it with a value that
is different each time. The typical way to do this is to feed the current system
time into the srand function, which seeds the random number generator with a different
time each time that the application runs. This seeding of the number generator must
be done only once each time the application is run, so you can add this functionality
by 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 generator
4:     srand((unsigned)time(NULL));
5: }
</PRE>
<P>To complete the class, you need to include all of the necessary header files for
the functionality that you've added to this class. The random number generator needs
the stdlib.h and time.h header files, and the object array needs the header file
for the CLine class. You also need to populate the color table for use when generating
squiggles. You can add all of these finishing touches by scrolling to the top of
the source code file for the drawing class and adding lines 5, 6, 9, and 12 through
21 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 &lt;stdlib.h&gt;
6:  #include &lt;time.h&gt;
7:
8:  #include &quot;stdafx.h&quot;
9:  #include &quot;Line.h&quot;
10: #include &quot;ModArt.h&quot;
11:
12: const COLORREF CModArt::m_crColors[8] = {
13:     RGB(   0,   0,   0),    // Black
14:     RGB(   0,   0, 255),    // Blue
15:     RGB(   0, 255,   0),    // Green
16:     RGB(   0, 255, 255),    // Cyan
17:     RGB( 255,   0,   0),    // Red
18:     RGB( 255,   0, 255),    // Magenta
19:     RGB( 255, 255,   0),    // Yellow
20:     RGB( 255, 255, 255)     // White
21: };
</PRE>
<P>You have now completed your library module. Before you go any further, you need
to compile your project. Once you compile your project, you cannot run anything because
you need to create an application that uses your library module in order to run and
test your code. To get ready for creating this test application, close the entire
workspace 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 uses
the module. This plain application can contain just enough functionality to thoroughly
test the module. All you want to do at this point is test all the functionality in
the 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 for
the drawing class in the relevant classes in your application. In a typical SDI or
MDI application, this means including the header file in the document class at a
minimum and probably the view and application class source files also. You also have
to add the library file that your module created in the application project so that
it 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 SDI
or MDI application shell. For the purposes of keeping the test application as simple
as possible, it's probably advisable to use an SDI application. However, if you've
got 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 standard
SDI application shell using the AppWizard. Give the project a name such as TestApp
or some other suitable name. Specify a file extension on the advanced button on the
fourth AppWizard step. Otherwise, just go ahead and use the default settings for
everything else.</P>
<P>Once you create the application shell, you need to add the library module to the
project. You can do this by selecting Project | Add To Project | Files. Once in the
Insert Files dialog, specify the file types as library files, as shown in Figure
16.3. Navigate to the debug directory of the module project to find the library module
that you created with the previous project. This typically requires moving up one
directory level, finding the project directory for the module, and then navigating
through it to the debug directory. (If you are building the release version of the
module and application, you want to navigate down to the release directory of the
module 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>Specifying
library files.</I></P>

<P><A HREF="javascript:popUp('16fig04.gif')"><B>FIGURE 16.4.</B></A><B> </B><I>Adding
a library file to the project.</I></P>

<P>Once you add the library file to the project, you also need to add the header
files for any of the classes in the module that will be used into the appropriate
application source code files. For the test application that you are building, this
entails adding line 7 in Listing 16.9. You want to add the same line in the include
sections 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 class
2: //
3:
4: #include &quot;stdafx.h&quot;
5: #include &quot;TestApp.h&quot;
6:
7: #include &quot;..\ModArtMod\ModArt.h&quot;
8: #include &quot;TestAppDoc.h&quot;
</PRE>
<P>The last thing that you need to do in preparing the application shell is add a
variable for any classes from the library module that need to be included in any
of 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 in
the library module project. To add this variable to your application, add a new member
variable to the document class. Specify the variable type as the drawing class from
the library module (in this instance, CModArt) and specify the name as m_maDrawing
and 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 module
is when you are creating a new document. This is the time to be generating a new
drawing. As a result, you want to do two things. First, get the drawing area of the
view class, passing it along to the drawing object. Second, tell the drawing object
to generate a new drawing. This is all fairly straightforward. To add this functionality
to your application, edit the OnNewDocument function in the document class, adding
the 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 here
7:      // (SDI documents will reuse this document)
8:
9:      // Get the position of the view
10:     POSITION pos = GetFirstViewPosition();
11:     // Did we get a valid position?
12:     if (pos != NULL)
13:     {
14:         // Get a pointer to the view
15:         CView* pView = GetNextView(pos);
16:         RECT lWndRect;
17:         // Get the display area rectangle
18:         pView-&gt;GetClientRect(&amp;lWndRect);
19:         // Set the drawing area
20:         m_maDrawing.SetRect(lWndRect);
21:         // Create a new drawing
22:         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 save
and restore the drawing and to delete the current drawing. These tasks are the last
of the document-related functionality of your library module.</P>
<P>To add the functionality to save and restore drawings to your application, edit
the Serialize function in the document class. Delete all the current contents of
the 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&amp; ar)
2: {
3:     // Serialize the drawing
4:     m_maDrawing.Serialize(ar);
5: }
</PRE>
<P>To add the functionality to delete the current drawing so that a new drawing can
be generated or a saved drawing can be loaded, you need to add the event handler
for the DeleteContents function to the document class. In this function, you call
the 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 the
document 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 class
4:     // Delete the drawing
5:     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 before
you can test your library module: the drawing functionality to the application. This
functionality belongs in the view class because it is the object that knows when
it 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 easiest
way to add this capability is to add another function to the document class that
can 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 document
class, add a new member function to the document class. Specify the function type
as a pointer to the drawing object, in this case, CModArt*, and specify the function
declaration as GetDrawing and the access as public. Edit the function, adding the
code 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 object
4:     return &amp;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 + -