📄 ch17.htm
字号:
you need to create a new MFC DLL Wizard project, specifying that the project is anMFC extension DLL. Copy the source code and header files for the line and drawingclasses into the project directory. Load the files for the line and drawing classesinto the current project. Add the AFX_EXT_CLASS macro to the drawing class. Finally,move the color table from a global static table to a local variable inside the functionthat creates the squiggles.</P><P>To create this DLL, start a new project. Give the project a suitable name, suchas ModArtDll, and specify that the project is an MFC AppWizard (DLL) project, asin Figure 17.1. Once in the DLL Wizard, specify that the DLL is an MFC ExtensionDLL, as in Figure 17.2.</P><P><A HREF="javascript:popUp('17fig01.gif')"><B>FIGURE 17.1.</B></A><B> </B><I>Selectingthe MFC DLL Wizard.</I></P><P>Once you create the DLL shell, open the file explorer and copy the source codeand header files for the line and drawing classes (line.cpp, line.h, ModArt.cpp,and ModArt.h) from the library module project you created yesterday into the projectdirectory that you just created. Add all four of these files to the project. Bothclasses should appear in the Class View of the workspace pane.</P><P><A HREF="javascript:popUp('17fig02.gif')"><B>FIGURE 17.2.</B></A><B> </B><I>Specifyingthe DLL type.</I></P><P>Open the header file containing the definition of the drawing class. Add the AFX_EXT_CLASSmacro to the class declaration as shown in Listing 17.1. Remove the color table variablefrom the class declaration also.</P><P><H4>LISTING 17.1. THE MODIFIED CModArt CLASS DECLARATION.</H4><PRE>1: class AFX_EXT_CLASS CModArt : public CObject2: {3: public:4: void NewDrawing();5: virtual void Serialize(CArchive &ar);6: void Draw(CDC *pDC);7: void ClearDrawing();8: void SetRect(CRect rDrawArea);9: CModArt();10: virtual ~CModArt();11:12: private:13: void NewLine();14: CRect m_rDrawArea;15: CObArray m_oaLines;16: };</PRE><P>You cannot have public static tables in DLLs, so you cannot declare the colortable as a public, static member of the drawing class, as it was yesterday. As aresult, you'll move it to a local variable in the NewLine member function. Edit theNewLine function to add this local variable and to reset the function to behave asit did in its initial incarnation, as in Listing 17.2.</P><P><H4>LISTING 17.2. THE 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:10: // Normalize the rectangle before determining the width and height11: m_rDrawArea.NormalizeRect();12: // get the area width and height13: int lWidth = m_rDrawArea.Width();14: int lHeight = m_rDrawArea.Height();15:16: COLORREF crColors[8] = {17: RGB( 0, 0, 0), // Black18: RGB( 0, 0, 255), // Blue19: RGB( 0, 255, 0), // Green20: RGB( 0, 255, 255), // Cyan21: RGB( 255, 0, 0), // Red22: RGB( 255, 0, 255), // Magenta23: RGB( 255, 255, 0), // Yellow24: RGB( 255, 255, 255) // White25: };26:27: // Determine the number of parts to this squiggle28: lNumLines = rand() % 100;29: // Are there any parts to this squiggle?30: if (lNumLines > 0)31: {32: // Determine the color33: nCurColor = rand() % 8;34: // Determine the pen width35: nCurWidth = (rand() % 8) + 1;36: // Determine the starting point for the squiggle37: pFrom.x = (rand() % lWidth) + m_rDrawArea.left;38: pFrom.y = (rand() % lHeight) + m_rDrawArea.top;39: // Loop through the number of segments40: for (lCurLine = 0; lCurLine < lNumLines; lCurLine++)41: {42: // Determine the end point of the segment43: pTo.x = ((rand() % 20) - 10) + pFrom.x;44: pTo.y = ((rand() % 20) - 10) + pFrom.y;45: // Create a new CLine object46: CLine *pLine = new CLine(pFrom, pTo, nCurWidth, ÂcrColors[nCurColor]);47: try48: {49: // Add the new line to the object array50: m_oaLines.Add(pLine);51: }52: // Did we run into a memory exception?53: catch (CMemoryException* perr)54: {55: // Display a message for the user, giving him the56: // bad news57: AfxMessageBox("Out of memory", MB_ICONSTOP | MB_OK);58: // Did we create a line object?59: if (pLine)60: {61: // Delete it62: delete pLine;63: pLine = NULL;64: }65: // Delete the exception object66: perr->Delete();67: }68: // Set the starting point to the end point69: pFrom = pTo;70: }71: }72: }</PRE><P>After making these changes to the drawing class, you are ready to compile yourDLL. Once you compile the DLL, switch over to the file explorer, find the DLL inthe debug subdirectory under the project directory, and copy the DLL to the debugdirectory in the test application project directory.</P><P><H3><A NAME="Heading6"></A>Adapting the Test Application</H3><P>To adapt the test application to use the DLL, open the test application projectthat you created yesterday. You are going to delete the library module that you createdyesterday and add the LIB file that was created with the DLL. You are also goingto change the header file that is included for the drawing class. After making thesetwo changes, your test application will be ready to use with the DLL.</P><P>To delete the library module from the project, open the File View in the workspacepane. Select the LIB file from the list of project files and press the Delete key.Once you delete the library file from the project, select Project | Add To Project| Files from the main menu. Specify the Library Files (.lib) file type, and thennavigate to the debug directory of the DLL project. Select the LIB file that wascreated with your DLL, in this case, ModArtDll.lib. Click OK to add the file to theproject.</P><P>Once you add the DLL's LIB file, edit the source-code files for the document,view, and application classes, changing the include of the drawing class to pointto the project directory of the DLL, as in line 7 in Listing 17.3.</P><P><H4>LISTING 17.3. 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 "..\ModArtDll\ModArt.h"8: #include "TestAppDoc.h"</PRE><P>After making this change to all three source-code files, you are ready to compileand run your test application. You should find your test application running justlike it did yesterday, only generating shorter squiggles and using only the eightcolors in the color table.</P><P><H3><A NAME="Heading7"></A>Changing the DLL</H3><P>Now that you have the test application running with the DLL, you'll make the samechanges to the DLL that you made to the library module yesterday. You'll increasethe number of squiggles that can be included in a drawing, increase the possiblelength of each squiggle, and generate any number of colors for use in the squiggles.</P><P>To make these changes, switch back to the DLL project. Increase the number oflines that may be generated in the NewDrawing member function of the drawing class.Increase the possible length of the squiggles in the NewLine member function, andadd the random colors back in, as in Listing 17.4.</P><P><H4>LISTING 17.4. 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: // 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 > 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) + m_rDrawArea.left;44: pFrom.y = (rand() % lHeight) + m_rDrawArea.top;45: // Loop through the number of segments46: for (lCurLine = 0; lCurLine < 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, ÂRGB(cRed, cGreen, cBlue));53: try54: {55: // Add the new line to the object array56: m_oaLines.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("Out of memory", 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->Delete();73: }74: // Set the starting point to the end point75: pFrom = pTo;76: }77: }78: }</PRE><P>After making these changes, compile the DLL again. Once you compile the DLL, switchto the file explorer and copy the DLL into the debug directory of the test applicationagain. Once you copy the DLL, run the test application from the Start | Run Taskbar,as in Figure 17.3. You should find that the application has been updated, and itis now including more squiggles and using many different colors.</P><P><A HREF="javascript:popUp('17fig03.gif')"><B>FIGURE 17.3.</B></A><B> </B><I>Startingthe sample application.</I></P><P><I></I><H2><A NAME="Heading8"></A>Creating and Using a Regular DLL</H2><P>You might think that you broke the rules about using variables that are not ownedby the application in a DLL when you created and used the MFC extension DLL. Well,you didn't. The instance of the drawing class was a member of the document classin the test application. It was created and maintained by the application, not theDLL. Now that you are turning your attention to implementing the same functionalityas a regular DLL, this will become clearer.</P><P>To convert the MFC extension DLL into a regular DLL, you'll have to convert thedrawing class into a series of regular function calls. In the course of making thisconversion, the object array must become a member variable of the application documentclass and must be passed as an argument to every exported function in the DLL.</P><P><H3><A NAME="Heading9"></A>Creating the Regular DLL</H3><P>To convert the MFC extension DLL into a regular DLL, you have to start a new project.Visual C++ has to build a project that tells the compiler what type of file it'screating. You can create this new project using the same steps you used to createthe MFC extension DLL project, but specify on the DLL Wizard that you are creatinga regular DLL. (You can leave the wizard at the default settings.) Once you createthe project, you can copy the line and drawing class source code and header filesinto the project directory and add these files to the project. Once you add thesefiles to the project, you need to begin the process of converting the drawing classinto a series of straight function calls.</P><P><DL>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -