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

📄 ch18.htm

📁 VC 21天 学习VC 的好东西
💻 HTM
📖 第 1 页 / 共 5 页
字号:
this, you'll calculate the new position of the starting and ending points of each
line, set the view port origination point, select the drawing color, and create a
pen to draw in that color. Once you have all of this, you will be able to draw the
line from the starting point to the ending point. Once the line is drawn, you can
restore the pen to what it was before the line was drawn. Next, you'll calculate
the position of the next line to draw before exiting the function.</P>
<P>To add this functionality to your spinner object, add a member function to the
CSpinner class. Specify the type as void, the name as Draw, and the access as public.
Edit the function, adding the code in Listing 18.4.</P>
<P>
<H4>LISTING 18.4. THE CSpinner Draw FUNCTION.</H4>
<PRE> 1: void CSpinner::Draw()
 2: {
 3:     // Get a pointer to the device context
 4:     CDC *pDC = m_pViewWnd-&gt;GetDC();
 5:     // Set the mapping mode
 6:     pDC-&gt;SetMapMode (MM_LOENGLISH);
 7:     // Copy the spinner center
 8:     CPoint org = m_pCenter;
 9:     CPoint pStartPoint;
10:     // Set the starting point
11:     pStartPoint.x = (m_iRadius / 2);
12:     pStartPoint.y = (m_iRadius / 2);
13:     // Set the origination point
14:     org.x = m_pCenter.x + (m_iRadius / 2);
15:     org.y = m_pCenter.y + m_iRadius;
16:     // Set the viewport origination point
17:     pDC-&gt;SetViewportOrg(org.x, org.y);
18: 
19:     CPoint pEndPoint;
20:     // Calculate the angle of the next line
21:     double nRadians = (double) (m_nMinute * 6) * 0.017453292;
22:     // Set the end point of the line
23:     pEndPoint.x = (int) (m_iRadius * sin(nRadians));
24:     pEndPoint.y = (int) (m_iRadius * cos(nRadians));
25: 
26: 
27:     // Create the pen to use
28:     CPen pen(PS_SOLID, 0, m_crColors[m_crColor]);
29:     // Select the pen for use
30:     CPen* pOldPen = pDC-&gt;SelectObject(&amp;pen);
31: 
32:     // Move to the starting point
33:     pDC-&gt;MoveTo (pEndPoint);
34:     // Draw the line to the end point
35:     pDC-&gt;LineTo (pStartPoint);
</PRE>
<PRE>36: 
</PRE>
<PRE>37:     // Reselect the previous pen
38:     pDC-&gt;SelectObject(&amp;pOldPen);
39: 
40:     // Release the device context
41:     m_pViewWnd-&gt;ReleaseDC(pDC);
42: 
43:     // Increment the minute
44:     if (++m_nMinute == 60)
45:     {
46:         // If the minutes have gone full circle, reset to 0
47:         m_nMinute = 0;
48:         // Increment the color
49:         if (++m_crColor == 8)
50:             // If we've gone through all colors, start again
51:             m_crColor = 0;
52:     }
53: }
</PRE>
<P>That was quite a bit of code to type. What does it do? Well, to understand what
this function is doing, and how it's going to make your spinner draw a color wheel
on the window, let's take a closer look at the code.</P>
<P>To make efficient use of the spinner by the different threads, it'll only draw
one line each time the function is called. This function will be called 60 times
for each complete circle, once for each &quot;minute&quot; in the clockwise rotation.
Each complete rotation will cause the spinner to switch to the next color in the
color table.</P>
<P>One of the first things that you need to do in order to perform any drawing on
the window is get the device context of the window. You do this by calling the GetDC
function on the view object pointer:</P>
<P>
<PRE>CDC *pDC = m_pViewWnd-&gt;GetDC();
</PRE>
<P>This function returns a CDC object pointer, which is an MFC class that encapsulates
the device context.</P>
<P>Once you have a pointer to the device context, you can call its member function,
SetMapMode, to set the mapping mode:</P>
<P>
<PRE>pDC-&gt;SetMapMode (MM_LOENGLISH);
</PRE>
<P>The mapping mode determines how the x and y coordinates are translated into positions
on the screen. The MM_LOENGLISH mode converts each logical unit to 0.01 inch on the
screen. There are several different mapping modes, each converting logical units
to different measurements on the screen.</P>
<P>At this point, you start preparing to draw the current line for the color wheel.
You start by calculating the starting point for the line that will be drawn. This
point will be consistent for all lines drawn by the spinner object. After you calculate
the starting point for the line, you calculate the position of the viewport. The
viewport is used as the starting point for the coordinates used for drawing.</P>


<BLOCKQUOTE>
	<P>
<HR>
<STRONG>NOTE:</STRONG> The starting point for the line to be drawn is calculated in an off-center
	position. If you want the starting point for the lines to be in the center of the
	color wheel, set both the x and y coordinates of the starting point to 0.
<HR>


</BLOCKQUOTE>

<P>Once the viewport origination point is calculated, use the SetViewportOrg function
to set the viewport:</P>
<P>
<PRE>pDC-&gt;SetViewportOrg(org.x, org.y);
</PRE>
<P>Now that you've got the drawing area specified, and the starting point for the
line that you are going to be drawing, you need to figure out where the other end
of the line will be. You'll perform this calculation using the following three lines
of code:</P>
<P>
<PRE>double nRadians = (double) (m_nMinute * 6) * 0.017453292;
pEndPoint.x = (int) (m_iRadius * sin(nRadians));
pEndPoint.y = (int) (m_iRadius * cos(nRadians));
</PRE>
<P>In the first of these calculations, convert the minutes into degrees, which can
then be fed into the sine and cosine functions to set the x and y coordinates to
draw a circle. This sets the end point of the line that will be drawn.</P>
<P>Now that you've figured out the starting and ending points of the line, you'll
create a pen to use in drawing the line:</P>
<P>
<PRE>CPen pen(PS_SOLID, 0, m_crColors[m_crColor]);
</PRE>
<P>You've specified that the pen will be solid and thin, and you are picking the
current color from the color table. Once you create the pen to use, select the pen
for drawing, being sure to capture the current pen as the return value from the device
context object:</P>
<P>
<PRE>CPen* pOldPen = pDC-&gt;SelectObject(&amp;pen);
</PRE>
<P>Now you are ready to draw the line, which is done using the MoveTo and LineTo
functions that you're well familiar with by now. Once the line is drawn, release
the device context so that you don't have a resource leak in your application:</P>
<P>
<PRE>m_pViewWnd-&gt;ReleaseDC(pDC);
</PRE>
<P>At this point, you've drawn the line, so all that's left to do is increment the
minute counter, resetting it if you've made it all the way around the circle. Each
time you complete a circle, you increment the color counter until you've gone through
all eight colors, at which time you reset the color counter.</P>
<P>In order to be able to use the trigonometric functions in this function, include
the math.h header file in the Spinner class source file. To add this, scroll up to
the top of the source code file and add another #include line, specifying the math.h
header file as the file to be included, as in Listing 18.5.</P>
<P>
<H4>LISTING 18.5. THE CSpinner SOURCE FILE.</H4>
<PRE> 1: // Spinner.cpp : implementation of the CSpinner class
 2: //
 3: //////////////////////////////////////////////////////////////////////
 4:
 5: #include &quot;stdafx.h&quot;
 6: #include &lt;math.h&gt;
 7: #include &quot;Tasking.h&quot;
 8: #include &quot;Spinner.h&quot;
</PRE>
<H2><A NAME="Heading8"></A>Supporting the Spinners</H2>
<P>Now that you've created the spinner class for drawing the spinning color wheel
on the window, add some support for the spinners. You can add an array to hold the
four spinners in the document class, but you'll still need to calculate where each
spinner should be placed on the application window and set all the variables in each
of the spinners.</P>
<P>You can add all of this code to the document class, starting with the array of
spinners. Add a member variable to the document class (in this instance, CTaskingDoc),
specifying the type as CSpinner, the name as m_cSpin[4], and the access as private.
Once you add the array, open the source code to the document class and include the
spinner header file, as in Listing 18.6.</P>
<P>
<H4>LISTING 18.6. THE CTaskingDoc SOURCE FILE.</H4>
<PRE> 1: // TaskingDoc.cpp : implementation of the CTaskingDoc class
 2: //
 3: 
 4: #include &quot;stdafx.h&quot;
 5: #include &quot;Tasking.h&quot;
 6: 
 7: #include &quot;Spinner.h&quot;
 8: #include &quot;TaskingDoc.h&quot;
 9: #include &quot;TaskingView.h&quot;
10: .
11: .
12: . 
</PRE>
<H4>Calculating the Spinner Positions</H4>
<P>One of the preparatory things that needs to happen while initializing the application
is determining the locations of all four spinners. The window is roughly broken up
into four quarters by the check boxes that will turn the spinner threads on and off,
so it makes sense to divide the window area into four quarter squares and place one
spinner in each quarter.</P>
<P>To calculate the location of each spinner, it is easiest to create a function
that calculates the location for one spinner, placing the spinner into the quarter
square appropriate for the spinner number. If the function was passed a pointer to
the spinner object, it could update the spinner object directly with the location.</P>
<P>To add this functionality to your application, add a new member function to the
document class (for instance, in the CTaskingDoc class). Specify the function type
as void, the declaration as CalcPoint(int nID, CSpinner *pSpin), and the access as
private. Edit the function, adding the code in Listing 18.7.</P>
<P>
<H4>LISTING 18.7. THE CTaskingDoc CalcPoint FUNCTION.</H4>
<PRE> 1: void CTaskingDoc::CalcPoint(int nID, CSpinner *pSpin)
 2: {
 3:     RECT lWndRect;
 4:     CPoint pPos;
 5:     int iLength;
 6:     CTaskingView *pWnd;
 7: 
 8:     // Get a pointer to the view window
 9:     pWnd = (CTaskingView*)pSpin-&gt;GetViewWnd();
10:     // Get the display area rectangle
11:     pWnd-&gt;GetClientRect(&amp;lWndRect);
12:     // Calculate the size of the spinners
13:     iLength = lWndRect.right / 6;
14:     // Which spinner are we placing?
15:     switch (nID)
16:     {
17:     case 0:    // Position the first spinner
18:         pPos.x = (lWndRect.right / 4) - iLength;
19:         pPos.y = (lWndRect.bottom / 4) - iLength;
20:         break;
21:     case 1:    // Position the second spinner
22:         pPos.x = ((lWndRect.right / 4) * 3) - iLength;
23:         pPos.y = (lWndRect.bottom / 4) - iLength;
24:         break;
25:     case 2:    // Position the third spinner
26:         pPos.x = (lWndRect.right / 4) - iLength;
27:         pPos.y = ((lWndRect.bottom / 4) * 3) - (iLength * 1.25);
28:         break;
29:     case 3:    // Position the fourth spinner
30:         pPos.x = ((lWndRect.right / 4) * 3) - iLength;
31:         pPos.y = ((lWndRect.bottom / 4) * 3) - (iLength * 1.25);
32:         break;
33:     }
34:     // Set the size of the spinner
35:     pSpin-&gt;SetLength(iLength);
36:     // Set the location of the spinner
37:     pSpin-&gt;SetPoint(pPos);
38: }
</PRE>
<P>In this function, the first thing that you do is move the pointer to the view
window from the spinner object by calling the GetViewWnd function:</P>
<P>
<PRE>pWnd = (CTaskingView*)pSpin-&gt;GetViewWnd();
</PRE>
<P>By moving the pointer directly from the spinner object, you save a few steps by
taking a more direct route to get the information that you need.</P>
<P>Once you have a pointer to the view object, you can call the window's GetClientRect
function to get the size of the available drawing area:</P>
<P>
<PRE>pWnd-&gt;GetClientRect(&amp;lWndRect);
</PRE>
<P>Once you have the size of the drawing area, you can calculate a reasonable color
wheel size by dividing the length of the drawing area by 6:</P>
<P>
<PRE>iLength = lWndRect.right / 6;
</PRE>
<P>Dividing the drawing area by 4 will position you at the middle of the upper-left
square. Subtract the size of the circle from this point, and you have the upper-left
corner of the drawing area for the first spinner:</P>
<P>
<PRE>pPos.x = (lWndRect.right / 4) - iLength;
</PRE>
<PRE>pPos.y = (lWndRect.bottom / 4) - iLength;

⌨️ 快捷键说明

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