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

📄 ch17.htm

📁 visual c plus plus its a book for how to learn c plus plus in just 21 days its an easy way to lea
💻 HTM
📖 第 1 页 / 共 4 页
字号:
	<DT><B>Altering the Header File</B></DT></DL><P>To start with, you need to radically alter the header file for the drawing classso that it will work for a regular DLL. You have to eliminate every trace of theactual class from the header file, leaving only the function calls. All of thesefunctions must be passed in any objects that they need to work with. (Every functionwill need to be passed the object array as one of its arguments.) Next, you needto slightly modify all the function names so that the compiler does not get mixedup and call a member function of any class by mistake (such as the Serialize function).Finally, each of the public functions must be declared as an exportable function.Making these changes to the header file, you end up replacing the entire class declarationwith the function prototypes in Listing 17.5.</P><P><H4>LISTING 17.5. THE MODIFIED ModArt HEADER FILE.</H4><PRE>1: extern &quot;C&quot; void PASCAL EXPORT ModArtNewDrawing(CRect pRect,         &Acirc;CObArray *poaLines);2: extern &quot;C&quot; void PASCAL EXPORT ModArtSerialize(CArchive &amp;ar,         &Acirc;CObArray *poaLines);3: extern &quot;C&quot; void PASCAL EXPORT ModArtDraw(CDC *pDC, CObArray *poaLines);4: extern &quot;C&quot; void PASCAL EXPORT ModArtClearDrawing(CObArray *poaLines);5: void NewLine(CRect pRect, CObArray *poaLines); </PRE><BLOCKQUOTE>	<P><HR><STRONG>NOTE:</STRONG> Notice that the object array is always passed as a pointer to each	of these functions. Because these functions are adding and removing objects from	the array, they need to work with the actual array and not a copy of it.<HR></BLOCKQUOTE><H4>Adapting the Drawing Generation Functions</H4><P>Moving to the source-code file, you need to make numerous small yet significantchanges to these functions. Starting with the NewDrawing function, you need to passin the CRect object to get the drawing area. You dropped the function for settingthe drawing area because you have no local variables in which you can hold this object.As a result, you are better off passing it to the drawing generation functions. Theother change is where you pass in the object array as another argument to the function.You aren't doing anything with either of these arguments in this function, just passingthem along to the squiggle generating function. The other alteration in this functionis the addition of the AFX_MANAGE_STATE macro as the first line in the body of thefunction. After making these changes, the NewDrawing function will look like theone in Listing 17.6.</P><P><H4>LISTING 17.6. THE ModArtNewDrawing FUNCTION.</H4><PRE>1:  extern &quot;C&quot; void PASCAL EXPORT ModArtNewDrawing(CRect pRect,         &Acirc;CObArray *poaLines)2:  {3:      AFX_MANAGE_STATE(AfxGetStaticModuleState());4:      // normal function body here5:      int lNumLines;6:      int lCurLine;7:8:      // Initialize the random number generator9:      srand((unsigned)time(NULL));10:     // Determine how many lines to create11:     lNumLines = rand() % 50;12:     // Are there any lines to create?13:     if (lNumLines &gt; 0)14:     {15:         // Loop through the number of lines16:         for (lCurLine = 0; lCurLine &lt; lNumLines; lCurLine++)17:         {18:             // Create the new line19:             NewLine(pRect, poaLines);20:         }21:     }22: }</PRE><P>Another change that is required in the NewDrawing function is the addition ofthe random number generator seeding on line 9. Because there is no class constructorany more, you cannot seed the random number generator in it. Therefore, the nextlogical place to add this is in the NewDrawing function before any random numbersare generated.</P><P>On the NewLine function, the changes are more extensive. First, the CRect objectand the object array are passed in as arguments. Second, because this is not an exportedfunction, you do not need to add the AFX_MANAGE_STATE macro. Third, all the placeswhere the CRect member variable is used must be changed to use the CRect that ispassed as an argument to the function. Finally, when adding objects to the objectarray, you need to change this to use the object array pointer that was passed asan argument. Making these changes leaves you with the code in Listing 17.7.</P><P><H4>LISTING 17.7. THE NewLine FUNCTION.</H4><PRE> 1:   void NewLine(CRect pRect, CObArray *poaLines) 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          &Acirc;height14:      pRect.NormalizeRect();15:      // get the area width and height16:      int lWidth = pRect.Width();17:      int lHeight = pRect.Height();18: 19:  //    COLORREF crColors[8] = {20:  //    RGB(   0,   0,   0),    // Black21:  //    RGB(   0,   0, 255),    // Blue22:  //    RGB(   0, 255,   0),    // Green23:  //    RGB(   0, 255, 255),    // Cyan24:  //    RGB( 255,   0,   0),    // Red25:  //    RGB( 255,   0, 255),    // Magenta26:  //    RGB( 255, 255,   0),    // Yellow27:  //    RGB( 255, 255, 255)     // White28:  //    };29: 30:      // Determine the number of parts to this squiggle31:      lNumLines = rand() % 200;32:      // Are there any parts to this squiggle?33:      if (lNumLines &gt; 0)34:      {35:          // Determine the color36:  //      nCurColor = rand() % 8;37:          cRed = rand() % 256;38:          cBlue = rand() % 256;39:          cGreen = rand() % 256;40:          // Determine the pen width41:          nCurWidth = (rand() % 8) + 1;42:          // Determine the starting point for the squiggle43:          pFrom.x = (rand() % lWidth) + pRect.left;44:          pFrom.y = (rand() % lHeight) + pRect.top;45:          // Loop through the number of segments46:          for (lCurLine = 0; lCurLine &lt; lNumLines; lCurLine++)47:          {48:              // Determine the end point of the segment49:              pTo.x = ((rand() % 20) - 10) + pFrom.x;50:              pTo.y = ((rand() % 20) - 10) + pFrom.y;51:              // Create a new CLine object52:              CLine *pLine = new CLine(pFrom, pTo, nCurWidth,                          &Acirc;RGB(cRed, cGreen, cBlue));53:              try54:              {55:                  // Add the new line to the object array56:                  poaLines-&gt;Add(pLine);57:              }58:              // Did we run into a memory exception?59:              catch (CMemoryException* perr)60:              {61:                  // Display a message for the user, giving him the62:                  // bad news63:                  AfxMessageBox(&quot;Out of memory&quot;, MB_ICONSTOP | MB_OK);64:                  // Did we create a line object?65:                  if (pLine)66:                  {67:                      // Delete it68:                      delete pLine;69:                      pLine = NULL;70:                  }71:                  // Delete the exception object72:                  perr-&gt;Delete();73:              }74:              // Set the starting point to the end point75:              pFrom = pTo;76:          }77:      }78:  }</PRE><H4>Adapting the Other Functions</H4><P>Making the necessary changes to the other functions is less involved than thechanges to the drawing generation functions. With the rest of the functions, youmust add a pointer to the object array as a function argument and then alter theuses of the array to use the pointer instead of the no longer existing member variable.You also need to add the AFX_MANAGE_STATE macro as the first line in each of theremaining functions. This leaves you with the functions shown in Listings 17.8, 17.9,and 17.10.</P><P><H4>LISTING 17.8. THE ModArtDraw FUNCTION.</H4><PRE>1:  extern &quot;C&quot; void PASCAL EXPORT ModArtDraw(CDC *pDC, CObArray *poaLines)2:  {3:      AFX_MANAGE_STATE(AfxGetStaticModuleState());4:      // normal function body here5:      // Get the number of lines in the object array6:      int liCount = poaLines.GetSize();7:      int liPos;8:9:      // Are there any objects in the array?10:     if (liCount)11:     {12:         // Loop through the array, drawing each object13:         for (liPos = 0; liPos &lt; liCount; liPos++)14:             ((CLine*)poaLines[liPos])-&gt;Draw(pDC);15:     }16: }</PRE><H4>LISTING 17.9. THE ModArtSerialize FUNCTION.</H4><PRE>1: extern &quot;C&quot; void PASCAL EXPORT ModArtSerialize(CArchive &amp;ar,         &Acirc;CObArray *poaLines)2: {3:     AFX_MANAGE_STATE(AfxGetStaticModuleState());4:     // normal function body here5:     // Pass the archive object on to the array6:     poaLines.Serialize(ar);7: }</PRE><H4>Listing 17.10. The MODARTCLEARDRAWING function.</H4><PRE>1:  extern &quot;C&quot; void PASCAL EXPORT ModArtClearDrawing(CObArray *poaLines)2:  {3:      AFX_MANAGE_STATE(AfxGetStaticModuleState());4:      // Normal function body here5:      // Get the number of lines in the object array6:      int liCount = poaLines.GetSize();7:      int liPos;8:9:      // Are there any objects in the array?10:     if (liCount)11:     {12:         // Loop through the array, deleting each object13:         for (liPos = 0; liPos &lt; liCount; liPos++)14:             delete poaLines[liPos];15:         // Reset the array16:         poaLines.RemoveAll();17:     }18: }</PRE><P>Once you make the changes to these functions, the only thing remaining is to removeall code for the class constructor and destructor, along with the code for the SetRectfunction.</P><P><H4>Building the Module Definition File</H4><P>Before you compile the DLL, you need to add all the function names to the moduledefinition file. You can find this file in the list of source-code files in the FileView of the workspace pane. When you open this file, you'll find that it brieflydescribes the module that you are building in generic terms. You'll see a place atthe bottom of the file where you can add the exports for the DLL. Edit this file,adding the exportable function names, as in Listing 17.11.</P><P><H4>LISTING 17.11. THE DLL MODULE DEFINITION FILE.</H4><PRE>1:  ; ModArtRDll.def : Declares the module parameters for the DLL2:3:  LIBRARY        &quot;ModArtRDll&quot;4:  DESCRIPTION    `ModArtRDll Windows Dynamic Link Library'5:6:  EXPORTS7:       ; Explicit exports can go here8:       ModArtNewDrawing9:       ModArtSerialize10:      ModArtDraw11:      ModArtClearDrawing</PRE><P>You are now ready to compile your regular DLL. Once you compile the DLL, copyit into the debug directory of the test application.</P><P><H3><A NAME="Heading10"></A>Adapting the Test Application</H3><P>To adapt the test application to use the new DLL that you have just created, youneed to make a number of changes. First, you need to change the member variable ofthe document class from an instance of the drawing class to the object array. Next,you need to change the include in the document and view source code to include theheader from the new DLL instead of the header from the old DLL. (You can completelyremove the include in the application source-code file.) Drop the DLL LIB file andadd the LIB file for the new DLL to the project. Change all of the drawing classfunction calls to call functions in the new DLL instead. Finally, change the GetDrawingfunction in the document class so that it returns a pointer to the object array,instead of the drawing object.</P><P>You can start making these changes by deleting the LIB file from the test applicationproject. Once you delete the file, add the LIB file for the new DLL to the projectby selecting Project | Add To Project | Files from the main menu.</P><P>Once you switch the LIB files in the project, edit the source code for the documentand view classes to change the include statement, changing the project directoryto the new DLL project directory. You can edit the application class source-codefile and remove the include from this file. Because you are not creating any instancesof the drawing class, the application file doesn't need to know about anything inthe DLL.</P><P>Once you make all those changes, open the header file for the document class.Edit the document class declaration: Change the function type of the GetDrawing functionto return a pointer to an object array, remove the drawing class variable, and addan object array variable, as in Listing 17.12. Make only these three changes; donot change anything else in the class declaration.</P><P><H4>LISTING 17.12. THE CTestAppDoc CLASS DECLARATION.</H4><PRE>1:  class CTestAppDoc : public CDocument2:  {3:  protected: // create from serialization only4:      CTestAppDoc();5:      DECLARE_DYNCREATE(CTestAppDoc)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -