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

📄 ch16.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 页
字号:
a library module project.</I></P><P><A HREF="javascript:popUp('16fig02.gif')"><B>FIGURE 16.2.</B></A><B> </B><I>Specifyingproject support options.</I></P><P><I></I><H4>Creating a Library Project</H4><P>To start the library project for today's example, you need to create a new project,specifying that the project is a Win32 Static Library project. Give the project asuitable name and click OK to create the project.</P><P>For today's sample project, specify on the one wizard step to include both MFCand precompiled header support. Although the precompiled header support is not necessary,it will speed up most compiles that you perform while building the module.</P><P>Once you create your module project, you'll find yourself working with a projectthat has no classes. You've got a blank slate from which you can create whatevertype of module you need.</P><P>For your sample project, because you already have the CLine class built, copyit from the Day 10 project area into the project directory for today's project. Addboth the header and source code file to today's project by choosing Project | AddTo Project \ Files. Once you add both of these files to the project, you should seethe CLine class appear in the Class View of your project.</P><P><H4>Defining the Classes</H4><P>Now that you've got a basic library module project ready to go, it's time to beginadding the meat of the module. Using the CLine class is an easy way of reusing somefunctionality that you created earlier in another setting. However, the real functionalityof this module will be in its ability to generate random drawings, or squiggles.For this functionality, you'll need to create a new class.</P><P>To start this new class, add a new class to the project by selecting New Classfrom the pop-up menu in the Class View tab. The first thing that you'll notice inthe New Class dialog is that you are limited to creating generic classes. Becauseyou are creating a static library that will be linked into the application, VisualC++ is making some assumptions about the type of class that you want to create. Becausethis is not an MFC project, even though MFC support is included, you are preventedfrom creating a new MFC or form class. If you need to inherit a new class from anMFC class, you have to add it as if it were a generic class.</P><P>Use the New Class dialog to create your new class. Give the class a name thatreflects its functionality, such as CModArt, and specify that it's derived from theCObject class as public. You'll receive the same warning that the base class headerfile cannot be found, but because you specified that MFC support should be included,you can ignore that message.</P><P>Once you create your class, you need to add a couple of variables to the class.First, you need somewhere to hold all the lines that will make up the drawing, soyou'll add an object array. Second, you need to know the area of the drawing surface,so you'll want a CRect to hold the drawing area specification. You can add both ofthese variables to your new class using the types and names in Table 16.1.</P><P><H4>TABLE 16.1. CModArt VARIABLES.</H4><P><TABLE BORDER="1">	<TR ALIGN="LEFT" VALIGN="TOP">		<TD ALIGN="LEFT"><I>Type</I></TD>		<TD ALIGN="LEFT"><I>Name</I></TD>		<TD ALIGN="LEFT"><I>Access</I></TD>	</TR>	<TR ALIGN="LEFT" VALIGN="TOP">		<TD ALIGN="LEFT">static const COLORREF		</TD>		<TD ALIGN="LEFT">m_crColors[8]		</TD>		<TD ALIGN="LEFT">Public		</TD>	</TR>	<TR ALIGN="LEFT" VALIGN="TOP">		<TD ALIGN="LEFT">CRect		</TD>		<TD ALIGN="LEFT">m_rDrawArea		</TD>		<TD ALIGN="LEFT">Private		</TD>	</TR>	<TR ALIGN="LEFT" VALIGN="TOP">		<TD ALIGN="LEFT">CObArray		</TD>		<TD ALIGN="LEFT">m_oaLines		</TD>		<TD ALIGN="LEFT">Private		</TD>	</TR></TABLE></P><P><B>Setting the Drawing Area</B></P><P>Before you can draw anything, you need to know the area that you have to drawwithin. You can add a public function to your class that will copy the passed inCRect to the member CRect variable. To add this function to your project, add a newmember function to your new class, specifying the type as void, the declaration asSetRect(CRect rDrawArea), and the access as public. Edit the function as in Listing16.1.</P><P><H4>LISTING 16.1. THE CModArt SetRect FUNCTION.</H4><PRE>1: void CModArt::SetRect(CRect rDrawArea)2: {3:     // Set the drawing area rectangle4:     m_rDrawArea = rDrawArea;5: }</PRE><P><B>Creating a New Drawing</B></P><P>One of the key pieces to this module is the ability to generate random squigglesthat appear on the drawing area. By generating a whole series of these squiggles,your module will be able to create an entire drawing. Starting with the single squiggle,you can design a function that generates one squiggle and then calls this functiona number of times to generate the entire drawing.</P><P>This first function, the squiggle generator, needs to determine how many lineswill be in the squiggle. It needs to determine the color and width of the pen tobe used when drawing the squiggle. It also needs to determine the starting pointfor the squiggle. From this point, it could loop through the appropriate number oflines, generating a new destination to continue the squiggle from the previous destinationpoint.</P><P>To add this functionality to your project, add a new member function to the drawingclass. Specify the function type as void, the definition as NewLine, and the accessas private because this function will only be called by the master loop that is determininghow many of these squiggles will be in the final drawing. Edit the new function withthe code in Listing 16.2.</P><P><H4>LISTING 16.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:     // Determine the number of parts to this squiggle17:     lNumLines = rand() % 100;18:     // Are there any parts to this squiggle?19:     if (lNumLines &gt; 0)20:     {21:         // Determine the color22:         nCurColor = rand() % 8;23:         // Determine the pen width24:         nCurWidth = (rand() % 8) + 1;25:         // Determine the starting point for the squiggle26:         pFrom.x = (rand() % lWidth) + m_rDrawArea.left;27:         pFrom.y = (rand() % lHeight) + m_rDrawArea.top;28:         // Loop through the number of segments29:         for (lCurLine = 0; lCurLine &lt; lNumLines; lCurLine++)30:         {31:             // Determine the end point of the segment32:             pTo.x = ((rand() % 20) - 10) + pFrom.x;33:             pTo.y = ((rand() % 20) - 10) + pFrom.y;34:             // Create a new CLine object35:             CLine *pLine = new CLine(pFrom, pTo, nCurWidth,                         &Acirc;m_crColors[nCurColor]);36:             try37:             {38:                 // Add the new line to the object array39:                 m_oaLines.Add(pLine);40:             }41:             // Did we run into a memory exception?42:             catch (CMemoryException* perr)43:             {44:                 // Display a message for the user, giving him the45:                 // bad news46:                 AfxMessageBox(&quot;Out of memory&quot;, MB_ICONSTOP | MB_OK);47:                 // Did we create a line object?48:                 if (pLine)49:                 {50:                     // Delete it51:                     delete pLine;52:                     pLine = NULL;53:                 }54:                 // Delete the exception object55:                 perr-&gt;Delete();56:             }57:             // Set the starting point to the end point58:             pFrom = pTo;59:         }60:     }61: }</PRE><P>In this function, the first thing that you did was get the area that you had availablefor drawing with the following three lines:</P><P><PRE>m_rDrawArea.NormalizeRect();int lWidth = m_rDrawArea.Width();int lHeight = m_rDrawArea.Height();</PRE><P>In the first of these lines, you normalized the rectangle. This is necessary toguarantee that the width and height returned in the next two lines are both positivevalues. Because of the coordinate system used in Windows, getting the width by subtractingthe left-side position from the right-side position can result in a negative number.The same can happen with the height. By normalizing the rectangle, you are guaranteeingthat you'll get positive results for these two values.</P><P>Once you determined the drawing area, you determined the number of line segmentsyou would use in this squiggle:</P><P><PRE>lNumLines = rand() % 100;</PRE><P>The rand function is capable of returning numbers in a wide range. By gettingthe modulus of 100, you are guaranteeing that the resulting number will be between0 and 100. This is a common technique for generating random numbers within a certainrange, using the modulus function with the upper limit of the value range (or theupper limit minus the lower limit, if the lower limit is not equal to 0, and thenadding the lower limit to the resulting number). You use the same technique to determinethe color, width, and starting position for the squiggle:</P><P><PRE>nCurColor = rand() % 8;nCurWidth = (rand() % 8) + 1;pFrom.x = (rand() % lWidth) + m_rDrawArea.left;pFrom.y = (rand() % lHeight) + m_rDrawArea.top;</PRE><P>Notice how when you were determining the starting position, you added the leftand top of the drawing area to the position that you generated. This guarantees thatthe starting position is within the drawing area. Once you enter the loop, generatingall the line segments in the squiggle, you limit the available area for the nextdestination within 10 of the current position:</P><P><PRE>pTo.x = ((rand() % 20) - 10) + pFrom.x;pTo.y = ((rand() % 20) - 10) + pFrom.y;CLine *pLine = new CLine(pFrom, pTo, nCurWidth, m_crColors[nCurColor]);m_oaLines.Add(pLine);</PRE><P>You can easily increase this distance to make the drawings more angular. Onceyou generate the next line segment, you create the line object and add it to theobject array. Finally, you set the starting position to the ending position of theline segment you just generated:</P><P><PRE>pFrom = pTo;</PRE><P>Now you are ready to go through the loop again and generate the next line segment,until you have generated all line segments in this squiggle.</P><P>Now that you can generate a single squiggle, the rest of the process is easy.First, you determine how many squiggles will be in the drawing. Next, you loop forthe number of squiggles that need to be generated and call the NewLine function oncefor each squiggle. To add this functionality to your project, add a new member functionto the drawing class. Specify the type as void, the declaration as NewDrawing, andthe access as public. Edit the function as in Listing 16.3.</P><P><H4>LISTING 16.3. THE 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() % 10;8:      // Are there any lines to create?9:      if (lNumLines &gt; 0)10:     {11:         // Loop through the number of lines12:         for (lCurLine = 0; lCurLine &lt; lNumLines; lCurLine++)13:         {14:             // Create the new line15:             NewLine();16:         }17:     }18: }</PRE><P><B>Displaying the Drawing</B></P><P>To draw the set of squiggles on the drawing area, you can add a function thatwill loop through the object array, calling the Draw function on each line segmentin the array. This function needs to receive the device context as the only argumentand must pass it along to each of the line segments. To add this function to yourproject, add a new member function to the drawing class. Specify the function typeas void, the function declaration as Draw(CDC *pDC), and the access as public. Editthe function as in Listing 16.4.</P><P><H4>LISTING 16.4. THE CModArt Draw FUNCTION.</H4><PRE>1:  void CModArt::Draw(CDC *pDC)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)

⌨️ 快捷键说明

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