- Table of Contents
- Copyright
- About the Authors
- About the Contributors
- Acknowledgments
- Tell Us What You Think!
- Introduction
- How to Use This Book
- What You Need to Use This Book
- What's New in Visual C++ 6.0
- Contacting the Main Author
- Part I: Introduction
- Chapter 1. The Visual C++ 6.0 Environment
- Part II: MFC Programming
- Chapter 2. MFC Class Library Overview
- Chapter 3. MFC Message Handling Mechanism
- Chapter 4. The Document View Architecture
- Chapter 5. Creating and Using Dialog Boxes
- Chapter 6. Working with Device Contexts and GDI Objects
- Chapter 7. Creating and Using Property Sheets
- Chapter 8. Working with the File System
- Chapter 9. Using Serialization with File and Archive Objects
- Part III: Internet Programming with MFC
- Chapter 10. MFC and the Internet Server API (ISAPI)
- Chapter 11. The WinInet API
- Chapter 12. MFC HTML Support
- Part IV: Advanced Programming Topics
- Chapter 13. Using the Standard C++ Library
- Chapter 14. Error Detection and Exception Handling Techniques
- Chapter 15. Debugging and Profiling Strategies
- Chapter 16. Multithreading
- Chapter 17. Using Scripting and Other Tools to Automate the Visual C++ IDE
- Part V: Database Programming
- Chapter 18. Creating Custom AppWizards
- Chapter 19. Database Overview
- Chapter 20. ODBC Programming
- Chapter 21. MFC Database Classes
- Chapter 22. Using OLE DB
- Chapter 23. Programming with ADO
- Part VI: MFC Support for COM and ActiveX
- Chapter 24. Overview of COM and Active Technologies
- Chapter 25. Active Documents
- Chapter 26. Active Containers
- Chapter 27. Active Servers
- Chapter 28. ActiveX Controls
- Part VII: Using the Active Template Library
- Chapter 29. ATL Architecture
- Chapter 30. Creating COM Objects Using ATL
- Chapter 31. Creating ActiveX Controls Using ATL
- Chapter 32. Using ATL to Create MTS and COM+ Components
- Part VIII: Finishing Touches
- Chapter 33. Adding Windows Help
- Part IX: Appendix
Working with Fonts
Much of Windows graphical output consists of text in a variety of fonts. Like pens, brushes, and regions, a GDI handle (HFONT) also represents font object instances.
The fonts and their related rendering data for each character make a considerable memory footprint for each instance of a font object. To reduce the overhead of memory and processing time required to load, initialize, and store the details for each instance of a font, Windows uses a font mapper.
Whenever a new font object is created, the font mapper looks for the nearest match of the requested characteristics from the list of installed fonts. It then constructs a font that is as close as possible to the one you have requested.
Fonts and the CFont Class
The MFC CFont class is a wrapper for the HFONT GDI object. To create a font using CFont, you first must construct a CFont object with the default constructor and then call one of the font-creation routines.
The quickest and easiest way to create a font is with CFont's CreatePointFont() function. You can pass a desired point size (in tenths of a point), a typeface name, and optionally a reference device context pointer to create the font. You should pass a pointer to the device context to create an accurate point-size match. Otherwise, the default screen device context is used (which is inaccurate when printing).
You also can use CreatePointFontIndirect() to create a font from the lfHeight member set in a LOGFONT structure.
A much more sophisticated font-creation function is CreateFont(), which lets you specify a huge number of required attributes for the font. These attributes specify the width, height, escapement, orientation, weight, effects, character set, clipping, rendering precision, font family, pitch, and typeface with its 14 parameters. The orientation and escapement attributes are closely related. The orientation attribute refers to the rotation angle of each individual character. The escapement is similar, but refers to the entire line of text. On Windows 95/98, these values must be set to the same value. On Windows NT/2000, these values may be set independently of each other.
Each of these parameters has several associated flag values to hone the type of font required. The font mapper then uses all these attributes to try to find the best matching font for the requested specifications.
You can initialize the LOGFONT structure with these specifications and pass a pointer to the LOGFONT structure to the CreateFontIndirect() function, which then creates a font and returns a font handle. This creation form is especially useful when you have enumerated the currently installed fonts with one of the font-enumeration functions, such as EnumFonts(). The callback functions for these enumerators are passed a pointer to a LOGFONT structure so that you can create a font object instance directly from it.
After a LOGFONT structure is initialized, you can fill it with the details of a font by using the GetLogFont() function.
The CFont class also has an HFONT operator to retrieve the underlying GDI handle when cast as an HFONT.
Selecting Fonts into the Device Context
As with the other GDI objects, a font must be selected into the device context before you can use it, and the previously selected font is restored after use. You must ensure that the font is not currently selected in a device context when it is deleted.
After the font is selected, it is used whenever any of the text-output functions are called.
Stock Fonts
A number of stock fonts can be selected with the SelectStockObject() function, as Table 6.8 shows.
Table 6.8. Stock Font Objects
| Stock Object Flag | Font Description |
| ANSI_FIXED_FONT | ANSI fixed pitch |
| ANSI_VAR_FONT | ANSI variable pitch |
| SYSTEM_FONT | Current Windows system font |
| DEVICE_DEFAULT_FONT | Device's default font |
| OEM_FIXED_FONT | OEM's fixed-pitch font |
Device Context Font Interrogation Functions
The device context has a number of member functions that let you retrieve information regarding the currently selected font.
With variable-pitch fonts, you may need to know about the average and specific widths of characters when rendered in a specific device context. You can use the GetCharWidth() function to fill an array with the widths of individual characters for non-TrueType fonts or GetABCCharWidths() for TrueType fonts.
You can find the average widths, height, and many other specific elements of a font from its TEXTMETRICS structure. The device context's GetOutputTextMetrics() function fills such a structure for you with details of the currently selected font.
You can retrieve the typeface name of the currently selected font by calling the GetTextFace() function and passing a CString object by reference to receive the typeface name.
Kerning pairs specify the width between two characters placed together in a variable-pitch font. These values often may be negative, because characters such as l and i are thin and can be placed close together. The GetKerningPairs() function can fill an array of KERNINGPAIR structures to retrieve this information.
The GetOutlineTextMetrics() function returns an array of OUTLINETEXTMETRICS structures. These structures are full of information about TrueType fonts.
Text-Rendering Functions
Many text-rendering functions are available that perform slightly different jobs in different circumstances. The simplest is TextOut(), which lets you specify an x and y coordinate and a CString holding the text to display.
The device context's text-alignment flags adjust the position of the text relative to the given coordinate. You can adjust these flags by using the SetTextAlign() function and passing a combination of the alignment flags, such as TA_TOP, TA_CENTER, TA_RIGHT, TA_LEFT, TA_BASELINE, and TA_BOTTOM. You can combine this flag value with the TA_NOUPDATECP and TA_UPDATECP to not update or update the current graphic cursor position after the text rendering. The corresponding GetTextAlign() returns the current flag settings.
You can change the color of the rendered text with the device context's SetTextColor() and SetBkColor() functions to set the foreground and background colors to a specified COLORREF value. You can make the background behind the text transparent or opaque by passing the TRANSPARENT or OPAQUE flag to the SetBkMode() function.
The ExtTextOut() function lets you clip text to a specified rectangle by using the ETO_CLIPPED flag. You can supply an array of spacing values to separate the individual character cells to ExtTextOut().
You can use TabbedTextout() to display a text string with embedded tab characters. These tabs then are expanded to positions specified by an array of consecutive tab positions relative to a specified origin.
The DrawText() function performs some quite advanced text formatting, such as word wrapping and justification. You can pass a combination of formatting flag values, such as DT_WORDBREAK, DT_LEFT, DT_RIGHT, DT_TOP, and DT_CENTER (and many others).
You can call the GrayString() function to draw grayed text using a specific graying brush and optionally pass a pointer to your own text-rendering function.
You often will want to know the dimensions required by a text string without actually rendering it. You can find these dimensions by using the GetOutputTextExtent(), GetTabbedTextExtent(), or GetOutputTabbedTextExtent() function. These functions use the device context to calculate and return a CSize object holding the size required to render the text using the currently selected font and device-context settings.
Creating and Loading Bitmaps | Next Section

Account Sign In
View your cart