This example sets up a view window with the logical twips mapping mode. A text string is displayed in 10 point sizes with the Arial TrueType font. Here are the steps for building the application:
void CEx05aView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo) { pDC->SetMapMode(MM_ANISOTROPIC); pDC->SetWindowExt(1440, 1440); pDC->SetViewportExt(pDC->GetDeviceCaps(LOGPIXELSX), -pDC->GetDeviceCaps(LOGPIXELSY)); }
private: void ShowFont(CDC* pDC, int& nPos, int nPoints);
Then add the function itself in ex05aView.cpp:
void CEx05aView::ShowFont(CDC* pDC, int& nPos, int nPoints) { TEXTMETRIC tm; CFont fontText; CString strText; CSize sizeText; fontText.CreateFont(-nPoints * 20, 0, 0, 0, 400, FALSE, FALSE, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, "Arial"); CFont* pOldFont = (CFont*) pDC->SelectObject(&fontText); pDC->GetTextMetrics(&tm); TRACE("points = %d, tmHeight = %d, tmInternalLeading = %d," " tmExternalLeading = %d\n", nPoints, tm.tmHeight, tm.tmInternalLeading, tm.tmExternalLeading); strText.Format("This is %d-point Arial", nPoints); sizeText = pDC->GetTextExtent(strText); TRACE("string width = %d, string height = %d\n", sizeText.cx, sizeText.cy); pDC->TextOut(0, nPos, strText); pDC->SelectObject(pOldFont); nPos -= tm.tmHeight + tm.tmExternalLeading; }
void CEx05aView::OnDraw(CDC* pDC) { int nPosition = 0; for (int i = 6; i <= 24; i += 2) { ShowFont(pDC, nPosition, i); } TRACE("LOGPIXELSX = %d, LOGPIXELSY = %d\n", pDC->GetDeviceCaps(LOGPIXELSX), pDC->GetDeviceCaps(LOGPIXELSY)); TRACE("HORZSIZE = %d, VERTSIZE = %d\n", pDC->GetDeviceCaps(HORZSIZE), pDC->GetDeviceCaps(VERTSIZE)); TRACE("HORZRES = %d, VERTRES = %d\n", pDC->GetDeviceCaps(HORZRES), pDC->GetDeviceCaps(VERTRES)); }
The resulting output (assuming the use of a standard VGA card) looks like the screen shown here.
Notice that the output string sizes don't quite correspond to the point sizes. This discrepancy results from the font engine's conversion of logical units to pixels. The program's trace output, partially shown below, shows the printout of font metrics. (The numbers depend on your display driver and your video driver.)
points = 6, tmHeight = 150, tmInternalLeading = 30, tmExternalLeading = 4 string width = 990, string height = 150 points = 8, tmHeight = 210, tmInternalLeading = 45, tmExternalLeading = 5 string width = 1380, string height = 210 points = 10, tmHeight = 240, tmInternalLeading = 45, tmExternalLeading = 6 string width = 1770, string height = 240 points = 12, tmHeight = 270, tmInternalLeading = 30, tmExternalLeading = 8 string width = 2130, string height = 270
Following is a discussion of the important elements in the EX05A example.
Setting the Mapping Mode in the OnPrepareDC Function
The application framework calls OnPrepareDC prior to calling OnDraw, so the OnPrepareDC function is the logical place to prepare the device context. If you had other message handlers that needed the correct mapping mode, those functions would have contained calls to
OnPrepareDC.
The ShowFont Private Member Function
ShowFont contains code that is executed 10 times in a loop. With C, you would have made this a global function, but with C++ it's better to make it a private class member function, sometimes known as a helper function.
This function creates the font, selects it into the device context, prints
a string to the window, and then deselects the font. If you choose to include
debug information in the program, ShowFont also displays useful font metrics information, including the actual width of the string.
Calling CFont::CreateFont
This call includes lots of parameters, but the important ones are the first twothe font height and width. A width value of 0 means that the aspect ratio of the selected font will be set to a value specified by the font designer. If you put a nonzero value here, as you'll see in the next example, you can change the font's aspect ratio.
If you want your font to be a specific point size, the CreateFont font height parameter (the first parameter) must be negative. If you're using the MM_TWIPS mapping mode for a printer, for example, a height parameter of -240 ensures a true 12-point font, with tmHeight - tmInternalLeading = 240. A +240 height parameter gives you a smaller font, with tmHeight = 240.
The last CreateFont parameter specifies the font name, in this case the Arial TrueType font. If you had used NULL for this parameter, the FF_SWISS specification (which indicates a proportional font without serifs) would have caused Windows to choose the best matching font, which, depending on the specified size, might have been the System font or the Arial TrueType font. The font name takes precedence. If you had specified FF_ROMAN (which indicates a proportional font with serifs) with Arial, for example, you would have gotten Arial.