📄 ch11.htm
字号:
<P>Later this hour you will use <TT>GetDeviceCaps</TT> to display this information
in the DCTest example.
<BLOCKQUOTE>
<P>
<HR>
<B> </B><FONT COLOR="#000077"><B>Just a Minute:</B></FONT><B> </B><TT>GetDeviceCaps</TT>
is used primarily when printing; you can use this function to determine whether the
printer supports specific GDI functions. In Hour 21 you will see how <TT>GetDeviceCaps</TT>
is used to determine whether a printer can have bitmaps transferred to it.
<HR>
</BLOCKQUOTE>
<H4><FONT COLOR="#000077">Using the GetTextMetrics Function</FONT></H4>
<P><TT>GetTextMetrics</TT> is used to fill a <TT>TEXTMETRIC</TT> structure with a
variety of information:</P>
<PRE><FONT COLOR="#0066FF"><TT>TEXTMETRIC tm;</TT>
<TT>pDC->GetTextMetrics(&tm);</TT>
</FONT></PRE>
<P>The <TT>TEXTMETRIC</TT> structure has a large number of member variables that
contain information about the currently selected font. The most commonly used members
of the <TT>TEXTMETRIC</TT> structure are shown in Table 11.5.
<H4><FONT COLOR="#000077">Table 11.5. Common member variables of the TEXTMETRIC structure.</FONT></H4>
<P>
<TABLE BORDER="1">
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT" VALIGN="TOP"><B>Member</B></TD>
<TD ALIGN="LEFT" VALIGN="TOP"><B>Specifies...</B></TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT" VALIGN="TOP"><TT>tmAscent</TT></TD>
<TD ALIGN="LEFT" VALIGN="TOP">The number of units above the baseline used by characters in the current font.</TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT" VALIGN="TOP"><TT>TmDescent</TT></TD>
<TD ALIGN="LEFT" VALIGN="TOP">The number of units below the baseline used by characters in the current font.</TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT" VALIGN="TOP"><TT>TmHeight</TT></TD>
<TD ALIGN="LEFT" VALIGN="TOP">The total height for characters in the current font. This value is equal to adding
the <TT>tmAscent</TT> and <TT>tmDescent</TT> values together.</TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT" VALIGN="TOP"><TT>TmInternalLeading</TT></TD>
<TD ALIGN="LEFT" VALIGN="TOP">The area reserved for accent marks and similar marks associated with the font. This
area is inside the <TT>tmAscent</TT> area.</TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT" VALIGN="TOP"><TT>TmExternalLeading</TT></TD>
<TD ALIGN="LEFT" VALIGN="TOP">The area reserved for spacing between lines of text. This area is outside the <TT>tmAscent</TT>
area.</TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT" VALIGN="TOP"><TT>TmAveCharWidth</TT></TD>
<TD ALIGN="LEFT" VALIGN="TOP">The average width for non-bold, non-italic characters in the currently selected font.</TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT" VALIGN="TOP"><TT>TmMaxCharWidth</TT></TD>
<TD ALIGN="LEFT" VALIGN="TOP">The width of the widest character in the currently selected font.</TD>
</TR>
</TABLE>
</P>
<P>To get the height of the currently selected font, call the <TT>GetTextMetrics</TT>
function and use the value stored in the <TT>tmHeight</TT> member variable:</P>
<PRE><FONT COLOR="#0066FF"><TT>TEXTMETRIC tm;</TT>
<TT>pDC->GetTextMetrics(&tm);</TT>
<TT>nFontHeight = tm.tmHeight;</TT>
</FONT></PRE>
<H4><FONT COLOR="#000077">Modifying the CDCTestView Class</FONT></H4>
<P>In order to display information about the current map mode, you must first create
a collection based on <TT>CMap</TT>, one of the template collection classes. The
<TT>CMap</TT> variable, <TT>m_map</TT>, associates an integer map-mode value with
a <TT>CString</TT> object that describes the map mode. As shown in Listing 11.4,
add two new variables to the <TT>CDCTestView</TT> class declaration in the attributes
section.
<H4><FONT COLOR="#000077">TYPE: Listing 11.4. New member variables added to the CDCTestView
class declaration.</FONT></H4>
<PRE><FONT COLOR="#0066FF"><TT>// Attributes</TT>
<TT>private:</TT>
<TT> CMap< int, int, CString, CString > m_map;</TT>
<TT> int m_nMapMode;</TT>
</FONT></PRE>
<P>When using one of the MFC collection classes in a project, you should always add
an <TT>#include "afxtempl.h"</TT> statement to the <TT>stdafx.h</TT> file
in the project directory. This include directive adds the MFC template declarations
to the project's precompiled header, reducing project build time.</P>
<PRE><FONT COLOR="#0066FF"><TT>#include "afxtempl.h"</TT>
</FONT></PRE>
<P>The source code for <TT>CDCTestView::OnDraw</TT> is provided in Listing 11.5.
The current map mode is displayed, along with text and device metrics. The text metrics
vary depending on the current logical mapping mode, while the device measurements
remain constant. Some of the mapping modes will display the information from top
to bottom, whereas some of the modes cause the information to be displayed from bottom
to top.
<H4><FONT COLOR="#000077">TYPE: Listing 11.5. The CDCTestView::OnDraw function.</FONT></H4>
<PRE><FONT COLOR="#0066FF"><TT>void CDCTestView::OnDraw(CDC* pDC)</TT>
<TT>{</TT>
<TT> // Set mapping mode</TT>
<TT> pDC->SetMapMode( m_nMapMode );</TT>
<TT> // Get client rect, and convert to logical coordinates</TT>
<TT> CRect rcClient;</TT>
<TT> GetClientRect( rcClient );</TT>
<TT> pDC->DPtoLP( rcClient );</TT>
<TT> int x = 0;</TT>
<TT> int y = rcClient.bottom/2;</TT>
<TT> CString szOut;</TT>
<TT> m_map.Lookup( m_nMapMode, szOut );</TT>
<TT> pDC->TextOut( x, y, szOut );</TT>
<TT> // Determine the inter-line vertical spacing</TT>
<TT> TEXTMETRIC tm;</TT>
<TT> pDC->GetTextMetrics( &tm );</TT>
<TT> int nCyInterval = tm.tmHeight + tm.tmExternalLeading;</TT>
<TT> y += nCyInterval;</TT>
<TT> szOut.Format( "Character height - %d units", tm.tmHeight );</TT>
<TT> pDC->TextOut( x, y, szOut );</TT>
<TT> y += nCyInterval;</TT>
<TT> szOut.Format( "Average width - %d units", tm.tmAveCharWidth );</TT>
<TT> pDC->TextOut( x, y, szOut );</TT>
<TT> y += nCyInterval;</TT>
<TT> szOut.Format( "Descent space - %d units", tm.tmDescent );</TT>
<TT> pDC->TextOut( x, y, szOut );</TT>
<TT> y += nCyInterval;</TT>
<TT> szOut.Format( "Ascent space - %d units", tm.tmAscent );</TT>
<TT> pDC->TextOut( x, y, szOut );</TT>
<TT> int cxLog = pDC->GetDeviceCaps( LOGPIXELSX );</TT>
<TT> y += nCyInterval;</TT>
<TT> szOut.Format( "%d pixels per logical horiz. inch", cxLog );</TT>
<TT> pDC->TextOut( x, y, szOut );</TT>
<TT> int cyLog = pDC->GetDeviceCaps( LOGPIXELSY );</TT>
<TT> y += nCyInterval;</TT>
<TT> szOut.Format( "%d pixels per logical vert. inch", cyLog );</TT>
<TT> pDC->TextOut( x, y, szOut );</TT>
<TT>}</TT>
</FONT></PRE>
<P>Compile and run the DCTest example. Figure 11.3 shows the DCTest main window,
with device measurements and text metrics displayed.</P>
<P><A NAME="03"></A><A HREF="03.htm" tppabs="http://www.mcp.com/824169600/0-672/0-672-31242-5/ch11/03.htm"><B>Figure 11.3.</B></A> <BR>
<I>Running the DCTest example.</I>
<H2><FONT COLOR="#000077"><B>Using Color in Windows Applications</B></FONT></H2>
<P>As a final topic in this hour, it's important to understand how colors are represented
in Windows applications. Color values are stored in <TT>COLORREF</TT> variables,
which are 32-bit variables defined as</P>
<PRE><FONT COLOR="#0066FF"><TT>typedef DWORD COLORREF;</TT>
</FONT></PRE>
<P>Each <TT>COLORREF</TT> is a 32-bit variable, but only 24 bits are actually used,
with 8 bits reserved. The 24 bits are divided into three 8-bit chunks that represent
the red, green, and blue components of each color.</P>
<P>A <TT>COLORREF</TT> is created using the <TT>RGB</TT> macro, which stands for
Red, Green, and Blue--the three colors used for color output in a Windows program.
The RGB macro takes three parameters, each ranging from 0 to 255, with 255 signifying
that the maximum amount of that color should be included in the <TT>COLORREF</TT>.
For example, to create a <TT>COLORREF</TT> with a white value, the definition would
look like this:</P>
<PRE><FONT COLOR="#0066FF"><TT>COLORREF clrWhite = RGB(255,255,255);</TT>
</FONT></PRE>
<P>For black, the definition would look like this:</P>
<PRE><FONT COLOR="#0066FF"><TT>COLORREF clrBlack = RGB(0,0,0);</TT>
</FONT></PRE>
<P>You can change the current text color used for a device context through the <TT>SetTextColor</TT>
function. <TT>SetTextColor</TT> returns the previous text color used by the device
context.</P>
<P>Listing 11.6 shows two different ways in which you can use the <TT>SetTextColor</TT>
function. The first method uses the <TT>RGB</TT> macro inside the <TT>SetTextColor</TT>
function call; the next method creates a <TT>COLORREF</TT> value that is passed as
a parameter.
<H4><FONT COLOR="#000077">TYPE: Listing 11.6. Changing the text color using the SetTextColor
function.</FONT></H4>
<PRE><FONT COLOR="#0066FF"><TT>// Change text color to pure green</TT>
<TT>COLORREF colorOld = pDC->SetTextColor(RGB(0,255,0));</TT>
<TT>// Change text color to pure blue</TT>
<TT>COLORREF colorBlue = RGB(0,0,255);</TT>
<TT>pDC->SetTextColor(colorBlue);</TT>
<TT>// Restore original text color</TT>
<TT>pDC->SetTextColor(colorOld);</TT>
</FONT></PRE>
<H2><FONT COLOR="#000077"><B>Summary</B></FONT></H2>
<P>In this hour you learned about the Graphics Device Interface, or GDI. You also
learned the basics of the device context, as well as some of the MFC classes that
are used to manage them. You built a sample program that enables you to change and
display information about an output device and its map mode.
<H2><FONT COLOR="#000077"><B>Q&A</B></FONT></H2>
<DL>
<DD><B>Q I'm having trouble drawing an ellipse that is exactly six inches across.
I used <TT>GetDeviceCaps</TT> to retrieve the <TT>LOGPIXELSX</TT> and <TT>LOGPIXELSY</TT>
values, but the image is drawn either too small or too large. How can I draw an image
to an exact physical size?</B><BR>
<BR>
<B>A</B> The <TT>LOGPIXELSX</TT> and <TT>LOGPIXELSY</TT> values are supplied by the
video driver. These values are approximate, and are really just a wild guess. There's
no way to determine the true number of pixels per inch on your display adapter.<BR>
<BR>
<B>Q Why is a <TT>CPaintDC</TT> created and used for <TT>WM_PAINT</TT> messages instead
of a normal <TT>CDC</TT> object?</B><BR>
<BR>
<B>A</B> The <TT>CPaintDC</TT> class is exactly like the <TT>CDC</TT> class, except
that its constructor and destructor do some extra work that is needed when handling
a <TT>WM_PAINT</TT> message. This extra work tells Windows that the window has been
repainted. If a <TT>CDC</TT> object is used, Windows will not be notified that the
window has been repainted, and will continue to send <TT>WM_PAINT</TT> messages.
</DL>
<H2><FONT COLOR="#000077"><B>Workshop</B></FONT></H2>
<P>The Workshop is designed to help you anticipate possible questions, review what
you've learned, and begin thinking ahead to putting your knowledge into practice.
The answers to the quiz are in Appendix B, "Quiz Answers."
<H3><FONT COLOR="#000077"><B>Quiz</B></FONT></H3>
<DL>
<DD>1. What is the difference between a device context and an information device
context?<BR>
<BR>
2. What <TT>CDC</TT> member function is used to select a stock object?<BR>
<BR>
3. How many twips are in an inch?<BR>
<BR>
4. What type of GDI object is used to draw lines?<BR>
<BR>
5. What type of GDI object is used to fill areas?<BR>
<BR>
6. How do you determine the height and other characteristics of characters in the
currently selected font?<BR>
<BR>
7. What is the <TT>RGB</TT> macro used for?<BR>
<BR>
8. What MFC class is used as a base class for all device contexts?<BR>
<BR>
9. How can you tell that a call to <TT>SelectObject</TT> has failed?<BR>
<BR>
10. What mapping mode maps 1 device pixel per measurement unit?
</DL>
<H3><FONT COLOR="#000077"><B>Exercises</B></FONT></H3>
<DL>
<DD>1. Modify the DCTest program to change the color for each line of output.<BR>
<BR>
2. Modify the DCTest program so that every line starts with its x and y coordinates.
</DL>
<CENTER>
<P>
<HR>
<A HREF="ch10.htm" tppabs="http://www.mcp.com/824169600/0-672/0-672-31242-5/ch10/ch10.htm"><IMG SRC="previous.gif" tppabs="http://www.mcp.com/824169600/0-672/0-672-31242-5/button/previous.gif" WIDTH="128" HEIGHT="28"
ALIGN="BOTTOM" ALT="Previous chapter" BORDER="0"></A><A HREF="ch12.htm" tppabs="http://www.mcp.com/824169600/0-672/0-672-31242-5/ch12/ch12.htm"><IMG
SRC="next.gif" tppabs="http://www.mcp.com/824169600/0-672/0-672-31242-5/button/next.gif" WIDTH="128" HEIGHT="28" ALIGN="BOTTOM" ALT="Next chapter"
BORDER="0"></A><A HREF="index-1.htm" tppabs="http://www.mcp.com/824169600/0-672/0-672-31242-5/index.htm"><IMG SRC="contents.gif" tppabs="http://www.mcp.com/824169600/0-672/0-672-31242-5/button/contents.gif" WIDTH="128"
HEIGHT="28" ALIGN="BOTTOM" ALT="Contents" BORDER="0"></A> <BR>
<BR>
<BR>
<IMG SRC="corp.gif" tppabs="http://www.mcp.com/824169600/0-672/0-672-31242-5/button/corp.gif" WIDTH="284" HEIGHT="45" ALIGN="BOTTOM" ALT="Macmillan Computer Publishing USA"
BORDER="0"></P>
<P>© <A HREF="copy.htm" tppabs="http://www.mcp.com/824169600/0-672/0-672-31242-5/copy.htm">Copyright</A>, Macmillan Computer Publishing. All
rights reserved.
</CENTER>
</BODY>
</HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -