📄 ch13.htm
字号:
<TT> pDC->SetTextColor( clrOld );</TT>
<TT> pDC->SetBkMode( nOldMode );</TT>
<TT>}</TT> </FONT></PRE>
<P>Most of the earlier version of <TT>OnDraw</TT> can remain in place; only the middle
part of the function has changed between Listings 13.1 and 13.2. The first eight
and the last five lines are the same in both versions.
<H2><FONT COLOR="#000077"><B>Selecting and Configuring the Right Fonts</B></FONT></H2>
<P>The remainder of this hour discusses two ways to simplify and improve your font-handling
code: by using stock fonts provided by Windows and by using the Font Selection common
dialog box. You will also make some changes to the DCTest example so that the user
can select a font for the application.
<H3><FONT COLOR="#000077"><B>Stock Font Objects</B></FONT></H3>
<P>Just as with stock pens and brushes, discussed in Hour 12, Windows maintains a
set of stock fonts. Windows provides six stock fonts:
<UL>
<LI><TT>ANSI_FIXED_FONT</TT>: A fixed-pitch system font.<BR>
<BR>
<LI><TT>ANSI_VAR_FONT</TT>: A variable-pitch system font.<BR>
<BR>
<LI><TT>DEVICE_DEFAULT_FONT</TT>: A device-dependent font. This stock object is available
only on Windows NT.<BR>
<BR>
<LI><TT>DEFAULT_GUI_FONT</TT>: The default font for user interface objects such as
menus and dialog boxes.<BR>
<BR>
<LI><TT>OEM_FIXED_FONT</TT>: The OEM-dependent fixed-pitch font.<BR>
<BR>
<LI><TT>SYSTEM_FONT</TT>: The system font.
</UL>
<P>As with other stock objects, these fonts are used through a <TT>CDC</TT> object
by calling the <TT>SelectStockObject</TT> function, passing the stock object as a
parameter, as follows:</P>
<PRE><FONT COLOR="#0066FF"><TT>CPen* pOldFont = pDC->SelectStockObject(SYSTEM_FONT);</TT>
</FONT></PRE>
<H3><FONT COLOR="#000077"><B>Setting the Font for a Window</B></FONT></H3>
<P>You can change the font used by a control or any other window by calling the <TT>CWnd::SetFont</TT>
function. The <TT>SetFont</TT> function takes a pointer to a <TT>CFont</TT> object
as a parameter:</P>
<PRE><FONT COLOR="#0066FF"><TT>pCtrl->SetFont(fntWingDings);</TT>
</FONT></PRE>
<P>If you change the font for a window, you must be careful to keep the font that
is passed as a parameter valid for as long as the window exists.
<H3><FONT COLOR="#000077"><B>Using the Common Font Dialog Box</B></FONT></H3>
<P>Like the other common dialog boxes, the Common Font dialog box enables you, as
a programmer, to easily use a commonly used dialog box in your Windows programs.
The Common Font dialog box is extremely flexible from a user's point of view; the
user can change the color, style, typeface, and size of the font in a single dialog
box. In this section, you use the Common Font dialog box to select a font to be used
in the view window.</P>
<P>The font is represented by a <TT>LOGFONT</TT> variable that is a member of the
<TT>CDCTestView</TT> class. After selecting a new font with the Common Font dialog
box, the <TT>LOGFONT</TT> variable is updated and the view redrawn.</P>
<P>Five steps are involved in adding support for the Common Font dialog box:
<DL>
<DD>1. Add a new <TT>LOGFONT</TT> variable to the <TT>CDCTestView</TT> class.<BR>
<BR>
2. Modify the <TT>CDCTestView</TT> constructor.<BR>
<BR>
3. Create a new menu item for changing the font.<BR>
<BR>
4. Create a function in the <TT>CDCTestView</TT> class to handle the new menu item.<BR>
<BR>
5. Modify the <TT>CDCTestView::OnDraw</TT> member function so that the new <TT>LOGFONT</TT>
variable is used when creating a font.
</DL>
<P>Just to make things interesting, you modify the <TT>OnDraw</TT> function to display
the text rotated around the center of the view.
<H4><FONT COLOR="#000077">Add a LOGFONT Variable to the CDCTestView Class</FONT></H4>
<P>The first step is to add a <TT>LOGFONT</TT> variable to the <TT>CDCTestView</TT>
class. Although the font is created and destroyed every time the <TT>OnDraw</TT>
member function is called, the <TT>LOGFONT</TT> variable stores the current attributes
for the font selected for the view. Add this line to the attributes section of the
<TT>CDCTestView</TT> class declaration:</P>
<PRE><FONT COLOR="#0066FF"><TT>LOGFONT m_logFont;</TT>
</FONT></PRE>
<P>The <TT>CDCTestView</TT> class constructor must initialize this variable to a
known value. Listing 13.3 contains the source code for the new version of the <TT>CDCTestView</TT>
constructor. Only the last two lines of the source code have been added since the
previous version.
<H4><FONT COLOR="#000077">TYPE: Listing 13.3. Source code to initialize the m_logFont
variable.</FONT></H4>
<PRE><FONT COLOR="#0066FF"><TT>CDCTestView::CDCTestView()</TT>
<TT>{</TT>
<TT> m_nMapMode = MM_TEXT;</TT>
<TT> m_map.SetAt( MM_ANISOTROPIC, "MM_ANISOTROPIC" );</TT>
<TT> m_map.SetAt( MM_HIENGLISH, "MM_HIENGLISH" );</TT>
<TT> m_map.SetAt( MM_HIMETRIC, "MM_HIMETRIC" );</TT>
<TT> m_map.SetAt( MM_ISOTROPIC, "MM_ISOTROPIC" );</TT>
<TT> m_map.SetAt( MM_LOENGLISH, "MM_LOENGLISH" );</TT>
<TT> m_map.SetAt( MM_LOMETRIC, "MM_LOMETRIC" );</TT>
<TT> m_map.SetAt( MM_TEXT, "MM_TEXT" );</TT>
<TT> m_map.SetAt( MM_TWIPS, "MM_TWIPS" );</TT>
<TT> m_cxEllipse = 100;</TT>
<TT> m_cyEllipse = 200;</TT>
<TT> m_clrChoice = RGB(0,0,0);</TT>
<TT> ZeroMemory( &m_logFont, sizeof(LOGFONT) );</TT>
<TT> lstrcpy( m_logFont.lfFaceName, "Arial" );</TT>
<TT>}</TT></FONT></PRE>
<H4><FONT COLOR="#000077">Add a New Menu Item</FONT></H4>
<P>Using the Developer Studio resource editor, add a new menu item to the View menu,
using the values from Table 13.2.
<H4><FONT COLOR="#000077">Table 13.2. Values used for the Font menu item.</FONT></H4>
<P>
<TABLE BORDER="1">
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT" VALIGN="TOP"><B>Resource ID</B></TD>
<TD ALIGN="LEFT" VALIGN="TOP"><B>Caption</B></TD>
<TD ALIGN="LEFT" VALIGN="TOP"><B>Member Function</B></TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT" VALIGN="TOP"><TT>ID_VIEW_FONT</TT></TD>
<TD ALIGN="LEFT" VALIGN="TOP">&Font...</TD>
<TD ALIGN="LEFT" VALIGN="TOP"><TT>CDCTestView::OnViewFont</TT></TD>
</TR>
</TABLE>
</P>
<P>Use ClassWizard to add a message-handling function to the <TT>CDCTestView</TT>
class for the new menu item, using the default name of <TT>OnViewFont</TT>. The source
code for <TT>OnViewFont</TT> is shown in Listing 13.4.
<H4><FONT COLOR="#000077">TYPE: Listing 13.4. The CDCTestView::OnViewFont member
function.</FONT></H4>
<PRE><FONT COLOR="#0066FF"><TT>void CDCTestView::OnViewFont()</TT>
<TT>{</TT>
<TT> CFontDialog dlgFont( &m_logFont );</TT>
<TT> dlgFont.DoModal();</TT>
<TT> m_clrChoice = dlgFont.GetColor();</TT>
<TT> InvalidateRect( NULL );</TT>
</FONT></PRE>
<P><TT>}</TT> The source code in Listing 13.4 is the heart of this example. The current
<TT>LOGFONT</TT> is passed during construction to the Common Font dialog box, which
uses it as a starting point when the dialog box is initially displayed. After the
user dismisses the dialog box, the <TT>LOGFONT</TT> will contain any modifications
made by the user. Because the <TT>LOGFONT</TT> structure doesn't store the text color,
the <TT>GetColor</TT> function is called to update any color selections made in the
Common Font dialog box.
<H4><FONT COLOR="#000077">Modify the OnDraw Member Function</FONT></H4>
<P>The final step in this example is to use the selected font to draw a rotating
text message in the view. The <TT>lfEscapement</TT> field from the <TT>LOGFONT</TT>
structure is used to specify the angle of the text line. The source code in Listing
13.5 updates the font's escapement in a <TT>for</TT> loop, causing the text to rotate.
<H4><FONT COLOR="#000077">TYPE: Listing 13.5. Displaying a rotating text message
using a LOGFONT.</FONT></H4>
<PRE><FONT COLOR="#0066FF"><TT>void CDCTestView::OnDraw(CDC* pDC)</TT>
<TT>{</TT>
<TT> CRect rcClient;</TT>
<TT> GetClientRect( rcClient );</TT>
<TT> pDC->DPtoLP( rcClient );</TT>
<TT> COLORREF clrOld = pDC->SetTextColor( m_clrChoice );</TT>
<TT> int nOldMode = pDC->SetBkMode( TRANSPARENT );</TT>
<TT> CString szMsg = " ...Help! I'm Spinning and I can't get up!";</TT>
<TT> CFont fntRotate;</TT>
<TT> for( int nDegrees = 0; nDegrees < 3600; nDegrees += 200 )</TT>
<TT> {</TT>
<TT> m_logFont.lfEscapement = nDegrees;</TT>
<TT> fntRotate.CreateFontIndirect( &m_logFont );</TT>
<TT> CFont* pOldFont = pDC->SelectObject( &fntRotate );</TT>
<TT> pDC->TextOut( rcClient.Width()/2,</TT>
<TT> rcClient.Height()/2,</TT>
<TT> szMsg );</TT>
<TT> pDC->SelectObject( pOldFont );</TT>
<TT> fntRotate.DeleteObject();</TT>
<TT> }</TT>
<TT> pDC->SetTextColor( clrOld );</TT>
<TT> pDC->SetBkMode( nOldMode );</TT>
</FONT></PRE>
<P><TT>}</TT> The text will rotate around the center of the view, as shown in Figure
13.2. The font and color are updated when a new selection is made in the Common Font
dialog box.</P>
<P><A NAME="02"></A><A HREF="02.htm"><B>Figure 13.2.</B></A> <I><BR>
Displaying rotating text using font escapement.</I>
<H2><FONT COLOR="#000077"><B>Summary</B></FONT></H2>
<P>In this hour you learned about using fonts in Windows programs, as well as how
to use the <TT>CFont</TT> and <TT>CFontDialog</TT> classes. Sample programs illustrated
the use of the <TT>LOGFONT</TT> structure, the use of the Common Font dialog box,
and rotating fonts.
<H2><FONT COLOR="#000077"><B>Q&A</B></FONT></H2>
<DL>
<DD><B>Q I have problems determining the correct text metrics for my device context.
I call <TT>GetTextMetrics</TT> and then select my font into the device context. What
am I doing wrong?</B><BR>
<BR>
<B>A</B> The <TT>GetTextMetrics</TT> function returns information about the currently
selected font--you must select the font into the device context before calling <TT>GetTextMetrics</TT>.<BR>
<BR>
<B>Q When I change the font for a pushbutton control nothing happens--the original
font is still used to display the caption for the button. What am I doing wrong?</B><BR>
<BR>
<B>A</B> This problem is usually due to the <TT>CFont</TT> object being destroyed
before the control is destroyed. The control doesn't copy the font passed to it during
the <TT>SetFont</TT> function call--it must be available as long as the control exists.
If you change the font for a control, you should make the <TT>CFont</TT> object a
member of the <TT>CDialog</TT> derived class that contains the control.
</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. Give some examples of serif and sans-serif fonts.<BR>
<BR>
2. What are the stock font objects maintained by Windows?<BR>
<BR>
3. What is the font escapement attribute used for?<BR>
<BR>
4. What is a glyph?<BR>
<BR>
5. What MFC class is used to manage fonts?<BR>
<BR>
6. What are the six font families?<BR>
<BR>
7. What are the three pitch choices for a font?<BR>
<BR>
8. What function is used to change the font used by a window?
</DL>
<H3><FONT COLOR="#000077"><B>Exercises</B></FONT></H3>
<DL>
<DD>1. Modify the DCTest project so that a different font is used for the Color...
pushbutton.<BR>
<BR>
2. Modify the DCTest project to display text metric information for the currently
selected font.
</DL>
<CENTER>
<P>
<HR>
<A HREF="../ch12/ch12.htm"><IMG SRC="../button/previous.gif" WIDTH="128" HEIGHT="28"
ALIGN="BOTTOM" ALT="Previous chapter" BORDER="0"></A><A HREF="../ch14/ch14.htm"><IMG
SRC="../button/next.gif" WIDTH="128" HEIGHT="28" ALIGN="BOTTOM" ALT="Next chapter"
BORDER="0"></A><A HREF="../index.htm"><IMG SRC="../button/contents.gif" WIDTH="128"
HEIGHT="28" ALIGN="BOTTOM" ALT="Contents" BORDER="0"></A> <BR>
<BR>
<BR>
<IMG SRC="../button/corp.gif" WIDTH="284" HEIGHT="45" ALIGN="BOTTOM" ALT="Macmillan Computer Publishing USA"
BORDER="0"></P>
<P>© <A HREF="../copy.htm">Copyright</A>, Macmillan Computer Publishing. All
rights reserved.
</CENTER>
</BODY>
</HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -