17.3 逻辑字体


17.3.1 逻辑字体的创建和选择

(1)创建逻辑字体 hFont= CreateFontIndirect(&lf); //其中LOGFONT为结构体

(2)SelectObject(hdc,hFont); //选入并匹配字体或使用从ChooseFont中选择的字体

(3)返回选入设备环境的字体信息:

①GetTextFace(hdc,sizeof(szFaceName)/sizeof(TCHAR),szFaceName);//返回字样名称

②GetTextMetrics(hdc,&tm); //注意:TEXTMETRIC结构体和LOGFONT的不同。

17.3.2 PICKFONT程序

第17章 文本和字体_17.3 逻辑字体_ico



/*-----------------------------------------
PICKFONT.C -- Create Logical Font
(c) Charles Petzold, 1998
-----------------------------------------*/

#include <windows.h>
#include "resource.h"

// Structure shared between main window and dialog box

typedef struct
{
int iDevice, iMapMode ;
BOOL fMatchAspect ;
BOOL fAdvGraphics ;
LOGFONT lf ;
TEXTMETRIC tm ;
TCHAR szFaceName [LF_FULLFACESIZE] ;
}
DLGPARAMS ;

// Formatting for BCHAR fields of TEXTMETRIC structure

#ifdef UNICODE
#define BCHARFORM TEXT ("0x%04X")
#else
#define BCHARFORM TEXT ("0x%02X")
#endif

// Global variables

HWND hdlg ;
TCHAR szAppName[] = TEXT ("PickFont") ;

// Forward declarations of functions

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
BOOL CALLBACK DlgProc (HWND, UINT, WPARAM, LPARAM) ;
void SetLogFontFromFields (HWND hdlg, DLGPARAMS * pdp) ;
void SetFieldsFromTextMetric (HWND hdlg, DLGPARAMS * pdp) ;
void MySetMapMode (HDC hdc, int iMapMode) ;

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
HWND hwnd ;
MSG msg ;
WNDCLASS wndclass ;

wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = szAppName ;
wndclass.lpszClassName = szAppName ;

if (!RegisterClass (&wndclass))
{
MessageBox (NULL, TEXT ("This program requires Windows NT!"),
szAppName, MB_ICONERROR) ;
return 0 ;
}

hwnd = CreateWindow (szAppName, TEXT ("PickFont: Create Logical Font"),
WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL) ;

ShowWindow (hwnd, iCmdShow) ;
UpdateWindow (hwnd) ;

while (GetMessage (&msg, NULL, 0, 0))
{
if (hdlg == 0 || !IsDialogMessage (hdlg, &msg))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
}
return msg.wParam ;
}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static DLGPARAMS dp ;
static TCHAR szText[] = TEXT ("\x41\x42\x43\x44\x45 ")
TEXT ("\x61\x62\x63\x64\x65 ")

TEXT ("\xC0\xC1\xC2\xC3\xC4\xC5 ")
TEXT ("\xE0\xE1\xE2\xE3\xE4\xE5 ")
#ifdef UNICODE
TEXT ("\x0390\x0391\x0392\x0393\x0394\x0395 ")
TEXT ("\x03B0\x03B1\x03B2\x03B3\x03B4\x03B5 ")

TEXT ("\x0410\x0411\x0412\x0413\x0414\x0415 ")
TEXT ("\x0430\x0431\x0432\x0433\x0434\x0435 ")

TEXT ("\x5000\x5001\x5002\x5003\x5004")
#endif
;
HDC hdc ;
PAINTSTRUCT ps ;
RECT rect ;

switch (message)
{
case WM_CREATE:
dp.iDevice = IDM_DEVICE_SCREEN ;

hdlg = CreateDialogParam (((LPCREATESTRUCT) lParam)->hInstance,
szAppName, hwnd, DlgProc, (LPARAM) &dp) ;
return 0 ;

case WM_SETFOCUS:
SetFocus (hdlg) ;
return 0 ;

case WM_COMMAND:
switch (LOWORD (wParam))
{
case IDM_DEVICE_SCREEN:
case IDM_DEVICE_PRINTER:
CheckMenuItem (GetMenu (hwnd), dp.iDevice, MF_UNCHECKED) ;
dp.iDevice = LOWORD (wParam) ;
CheckMenuItem (GetMenu (hwnd), dp.iDevice, MF_CHECKED) ;
SendMessage (hwnd, WM_COMMAND, IDOK, 0) ;
return 0 ;
}
break ;

case WM_PAINT:
hdc = BeginPaint (hwnd, &ps) ;

// Set graphics mode so escapement works in Windows NT

SetGraphicsMode (hdc, dp.fAdvGraphics ? GM_ADVANCED : GM_COMPATIBLE) ;

// Set the mapping mode and the mapper flag

MySetMapMode (hdc, dp.iMapMode) ;
SetMapperFlags (hdc, dp.fMatchAspect) ;

// Find the point to begin drawing text

GetClientRect (hdlg, &rect) ;
rect.bottom += 1 ;
DPtoLP (hdc, (PPOINT) &rect, 2) ;

// Create and select the font; display the text

SelectObject (hdc, CreateFontIndirect (&dp.lf)) ;
TextOut (hdc, rect.left, rect.bottom, szText, lstrlen (szText)) ;

DeleteObject (SelectObject (hdc, GetStockObject (SYSTEM_FONT))) ;
EndPaint (hwnd, &ps) ;
return 0 ;

case WM_DESTROY:
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}

BOOL CALLBACK DlgProc (HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
{
static DLGPARAMS * pdp ;
static PRINTDLG pd = { sizeof (PRINTDLG) } ;
HDC hdcDevice ;
HFONT hFont ;

switch (message)
{
case WM_INITDIALOG:
// Save pointer to dialog-parameters structure in WndProc

pdp = (DLGPARAMS *) lParam ;

SendDlgItemMessage (hdlg, IDC_LF_FACENAME, EM_LIMITTEXT,
LF_FACESIZE - 1, 0) ;

CheckRadioButton (hdlg, IDC_OUT_DEFAULT, IDC_OUT_OUTLINE,
IDC_OUT_DEFAULT) ;

CheckRadioButton (hdlg, IDC_DEFAULT_QUALITY, IDC_PROOF_QUALITY,
IDC_DEFAULT_QUALITY) ;

CheckRadioButton (hdlg, IDC_DEFAULT_PITCH, IDC_VARIABLE_PITCH,
IDC_DEFAULT_PITCH) ;

CheckRadioButton (hdlg, IDC_FF_DONTCARE, IDC_FF_DECORATIVE,
IDC_FF_DONTCARE) ;

CheckRadioButton (hdlg, IDC_MM_TEXT, IDC_MM_LOGTWIPS,
IDC_MM_TEXT) ;

SendMessage (hdlg, WM_COMMAND, IDOK, 0) ;

// fall through
case WM_SETFOCUS:
SetFocus (GetDlgItem (hdlg, IDC_LF_HEIGHT)) ;
return FALSE ;

case WM_COMMAND:
switch (LOWORD (wParam))
{
case IDC_CHARSET_HELP:
MessageBox (hdlg,
TEXT ("0 = Ansi\n")
TEXT ("1 = Default\n")
TEXT ("2 = Symbol\n")
TEXT ("128 = Shift JIS (Japanese)\n")
TEXT ("129 = Hangul (Korean)\n")
TEXT ("130 = Johab (Korean)\n")
TEXT ("134 = GB 2312 (Simplified Chinese)\n")
TEXT ("136 = Chinese Big 5 (Traditional Chinese)\n")
TEXT ("177 = Hebrew\n")
TEXT ("178 = Arabic\n")
TEXT ("161 = Greek\n")
TEXT ("162 = Turkish\n")
TEXT ("163 = Vietnamese\n")
TEXT ("204 = Russian\n")
TEXT ("222 = Thai\n")
TEXT ("238 = East European\n")
TEXT ("255 = OEM"),
szAppName, MB_OK | MB_ICONINFORMATION) ;
return TRUE ;

// These radio buttons set the lfOutPrecision field

case IDC_OUT_DEFAULT:
pdp->lf.lfOutPrecision = OUT_DEFAULT_PRECIS ;
return TRUE ;

case IDC_OUT_STRING:
pdp->lf.lfOutPrecision = OUT_STRING_PRECIS ;
return TRUE ;

case IDC_OUT_CHARACTER:
pdp->lf.lfOutPrecision = OUT_CHARACTER_PRECIS ;
return TRUE ;

case IDC_OUT_STROKE:
pdp->lf.lfOutPrecision = OUT_STROKE_PRECIS ;
return TRUE ;

case IDC_OUT_TT:
pdp->lf.lfOutPrecision = OUT_TT_PRECIS ;
return TRUE ;

case IDC_OUT_DEVICE:
pdp->lf.lfOutPrecision = OUT_DEVICE_PRECIS ;
return TRUE ;

case IDC_OUT_RASTER:
pdp->lf.lfOutPrecision = OUT_RASTER_PRECIS ;
return TRUE ;

case IDC_OUT_TT_ONLY:
pdp->lf.lfOutPrecision = OUT_TT_ONLY_PRECIS ;
return TRUE ;

case IDC_OUT_OUTLINE:
pdp->lf.lfOutPrecision = OUT_OUTLINE_PRECIS ;
return TRUE ;

// These three radio buttons set the lfQuality field

case IDC_DEFAULT_QUALITY:
pdp->lf.lfQuality = DEFAULT_QUALITY ;
return TRUE ;

case IDC_DRAFT_QUALITY:
pdp->lf.lfQuality = DRAFT_QUALITY ;
return TRUE ;

case IDC_PROOF_QUALITY:
pdp->lf.lfQuality = PROOF_QUALITY ;
return TRUE ;

// These three radio buttons set the lower nibble
// of the lfPitchAndFamily field

case IDC_DEFAULT_PITCH:
pdp->lf.lfPitchAndFamily = (BYTE)
((0xF0 & pdp->lf.lfPitchAndFamily) | DEFAULT_PITCH) ;
return TRUE ;

case IDC_FIXED_PITCH:
pdp->lf.lfPitchAndFamily = (BYTE)
((0xF0 & pdp->lf.lfPitchAndFamily) | FIXED_PITCH) ;
return TRUE ;

case IDC_VARIABLE_PITCH:
pdp->lf.lfPitchAndFamily = (BYTE)
((0xF0 & pdp->lf.lfPitchAndFamily) | VARIABLE_PITCH) ;
return TRUE ;

// These six radio buttons set the upper nibble
// of the lpPitchAndFamily field

case IDC_FF_DONTCARE:
pdp->lf.lfPitchAndFamily = (BYTE)
((0x0F & pdp->lf.lfPitchAndFamily) | FF_DONTCARE) ;
return TRUE ;

case IDC_FF_ROMAN:
pdp->lf.lfPitchAndFamily = (BYTE)
((0x0F & pdp->lf.lfPitchAndFamily) | FF_ROMAN) ;
return TRUE ;

case IDC_FF_SWISS:
pdp->lf.lfPitchAndFamily = (BYTE)
((0x0F & pdp->lf.lfPitchAndFamily) | FF_SWISS) ;
return TRUE ;

case IDC_FF_MODERN:
pdp->lf.lfPitchAndFamily = (BYTE)
((0x0F & pdp->lf.lfPitchAndFamily) | FF_MODERN) ;
return TRUE ;

case IDC_FF_SCRIPT:
pdp->lf.lfPitchAndFamily = (BYTE)
((0x0F & pdp->lf.lfPitchAndFamily) | FF_SCRIPT) ;
return TRUE ;

case IDC_FF_DECORATIVE:
pdp->lf.lfPitchAndFamily = (BYTE)
((0x0F & pdp->lf.lfPitchAndFamily) | FF_DECORATIVE) ;
return TRUE ;

// Mapping mode:

case IDC_MM_TEXT:
case IDC_MM_LOMETRIC:
case IDC_MM_HIMETRIC:
case IDC_MM_LOENGLISH:
case IDC_MM_HIENGLISH:
case IDC_MM_TWIPS:
case IDC_MM_LOGTWIPS:
pdp->iMapMode = LOWORD (wParam) ;
return TRUE ;

// OK button pressed
// -----------------

case IDOK:
// Get LOGFONT structure

SetLogFontFromFields (hdlg, pdp) ;

// Set Match-Aspect and Advanced Graphics flags

pdp->fMatchAspect = IsDlgButtonChecked (hdlg, IDC_MATCH_ASPECT) ;
pdp->fAdvGraphics = IsDlgButtonChecked (hdlg, IDC_ADV_GRAPHICS) ;

// Get Information Context

if (pdp->iDevice == IDM_DEVICE_SCREEN)
{
hdcDevice = CreateIC (TEXT ("DISPLAY"), NULL, NULL, NULL) ;
}
else
{
pd.hwndOwner = hdlg ;
pd.Flags = PD_RETURNDEFAULT | PD_RETURNIC ;
pd.hDevNames = NULL ;
pd.hDevMode = NULL ;

PrintDlg (&pd) ;

hdcDevice = pd.hDC ;
}
// Set the mapping mode and the mapper flag

MySetMapMode (hdcDevice, pdp->iMapMode) ;
SetMapperFlags (hdcDevice, pdp->fMatchAspect) ;

// Create font and select it into IC

hFont = CreateFontIndirect (&pdp->lf) ;
SelectObject (hdcDevice, hFont) ;

// Get the text metrics and face name

GetTextMetrics (hdcDevice, &pdp->tm) ;
GetTextFace (hdcDevice, LF_FULLFACESIZE, pdp->szFaceName) ;
DeleteDC (hdcDevice) ;
DeleteObject (hFont) ;

// Update dialog fields and invalidate main window

SetFieldsFromTextMetric (hdlg, pdp) ;
InvalidateRect (GetParent (hdlg), NULL, TRUE) ;
return TRUE ;
}
break ;
}
return FALSE ;
}
void SetLogFontFromFields (HWND hdlg, DLGPARAMS * pdp)
{
pdp->lf.lfHeight = GetDlgItemInt (hdlg, IDC_LF_HEIGHT, NULL, TRUE) ;
pdp->lf.lfWidth = GetDlgItemInt (hdlg, IDC_LF_WIDTH, NULL, TRUE) ;
pdp->lf.lfEscapement = GetDlgItemInt (hdlg, IDC_LF_ESCAPE, NULL, TRUE) ;
pdp->lf.lfOrientation = GetDlgItemInt (hdlg, IDC_LF_ORIENT, NULL, TRUE) ;
pdp->lf.lfWeight = GetDlgItemInt (hdlg, IDC_LF_WEIGHT, NULL, TRUE) ;
pdp->lf.lfCharSet = GetDlgItemInt (hdlg, IDC_LF_CHARSET, NULL, FALSE) ;

pdp->lf.lfItalic =
IsDlgButtonChecked (hdlg, IDC_LF_ITALIC) == BST_CHECKED ;
pdp->lf.lfUnderline =
IsDlgButtonChecked (hdlg, IDC_LF_UNDER) == BST_CHECKED ;
pdp->lf.lfStrikeOut =
IsDlgButtonChecked (hdlg, IDC_LF_STRIKE) == BST_CHECKED ;

GetDlgItemText (hdlg, IDC_LF_FACENAME, pdp->lf.lfFaceName, LF_FACESIZE) ;
}

void SetFieldsFromTextMetric (HWND hdlg, DLGPARAMS * pdp)
{
TCHAR szBuffer [10] ;
TCHAR * szYes = TEXT ("Yes") ;
TCHAR * szNo = TEXT ("No") ;
TCHAR * szFamily [] = { TEXT ("Don't Know"), TEXT ("Roman"),
TEXT ("Swiss"), TEXT ("Modern"),
TEXT ("Script"), TEXT ("Decorative"),
TEXT ("Undefined") } ;

SetDlgItemInt (hdlg, IDC_TM_HEIGHT, pdp->tm.tmHeight, TRUE) ;
SetDlgItemInt (hdlg, IDC_TM_ASCENT, pdp->tm.tmAscent, TRUE) ;
SetDlgItemInt (hdlg, IDC_TM_DESCENT, pdp->tm.tmDescent, TRUE) ;
SetDlgItemInt (hdlg, IDC_TM_INTLEAD, pdp->tm.tmInternalLeading, TRUE) ;
SetDlgItemInt (hdlg, IDC_TM_EXTLEAD, pdp->tm.tmExternalLeading, TRUE) ;
SetDlgItemInt (hdlg, IDC_TM_AVECHAR, pdp->tm.tmAveCharWidth, TRUE) ;
SetDlgItemInt (hdlg, IDC_TM_MAXCHAR, pdp->tm.tmMaxCharWidth, TRUE) ;
SetDlgItemInt (hdlg, IDC_TM_WEIGHT, pdp->tm.tmWeight, TRUE) ;
SetDlgItemInt (hdlg, IDC_TM_OVERHANG, pdp->tm.tmOverhang, TRUE) ;
SetDlgItemInt (hdlg, IDC_TM_DIGASPX, pdp->tm.tmDigitizedAspectX, TRUE) ;
SetDlgItemInt (hdlg, IDC_TM_DIGASPY, pdp->tm.tmDigitizedAspectY, TRUE) ;

wsprintf (szBuffer, BCHARFORM, pdp->tm.tmFirstChar) ;
SetDlgItemText (hdlg, IDC_TM_FIRSTCHAR, szBuffer) ;

wsprintf (szBuffer, BCHARFORM, pdp->tm.tmLastChar) ;
SetDlgItemText (hdlg, IDC_TM_LASTCHAR, szBuffer) ;

wsprintf (szBuffer, BCHARFORM, pdp->tm.tmDefaultChar) ;
SetDlgItemText (hdlg, IDC_TM_DEFCHAR, szBuffer) ;

wsprintf (szBuffer, BCHARFORM, pdp->tm.tmBreakChar) ;
SetDlgItemText (hdlg, IDC_TM_BREAKCHAR, szBuffer) ;

SetDlgItemText (hdlg, IDC_TM_ITALIC, pdp->tm.tmItalic ? szYes : szNo) ;
SetDlgItemText (hdlg, IDC_TM_UNDER, pdp->tm.tmUnderlined ? szYes : szNo) ;
SetDlgItemText (hdlg, IDC_TM_STRUCK, pdp->tm.tmStruckOut ? szYes : szNo) ;

SetDlgItemText (hdlg, IDC_TM_VARIABLE,
TMPF_FIXED_PITCH & pdp->tm.tmPitchAndFamily ? szYes : szNo) ;

SetDlgItemText (hdlg, IDC_TM_VECTOR,
TMPF_VECTOR & pdp->tm.tmPitchAndFamily ? szYes : szNo) ;

SetDlgItemText (hdlg, IDC_TM_TRUETYPE,
TMPF_TRUETYPE & pdp->tm.tmPitchAndFamily ? szYes : szNo) ;

SetDlgItemText (hdlg, IDC_TM_DEVICE,
TMPF_DEVICE & pdp->tm.tmPitchAndFamily ? szYes : szNo) ;

SetDlgItemText (hdlg, IDC_TM_FAMILY,
szFamily [min (6, pdp->tm.tmPitchAndFamily >> 4)]) ;

SetDlgItemInt (hdlg, IDC_TM_CHARSET, pdp->tm.tmCharSet, FALSE) ;
SetDlgItemText (hdlg, IDC_TM_FACENAME, pdp->szFaceName) ;
}

void MySetMapMode (HDC hdc, int iMapMode)
{
switch (iMapMode)
{
case IDC_MM_TEXT: SetMapMode (hdc, MM_TEXT) ; break ;
case IDC_MM_LOMETRIC: SetMapMode (hdc, MM_LOMETRIC) ; break ;
case IDC_MM_HIMETRIC: SetMapMode (hdc, MM_HIMETRIC) ; break ;
case IDC_MM_LOENGLISH: SetMapMode (hdc, MM_LOENGLISH) ; break ;
case IDC_MM_HIENGLISH: SetMapMode (hdc, MM_HIENGLISH) ; break ;
case IDC_MM_TWIPS: SetMapMode (hdc, MM_TWIPS) ; break ;
case IDC_MM_LOGTWIPS:
SetMapMode (hdc, MM_ANISOTROPIC) ;
SetWindowExtEx (hdc, 1440, 1440, NULL) ;
SetViewportExtEx (hdc, GetDeviceCaps (hdc, LOGPIXELSX),
GetDeviceCaps (hdc, LOGPIXELSY), NULL) ;
break ;
}
}


//resource.h



//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by PickFont.rc
//
#define IDC_LF_HEIGHT 1000
#define IDC_LF_WIDTH 1001
#define IDC_LF_ESCAPE 1002
#define IDC_LF_ORIENT 1003
#define IDC_LF_WEIGHT 1004
#define IDC_MM_TEXT 1005
#define IDC_MM_LOMETRIC 1006
#define IDC_MM_HIMETRIC 1007
#define IDC_MM_LOENGLISH 1008
#define IDC_MM_HIENGLISH 1009
#define IDC_MM_TWIPS 1010
#define IDC_MM_LOGTWIPS 1011
#define IDC_LF_ITALIC 1012
#define IDC_LF_UNDER 1013
#define IDC_LF_STRIKE 1014
#define IDC_MATCH_ASPECT 1015
#define IDC_ADV_GRAPHICS 1016
#define IDC_LF_CHARSET 1017
#define IDC_CHARSET_HELP 1018
#define IDC_DEFAULT_QUALITY 1019
#define IDC_DRAFT_QUALITY 1020
#define IDC_PROOF_QUALITY 1021
#define IDC_LF_FACENAME 1022
#define IDC_OUT_DEFAULT 1023
#define IDC_OUT_STRING 1024
#define IDC_OUT_CHARACTER 1025
#define IDC_OUT_STROKE 1026
#define IDC_OUT_TT 1027
#define IDC_OUT_DEVICE 1028
#define IDC_OUT_RASTER 1029
#define IDC_OUT_TT_ONLY 1030
#define IDC_OUT_OUTLINE 1031
#define IDC_DEFAULT_PITCH 1032
#define IDC_FIXED_PITCH 1033
#define IDC_VARIABLE_PITCH 1034
#define IDC_FF_DONTCARE 1035
#define IDC_FF_ROMAN 1036
#define IDC_FF_SWISS 1037
#define IDC_FF_MODERN 1038
#define IDC_FF_SCRIPT 1039
#define IDC_FF_DECORATIVE 1040
#define IDC_TM_HEIGHT 1041
#define IDC_TM_ASCENT 1042
#define IDC_TM_DESCENT 1043
#define IDC_TM_INTLEAD 1044
#define IDC_TM_EXTLEAD 1045
#define IDC_TM_AVECHAR 1046
#define IDC_TM_MAXCHAR 1047
#define IDC_TM_WEIGHT 1048
#define IDC_TM_OVERHANG 1049
#define IDC_TM_DIGASPX 1050
#define IDC_TM_DIGASPY 1051
#define IDC_TM_FIRSTCHAR 1052
#define IDC_TM_LASTCHAR 1053
#define IDC_TM_DEFCHAR 1054
#define IDC_TM_BREAKCHAR 1055
#define IDC_TM_ITALIC 1056
#define IDC_TM_UNDER 1057
#define IDC_TM_STRUCK 1058
#define IDC_TM_VARIABLE 1059
#define IDC_TM_VECTOR 1060
#define IDC_TM_TRUETYPE 1061
#define IDC_TM_DEVICE 1062
#define IDC_TM_FAMILY 1063
#define IDC_TM_CHARSET 1064
#define IDC_TM_FACENAME 1065
#define IDM_DEVICE_SCREEN 40001
#define IDM_DEVICE_PRINTER 40002

// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 103
#define _APS_NEXT_COMMAND_VALUE 40003
#define _APS_NEXT_CONTROL_VALUE 1066
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif


//PickFont.c



//Microsoft Developer Studio generated resource script.
//
#include "resource.h"

#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"

/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS

/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32

#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//

1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END

2 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END

3 TEXTINCLUDE DISCARDABLE
BEGIN
"\r\n"
"\0"
END

#endif // APSTUDIO_INVOKED


/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//

PICKFONT DIALOG DISCARDABLE 0, 0, 348, 308
STYLE WS_CHILD | WS_VISIBLE | WS_BORDER
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "&Height:",IDC_STATIC,8,10,44,8
EDITTEXT IDC_LF_HEIGHT,64,8,24,12,ES_AUTOHSCROLL
LTEXT "&Width",IDC_STATIC,8,26,44,8
EDITTEXT IDC_LF_WIDTH,64,24,24,12,ES_AUTOHSCROLL
LTEXT "Escapement:",IDC_STATIC,8,42,44,8
EDITTEXT IDC_LF_ESCAPE,64,40,24,12,ES_AUTOHSCROLL
LTEXT "Orientation:",IDC_STATIC,8,58,44,8
EDITTEXT IDC_LF_ORIENT,64,56,24,12,ES_AUTOHSCROLL
LTEXT "Weight:",IDC_STATIC,8,74,44,8
EDITTEXT IDC_LF_WEIGHT,64,74,24,12,ES_AUTOHSCROLL
GROUPBOX "Mapping Mode",IDC_STATIC,97,3,96,90,WS_GROUP
CONTROL "Text",IDC_MM_TEXT,"Button",BS_AUTORADIOBUTTON,104,13,56,
8
CONTROL "Low Metric",IDC_MM_LOMETRIC,"Button",BS_AUTORADIOBUTTON,
104,24,56,8
CONTROL "High Metric",IDC_MM_HIMETRIC,"Button",
BS_AUTORADIOBUTTON,104,35,56,8
CONTROL "Low English",IDC_MM_LOENGLISH,"Button",
BS_AUTORADIOBUTTON,104,46,56,8
CONTROL "High English",IDC_MM_HIENGLISH,"Button",
BS_AUTORADIOBUTTON,104,57,56,8
CONTROL "Twips",IDC_MM_TWIPS,"Button",BS_AUTORADIOBUTTON,104,68,
56,8
CONTROL "Logical Twips",IDC_MM_LOGTWIPS,"Button",
BS_AUTORADIOBUTTON,104,79,64,8
CONTROL "Italic",IDC_LF_ITALIC,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,8,90,48,12
CONTROL "Underline",IDC_LF_UNDER,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,8,104,48,12
CONTROL "Strike Out",IDC_LF_STRIKE,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,8,118,48,12
CONTROL "Match Aspect",IDC_MATCH_ASPECT,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,60,104,62,8
CONTROL "Adv Grfx Mode",IDC_ADV_GRAPHICS,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,60,118,62,8
LTEXT "Character Set:",IDC_STATIC,8,137,46,8
EDITTEXT IDC_LF_CHARSET,58,135,24,12,ES_AUTOHSCROLL
PUSHBUTTON "?",IDC_CHARSET_HELP,90,135,14,14
GROUPBOX "Quality",IDC_STATIC,132,98,62,48,WS_GROUP
CONTROL "Default",IDC_DEFAULT_QUALITY,"Button",
BS_AUTORADIOBUTTON,136,110,40,8
CONTROL "Draft",IDC_DRAFT_QUALITY,"Button",BS_AUTORADIOBUTTON,
136,122,40,8
CONTROL "Proof",IDC_PROOF_QUALITY,"Button",BS_AUTORADIOBUTTON,
136,134,40,8
LTEXT "Face Name:",IDC_STATIC,8,154,44,8
EDITTEXT IDC_LF_FACENAME,58,152,136,12,ES_AUTOHSCROLL
GROUPBOX "Output Precision",IDC_STATIC,8,166,118,133,WS_GROUP
CONTROL "OUT_DEFAULT_PRECIS",IDC_OUT_DEFAULT,"Button",
BS_AUTORADIOBUTTON,12,178,112,8
CONTROL "OUT_STRING_PRECIS",IDC_OUT_STRING,"Button",
BS_AUTORADIOBUTTON,12,191,112,8
CONTROL "OUT_CHARACTER_PRECIS",IDC_OUT_CHARACTER,"Button",
BS_AUTORADIOBUTTON,12,204,112,8
CONTROL "OUT_STROKE_PRECIS",IDC_OUT_STROKE,"Button",
BS_AUTORADIOBUTTON,12,217,112,8
CONTROL "OUT_TT_PRECIS",IDC_OUT_TT,"Button",BS_AUTORADIOBUTTON,
12,230,112,8
CONTROL "OUT_DEVICE_PRECIS",IDC_OUT_DEVICE,"Button",
BS_AUTORADIOBUTTON,12,243,112,8
CONTROL "OUT_RASTER_PRECIS",IDC_OUT_RASTER,"Button",
BS_AUTORADIOBUTTON,12,256,112,8
CONTROL "OUT_TT_ONLY_PRECIS",IDC_OUT_TT_ONLY,"Button",
BS_AUTORADIOBUTTON,12,269,112,8
CONTROL "OUT_OUTLINE_PRECIS",IDC_OUT_OUTLINE,"Button",
BS_AUTORADIOBUTTON,12,282,112,8
GROUPBOX "Pitch",IDC_STATIC,132,166,62,50,WS_GROUP
CONTROL "Default",IDC_DEFAULT_PITCH,"Button",BS_AUTORADIOBUTTON,
137,176,52,8
CONTROL "Fixed",IDC_FIXED_PITCH,"Button",BS_AUTORADIOBUTTON,137,
189,52,8
CONTROL "Variable",IDC_VARIABLE_PITCH,"Button",
BS_AUTORADIOBUTTON,137,203,52,8
GROUPBOX "Family",IDC_STATIC,132,218,62,82,WS_GROUP
CONTROL "Don't Care",IDC_FF_DONTCARE,"Button",BS_AUTORADIOBUTTON,
137,229,52,8
CONTROL "Roman",IDC_FF_ROMAN,"Button",BS_AUTORADIOBUTTON,137,241,
52,8
CONTROL "Swiss",IDC_FF_SWISS,"Button",BS_AUTORADIOBUTTON,137,253,
52,8
CONTROL "Modern",IDC_FF_MODERN,"Button",BS_AUTORADIOBUTTON,137,
265,52,8
CONTROL "Script",IDC_FF_SCRIPT,"Button",BS_AUTORADIOBUTTON,137,
277,52,8
CONTROL "Decorative",IDC_FF_DECORATIVE,"Button",
BS_AUTORADIOBUTTON,137,289,52,8
DEFPUSHBUTTON "OK",IDOK,247,286,50,14
GROUPBOX "Text Metrics",IDC_STATIC,201,2,140,272,WS_GROUP
LTEXT "Height:",IDC_STATIC,207,12,64,8
LTEXT "0",IDC_TM_HEIGHT,281,12,44,8
LTEXT "Ascent:",IDC_STATIC,207,22,64,8
LTEXT "0",IDC_TM_ASCENT,281,22,44,8
LTEXT "Descent:",IDC_STATIC,207,32,64,8
LTEXT "0",IDC_TM_DESCENT,281,32,44,8
LTEXT "Internal Leading:",IDC_STATIC,207,42,64,8
LTEXT "0",IDC_TM_INTLEAD,281,42,44,8
LTEXT "External Leading:",IDC_STATIC,207,52,64,8
LTEXT "0",IDC_TM_EXTLEAD,281,52,44,8
LTEXT "Ave Char Width:",IDC_STATIC,207,62,64,8
LTEXT "0",IDC_TM_AVECHAR,281,62,44,8
LTEXT "Max Char Width:",IDC_STATIC,207,72,64,8
LTEXT "0",IDC_TM_MAXCHAR,281,72,44,8
LTEXT "Weight:",IDC_STATIC,207,82,64,8
LTEXT "0",IDC_TM_WEIGHT,281,82,44,8
LTEXT "Overhang:",IDC_STATIC,207,92,64,8
LTEXT "0",IDC_TM_OVERHANG,281,92,44,8
LTEXT "Digitized Aspect X:",IDC_STATIC,207,102,64,8
LTEXT "0",IDC_TM_DIGASPX,281,102,44,8
LTEXT "Digitized Aspect Y:",IDC_STATIC,207,112,64,8
LTEXT "0",IDC_TM_DIGASPY,281,112,44,8
LTEXT "First Char:",IDC_STATIC,207,122,64,8
LTEXT "0",IDC_TM_FIRSTCHAR,281,122,44,8
LTEXT "Last Char:",IDC_STATIC,207,132,64,8
LTEXT "0",IDC_TM_LASTCHAR,281,132,44,8
LTEXT "Default Char:",IDC_STATIC,207,142,64,8
LTEXT "0",IDC_TM_DEFCHAR,281,142,44,8
LTEXT "Break Char:",IDC_STATIC,207,152,64,8
LTEXT "0",IDC_TM_BREAKCHAR,281,152,44,8
LTEXT "Italic?",IDC_STATIC,207,162,64,8
LTEXT "0",IDC_TM_ITALIC,281,162,44,8
LTEXT "Underlined?",IDC_STATIC,207,172,64,8
LTEXT "0",IDC_TM_UNDER,281,172,44,8
LTEXT "Struck Out?",IDC_STATIC,207,182,64,8
LTEXT "0",IDC_TM_STRUCK,281,182,44,8
LTEXT "Variable Pitch?",IDC_STATIC,207,192,64,8
LTEXT "0",IDC_TM_VARIABLE,281,192,44,8
LTEXT "Vector Font?",IDC_STATIC,207,202,64,8
LTEXT "0",IDC_TM_VECTOR,281,202,44,8
LTEXT "TrueType Font?",IDC_STATIC,207,212,64,8
LTEXT "0",IDC_TM_TRUETYPE,281,212,44,8
LTEXT "Device Font?",IDC_STATIC,207,222,64,8
LTEXT "0",IDC_TM_DEVICE,281,222,44,8
LTEXT "Family:",IDC_STATIC,207,232,64,8
LTEXT "0",IDC_TM_FAMILY,281,232,44,8
LTEXT "Character Set:",IDC_STATIC,207,242,64,8
LTEXT "0",IDC_TM_CHARSET,281,242,44,8
LTEXT "0",IDC_TM_FACENAME,207,262,128,8
END


/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//

#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE
BEGIN
"PICKFONT", DIALOG
BEGIN
LEFTMARGIN, 8
RIGHTMARGIN, 341
BOTTOMMARGIN, 300
END
END
#endif // APSTUDIO_INVOKED


/////////////////////////////////////////////////////////////////////////////
//
// Menu
//

PICKFONT MENU DISCARDABLE
BEGIN
POPUP "&Device"
BEGIN
MENUITEM "&Screen", IDM_DEVICE_SCREEN, CHECKED
MENUITEM "&Printer", IDM_DEVICE_PRINTER
END
END

#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////



#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//


/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED


17.3.3 逻辑字体结构

(1)LOGFONT结构



字段



含义



lfHeight

(逻辑单位)



①lfHeight=0表示默认的字符高度;

②lfHeight>0,会匹配tmHeight大小的字体(注意含tmInternalLeading)。
③lfHeight<0时,会匹配tmHeight-tmInternalLeading大小的字体,即平时所说的字号大小。Windows根据lfHeight反向去查找字号的大小。
(注意:字号与字体高度的关系lfHeight =-(磅值*GetDeviceCaps(hdc,LOGPIXELSY)*72);



lfWidth

(逻辑单位)



①lfWidth =0,表示由Windows根据字符高度来选择合适的字体。

②lfWidth ≠0时,对TrueType字体会返回比正常字符稍宽或稍窄的字体,对点阵字体不起作用。

③lfWidth = tmAveCharWidth;

④正确使用方法:将lfWidth先设为0,并创建逻辑字体,再选入设备环境,然后调用GetTextMetrics获得tmAveCharWidth。并按比例调节tmAveCharWidth值,然后根据调节过的该值作为lfWidth字段值创建一个新字体。



lfEscapement



①字符串的方向,整个字符串以水平方向逆时针旋转的角度(单位是1/10度)如0表示字符串从左向右;900垂直向上;1800从右向左;2700垂直向下。

②字符串的每个字符并未被旋转,其基线和X轴是平行的。也就是每个字符还是垂直的。(SetGraphicsModes为GM_ADVANCED下)

③将SetGraphicsModes设为GM_COMPATIBLE字符串的每个字符也一直被旋转,也就是每个字符还是垂直于字符串延伸方向



lfOrientation



①单个字符的倾斜方向,是从水平方向往逆时针旋转的角度,单位也是1/10度。如900逆时针旋转90度

②使用该字段时一定要设置SetGraphicsMode为GM_ADVANCED才有效。



lfWeight



①指定是否使用粗体字。

②在WINGID.H中定义,其可用值

A、FW_DONTCARE(0);B、FW_THIN(100);C、FW_EXTRALIGHT(200)

D、FW_LIGHT(300);E、FW_NORMAL(400);F、FW_SEMIBOLD(600)

H、FW_BOLD(700);I、FW_EXTRABOLD(800);J、FW_HEAVY(900);



lfItalic



①非0值表示使用斜体。

②对于点阵字体,Windows会通过合成斜效果;对于TrueType会使用单独的斜字体。或该字体的倾斜属性版本



lfUnderLine



非0值表示字符加下划线



lfStrikeOut



非0值表示删除线



lfCharSet



①字符集,默认为1,即DEFAULT_CHARSET

②lfCharSet==0时,表示ANSI_CHARSET。



lfOutPrecision



通过字体的大小特征来匹配真实的字体。该字段设定相当复杂。一般不使用。但如果使用OUT_TT_ONLY_PRECIS,可能确保返回一个TrueType字体。



lfQuality



①只影响点阵字体,对TrueType字体没影响。

②DRAFT_QUALITY表示缩放点阵字体到期望的大小。PROOF_QUALITY表示不缩放。DEFULT_QUALITY(值为0)表示不在乎真实字体的美观程度



lfPitchAndFamily



①该字段是一个字节大小,由两部分组成:最低两位表示是否等宽,高6位表示字体族

②最低2位:DEFAULT_PITCH(0);FIXED_PITCH(1);VARIABLE_PITCH(2)③高6位:FF_DONTCARE(0x00);FF_ROMAN(0x10);FF_SWISS(0x20);

          FF_MODERN(0x30);FF_SCRIPT(0x40);FF_DECORATIVE(0x50)



lfFacename



实际字体的字样名字

该字段的长度为LF_FACESIZE(32个字符)的字节数组



17.3.4 字体匹配算法

(1)lfCharSet字段:字符集,该字段是重要字段

(2)lfPitchAndFamily字段:如果包含FIXED_PITCH值时,该字段非常重要。

(3)lfFaceName:当指定字体的字样名称时,表明了用户的意图。如果为NULL,但lfPitchAndFamily指定了某一字体族(除FF_DONTCARE外),那么lfPitchAndFamily的重要性被提高。

(4)lfHeight:对于点阵字体,Windows会尝试匹配lfHeight。如果是TrueType或笔画字体,Windows会对字体进行简单的缩放来得到期望的字体高度。

(5)设定lfQuality为PROOF_QUALITY可防止Windows对点阵字体缩放,而且表示字体的美观更重要,字符的高度则是比较次要的。

(6)lfHeight和lfWeight的比值和显示器纵横从不符合时。可以调用SetMapperFlags(hdc,TRUE)来避免Windows去找一个为不同纵横比显示器而设计的特殊点阵列字体。(对于TrueType没必要这样做)。

17.3.5 获取字体信息(TEXTMETRIC结构,除纵横比外,其余字段以逻辑单位表示)



字段



含义



tmHeight



字符高度。



tmAscent



基线之上的垂直高度



tmDescent



基线之下的垂直高度



tmInternalLeading



内部间隔,一般用来标重音符号



tmExternalLeading



外部间隔值。tmHeight不包含该部分的尺寸



tmAveCharWidth



小写字母的平均宽度



tmMaxCharWidth



该字体中最宽的字符宽度。等宽字体其值等于tmAverCharWidth



tmWeigth



字符的粗细程序,取值从0到999。400为正常字符,700为粗字体



tmOverhang



字符加粗时,该字符会变略宽。此字段代表额外的宽度。对于粗字体其宽度为tmAverCharWidth+tmOverHang,对于非粗字体的其宽度为tmAverChaWidth值



tmDigitizedAspectX

tmDigitizedAspectY



字体的纵横比,等于调用GetDeviceCaps时的

LOGPIXELSX/LOGPIXELSY.



tmFirstChar



该字体中第一个字符的编码



tmLastChar



该字体中最后一个字符的编码



tmDefaultChar



当希望显示一个字符在该字体中并不存在时,用该字段定义的字符来代替。



tmBreakChar



Windows认为在该字符处是可以断行的,一般该字段的值为32.也就是空格字符。



tmItalic



是否是斜体字



tmUnderlined



是否带下划线



tmStruckOut



是否带删除线



tmPitchAndFamily



低四位表示字体特性(如等宽或变宽)

高四位表示字符族(与LONGFONT中的含义一样)



tmCharSet



字符集

#define ANSI_CHARSET            0

#define DEFAULT_CHARSET         1

#define SYMBOL_CHARSET          2

#define MAC_CHARSET             77

#define SHIFTJIS_CHARSET        128

#define HANGEUL_CHARSET         129

#define HANGUL_CHARSET          129

#define JOHAB_CHARSET           130

#define GB2312_CHARSET          134

#define CHINESEBIG5_CHARSET     136

#define GREEK_CHARSET           161

#define TURKISH_CHARSET         162

#define VIETNAMESE_CHARSET      163

#define HEBREW_CHARSET          177

#define ARABIC_CHARSET          178

#define BALTIC_CHARSET          186

#define RUSSIAN_CHARSET         204

#define THAI_CHARSET            222

#define EASTEUROPE_CHARSET      238

#define OEM_CHARSET             255



  

17.3.6 EZFONT系统

(1)SetGraphicsMode(hdc,iMode):设置设备环境的图形模式



iMode



含义



GM_COMPATIBLE



缺省的模式。应用程序只能通过设置窗口或视口原点来改变逻辑坐标系到设备坐标系的转换。(如调用SetWindowsExtEx或SetViewportExtEx)。但是如果调用SetWorldTransform或ModifyWorldTransform来转换将失败



GM_ADVANCED



从逻辑坐标系统到设备坐标系统,使用的是高级模式转换,即通过SetWorldTransform或ModifyWorldTransform,进行矩阵变换来达到目的。(注意:当使用这种模式时,可以用映射模式来改变对字体进行缩放,代码如下)

  GetClientRect (hwnd, &rect) ;

SetGraphicsMode(hdc, GM_ADVANCED);

SetMapMode(hdc, MM_ISOTROPIC);

SetTextAlign(hdc, TA_CENTER);

SetWindowExtEx(hdc, 200, -200, NULL);

SetViewportExtEx(hdc, rect.right, rect.bottom, NULL);

SetViewportOrgEx(hdc, rect.right / 2, rect.bottom / 2, NULL);

TextOut(hdc, 0, 0, szStr, lstrlen(szStr));//文字放大且上下翻转



(2)SetWorldTransform(hDc,&xform);——旋转逻辑坐标系

  x' = x * eM11 + y * eM21 + eDx; (x', y')为新坐标,(x,y)为原坐标

  y' = x * eM12 + y * eM22 + eDy;

对于旋转来讲

  x' = cos(q)*x – sin(q)*y + x0;  (x0,y0)为坐标原点; q为顺时针旋转的角度

  y' = sin(q)*x  + cos(q)*y + y0;

(3)通过改变字体大小按比例缩放方法(不是通过映射模式的)

  ①先通过指定LOGFONT的lfHeight字段大小获得相应的字体。(注意lfWidth先设为0)

  ②通用GetTextMetrics获取新创建出来字体tmWidth大小。

  ③设置新的lfWidth = tmAverCharWidth* 指定的宽度/指定的高度,根据新的lfHeight和新的lfWidth创建一个新字体,并选入设备环境。这样一个按指定比例的字体创建出来。

 【RotateFont】

 第17章 文本和字体_17.3 逻辑字体_git_02



/*------------------------------------------------------------
FONTROTATE.C -- Font Rotate Demo
(c) Charles Petzold, 1998
------------------------------------------------------------*/
#include <windows.h>
#include <math.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
TCHAR szAppName[] = TEXT("FontRotate");
TCHAR szTitle[] = TEXT("FontRotate:Rotate Font Demo");
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
HWND hwnd;
MSG msg;
WNDCLASSEX wndclass;
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.cbSize = sizeof(WNDCLASSEX);
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(hInstance, szAppName);
wndclass.hIconSm = LoadIcon(hInstance, szAppName);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szAppName;
if (!RegisterClassEx(&wndclass))
{
MessageBox(NULL, TEXT("This program requires Windows NT!"),
szAppName, MB_ICONERROR);
return 0;
}

hwnd = CreateWindow(szAppName, // window class name
szTitle, // window caption
WS_OVERLAPPEDWINDOW, // window style
CW_USEDEFAULT, // initial x position
CW_USEDEFAULT, // initial y position
CW_USEDEFAULT, // initial x size
CW_USEDEFAULT, // initial y size
NULL, // parent window handle
NULL, // window menu handle
hInstance, // program instance handle
NULL); // creation parameters

ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);

while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
TCHAR* szStr45 = TEXT("顺时针旋转45度");
TCHAR* szStrDownUp = TEXT("字体缩放,并上下翻转");

HDC hdc;
PAINTSTRUCT ps;
RECT rect;
static XFORM xfm;
float theta = (float)(45 * 3.14 / 180.0f);

switch (message)
{
case WM_CREATE:
//构造旋转矩阵
xfm.eM11 = (FLOAT)cos(theta);
xfm.eM12 = (FLOAT)sin(theta);
xfm.eM21 = -(FLOAT)sin(theta);
xfm.eM22 = (FLOAT)cos(theta);
xfm.eDx = 0;
xfm.eDy = 0;
return 0;

case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);

GetClientRect(hwnd, &rect);

SetGraphicsMode(hdc, GM_ADVANCED); //这句很关键,是在映射模式中缩放字体的关键!
SetWorldTransform(hdc, &xfm); //顺时针转theta度
SetMapMode(hdc, MM_ISOTROPIC);
SetTextAlign(hdc, TA_CENTER);
SetWindowExtEx(hdc, 50, 200, NULL); //字体缩放,并旋转45度
SetViewportExtEx(hdc, rect.right, rect.bottom, NULL);
SetViewportOrgEx(hdc, rect.right / 2, rect.bottom / 2, NULL);
TextOut(hdc, 0, 0, szStr45, lstrlen(szStr45));

ModifyWorldTransform(hdc, NULL, MWT_IDENTITY);//恢复旋转矩阵为默认值
SetWindowExtEx(hdc, 50, -200, NULL); //字体缩放,并上下翻转(因为负范围)
SetViewportExtEx(hdc, rect.right, rect.bottom, NULL);
SetViewportOrgEx(hdc, rect.right / 2, 100, NULL);
TextOut(hdc, 0, 0, szStrDownUp, lstrlen(szStrDownUp));//字体缩放并上下翻转(因为负范围)

EndPaint(hwnd, &ps);
return 0;

case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}


EZTest程序】测试指定不同磅值下,匹配到的字体情况。

 第17章 文本和字体_17.3 逻辑字体_ico_03

(注意观察:lfHeight值和tmHeight值,一般多个lfHeight对应一个tmHeight。)



/*------------------------------------------------------------
EZTEST.C -- Test of EZFONT(Easy Font)
(c) Charles Petzold, 1998
------------------------------------------------------------*/
#include <windows.h>
#include "EzFont.h"
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
TCHAR szAppName[] = TEXT("EZTest");
TCHAR szTitle[] = TEXT("EZTest:Test of EZFONT");
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
HWND hwnd;
MSG msg;
WNDCLASSEX wndclass;
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.cbSize = sizeof(WNDCLASSEX);
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(hInstance, szAppName);
wndclass.hIconSm = LoadIcon(hInstance, szAppName);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szAppName;
if (!RegisterClassEx(&wndclass))
{
MessageBox(NULL, TEXT("This program requires Windows NT!"),
szAppName, MB_ICONERROR);
return 0;
}

hwnd = CreateWindow(szAppName, // window class name
szTitle, // window caption
WS_OVERLAPPEDWINDOW, // window style
CW_USEDEFAULT, // initial x position
CW_USEDEFAULT, // initial y position
CW_USEDEFAULT, // initial x size
CW_USEDEFAULT, // initial y size
NULL, // parent window handle
NULL, // window menu handle
hInstance, // program instance handle
NULL); // creation parameters

ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);

while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
void PaintRoutine(HWND hwnd, HDC hdc, int cxArea, int cyArea)
{
HFONT hFont;
LOGFONT lf;
int y, iPointSize;
TCHAR szBuffer[100];
TEXTMETRIC tm;
//设备为Logic Twips 映射模式
SetMapMode(hdc, MM_ANISOTROPIC);
SetWindowExtEx(hdc, 1440, 1440, NULL);
SetViewportExtEx(hdc, GetDeviceCaps(hdc, LOGPIXELSX),
GetDeviceCaps(hdc, LOGPIXELSY), NULL);
//测试一些字体
y = 0;
/*
字体大小从8磅到12磅,但并不是每个大小都有一个完全匹配的字体,通过
tmHeight的值和lfHeight不同就可以观察出来。如好一个lfHeight对应一个
tmHeight.
*/
for (iPointSize = 80; iPointSize <= 120; iPointSize++)
{
hFont = EzCreateFont(hdc, TEXT("Times New Roman"), iPointSize, 0, 0, TRUE);
GetObject(hFont, sizeof(LOGFONT), &lf);
SelectObject(hdc, hFont);
GetTextMetrics(hdc, &tm);
TextOut(hdc, 0, y, szBuffer,
wsprintf(szBuffer,
TEXT("Times New Roman font of %i.%i points ")
TEXT("lf.lfHeight= %i,tm.tmHeight=%i"),
iPointSize / 10, iPointSize & 10,
lf.lfHeight, tm.tmHeight));
DeleteObject(SelectObject(hdc, GetStockObject(SYSTEM_FONT)));
y += tm.tmHeight;
}
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
static int cxClient, cyClient;

switch (message)
{
case WM_SIZE:
cxClient = LOWORD(lParam);
cyClient = HIWORD(lParam);
return 0;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);

PaintRoutine(hwnd, hdc, cxClient, cyClient);
EndPaint(hwnd, &ps);
return 0;

case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}


//EzFont.h



/*----------------------------------------------------------
EZFONT.H header file
------------------------------------------------------------*/
#pragma once
#include <windows.h>
//iDeciPtHeight:字体高度:(单位1/10磅)如,12磅字体时,iDeciPtHeight=120
//iDecPtWidth:字体宽度(与上面单位一样)
//iAttributes:字体属性,如粗、斜、下划线、删除线等
//fLogRes:是否使用逻辑分辨率
HFONT EzCreateFont(HDC hdc, TCHAR* szFaceName, int iDeciPtHeight,
int iDeciPtWidth, int iAttributes, BOOL fLogRes);
#define EZ_ATTR_BOLD 1
#define EZ_ATTR_ITATIC 2
#define EZ_ATTR_UNDERLINE 4
#define Ez_ATTR_STRIKEOUT 8


//EzFont.c



/*-------------------------------------------------------------
EZFONT.C -- Easy Font Creation
(c) Charles Petzold, 1998
-------------------------------------------------------------*/
#include <windows.h>
#include <math.h>
#include "EzFont.h"
HFONT EzCreateFont(HDC hdc, TCHAR* szFaceName, int iDeciPtHeight,
int iDeciPtWidth, int iAttributes, BOOL fLogRes)
{
HFONT hFont;
LOGFONT lf;
TEXTMETRIC tm;
FLOAT cxDpi, cyDpi;
POINT pt;
SaveDC(hdc);
//设置高级图形模式,此模式下可以通过矩阵实现逻辑坐标到设备坐标的转换。
SetGraphicsMode(hdc, GM_ADVANCED);
ModifyWorldTransform(hdc, NULL, MWT_IDENTITY); //恢复变换到初始状态
SetViewportOrgEx(hdc, 0, 0, NULL);
SetWindowOrgEx(hdc, 0, 0, NULL);
if (fLogRes)
{
//使用逻辑分辨率(单位:像素/英寸)
cxDpi = (FLOAT)GetDeviceCaps(hdc, LOGPIXELSX);
cyDpi = (FLOAT)GetDeviceCaps(hdc, LOGPIXELSY);
} else
{
//实际的分辨率(单位:像素/英寸)
cxDpi = (FLOAT)(25.4 * GetDeviceCaps(hdc, HORZRES) /
GetDeviceCaps(hdc, HORZSIZE));
cyDpi = (FLOAT)(25.4 * GetDeviceCaps(hdc, VERTRES) /
GetDeviceCaps(hdc, VERTSIZE)); //vertsize单位为mm
}
//求出指定磅值的字体,需要多少像素点
pt.x = (int)(iDeciPtWidth* cxDpi / 72); //像素大小(设备单位)
pt.y = (int)(iDeciPtHeight* cyDpi / 72); //像素大小(设备单位)
DPtoLP(hdc, &pt, 1); //将像素大小由设备单位转为逻辑单位,也就是字体在逻辑坐标系中的大小
lf.lfHeight = -(int)(fabs(pt.y) / 10.0 + 0.5); //加0.5是为了向上取整
lf.lfWidth = 0; //注意这里要先设0,因为系统根据lfHeight匹配字体,会得到其固有的width
//而iDeciPtWidth会因高级图形模式允许对字体进行拉伸和缩放。
lf.lfEscapement = 0;
lf.lfOrientation = 0;
lf.lfWeight = iAttributes & EZ_ATTR_BOLD ? 700 : 0;
lf.lfItalic = iAttributes & EZ_ATTR_ITATIC ? 1 : 0;
lf.lfUnderline = iAttributes& EZ_ATTR_UNDERLINE ? 1 : 0;
lf.lfStrikeOut = iAttributes& Ez_ATTR_STRIKEOUT ? 1 : 0;
lf.lfCharSet = DEFAULT_CHARSET; //默认字符集
lf.lfOutPrecision = 0;
lf.lfClipPrecision = 0;
lf.lfQuality = 0;
lf.lfPitchAndFamily = 0;

lstrcpy(lf.lfFaceName, szFaceName);
hFont = CreateFontIndirect(&lf);
if (iDeciPtWidth != 0)
{
hFont = (HFONT)SelectObject(hdc, hFont); //选入,并返回旧字体
GetTextMetrics(hdc, &tm); //获取新字体信息
DeleteObject(SelectObject(hdc, hFont));//将旧的选入,交并删除新的字体
//字体的被左右拉伸,能这样实现的前提是设为高级图形模式,即SetGraphicsMode(hdc, GM_ADVANCED);
lf.lfWidth = (int)(tm.tmAveCharWidth*fabs(pt.x) / fabs(pt.y) + 0.5);
hFont = CreateFontIndirect(&lf);
}
RestoreDC(hdc, -1);
return hFont;
}


17.3.7 字体旋转

(1)在SetGraphicsMode(hdc,GM_ADVANCED)高级图形模式下,做字体的旋转

(2)lfEscapement每次增加30度,字体大小设为54磅


【FontRot程序】


第17章 文本和字体_17.3 逻辑字体_#include_04




/*------------------------------------------------------------
FONTDEMO.C -- Font Demonstration Shel Program
(c) Charles Petzold, 1998
------------------------------------------------------------*/
#include <windows.h>
#include "resource.h"
#include "..\\EzTest\\EzFont.h"
extern void PaintRoutine(HWND, HDC, int, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HINSTANCE hInst;
extern TCHAR szAppName[];
extern TCHAR szTitle[];
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT("About2");
HWND hwnd;
MSG msg;
WNDCLASSEX wndclass;
hInst = hInstance;
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.cbSize = sizeof(WNDCLASSEX);
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(hInstance, szAppName);
wndclass.hIconSm = LoadIcon(hInstance, szAppName);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName = szAppName;
wndclass.lpszClassName = szAppName;
if (!RegisterClassEx(&wndclass))
{
MessageBox(NULL, TEXT("This program requires Windows NT!"),
szAppName, MB_ICONERROR);
return 0;
}

hwnd = CreateWindow(szAppName, // window class name
szTitle, // window caption
WS_OVERLAPPEDWINDOW, // window style
CW_USEDEFAULT, // initial x position
CW_USEDEFAULT, // initial y position
CW_USEDEFAULT, // initial x size
CW_USEDEFAULT, // initial y size
NULL, // parent window handle
NULL, // window menu handle
hInstance, // program instance handle
NULL); // creation parameters

ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);

while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static int cxClient, cyClient;
static DOCINFO di = { sizeof(DOCINFO), TEXT("Font Demo:Printing") };
static PRINTDLG pd = { sizeof(PRINTDLG) };
int cxPage, cyPage;
HDC hdc, hdcPrn;
PAINTSTRUCT ps;
BOOL fSuccess;
switch (message)
{
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDM_PRINT:
//获得打印机DC
pd.hwndOwner = hwnd;
pd.Flags = PD_RETURNDC | PD_NOPAGENUMS | PD_NOSELECTION;
if (!PrintDlg(&pd))
return 0;
if (NULL == (hdcPrn = pd.hDC))
{
MessageBox(hwnd, TEXT("Cannot obtain PrinterDC"),
szAppName, MB_ICONEXCLAMATION | MB_OK);
return 0;
}

//获得可打印区域的大小
cxPage = GetDeviceCaps(hdcPrn, HORZRES);
cyPage = GetDeviceCaps(hdcPrn, VERTRES);
fSuccess = FALSE;
//打印页面
SetCursor(LoadCursor(NULL, IDC_WAIT));
ShowCursor(TRUE);
if ((StartDoc(hdcPrn, &di) >0) && (StartPage(hdcPrn)>0))
{
PaintRoutine(hwnd, hdcPrn, cxPage, cyPage);
if (EndPage(hdcPrn)>0)
{
fSuccess = TRUE;
EndDoc(hdcPrn);
}
}
DeleteDC(hdcPrn);
ShowCursor(FALSE);
SetCursor(LoadCursor(NULL, IDC_ARROW));
if (!fSuccess)
MessageBox(hwnd, TEXT("Error encountered during printing"),
szAppName, MB_ICONEXCLAMATION | MB_OK);
return 0;

case IDM_ABOUT:
MessageBox(hwnd, TEXT("Font Demonstration Program\n")
TEXT(" (c) Charles Petzold,1998"),
szAppName, MB_ICONINFORMATION | MB_OK);
return 0;
}

break;
case WM_SIZE:
cxClient = LOWORD(lParam);
cyClient = HIWORD(lParam);
return 0;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);

PaintRoutine(hwnd, hdc, cxClient, cyClient);
EndPaint(hwnd, &ps);
return 0;

case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}


//FontRot.c



/*--------------------------------------------------------
FONTROT.C —— Rotate Fonts
(c)Charles Petzold,1998
---------------------------------------------------------*/
#include <windows.h>
#include "..\\EzTest\\EzFont.h"

TCHAR szAppName[] = TEXT("FontRot");
TCHAR szTitle[] = TEXT("FontRot:Rotated Fonts");
void PaintRoutine(HWND hwnd, HDC hdc, int cxArea, int cyArea)
{
static TCHAR szString[] = TEXT("Rotation");
HFONT hFont;
int i;
LOGFONT lf;
//创建一个54磅大小的字体
hFont = EzCreateFont(hdc, TEXT("Times New Roman"), 540, 0, 0, TRUE);
GetObject(hFont, sizeof(LOGFONT), &lf);
DeleteObject(hFont);
//以这个字体为模版大小,通过指定lfEscapement来创建不同字体
SetBkMode(hdc, TRANSPARENT);
SetTextAlign(hdc, TA_BASELINE);
SetViewportOrgEx(hdc, cxArea / 2, cyArea / 2, NULL);
for (i = 0; i < 12; i++)
{
lf.lfEscapement = lf.lfOrientation = i * 300; //每次30度
SelectObject(hdc, CreateFontIndirect(&lf));
TextOut(hdc, 0, 0, szString, lstrlen(szString));
DeleteObject(SelectObject(hdc, GetStockObject(SYSTEM_FONT)));
}
}


//resource.h



//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ 生成的包含文件。
// 供 FontDemo.rc 使用
//
#define IDR_MENU1 101
#define IDM_PRINT 40001
#define IDM_ABOUT 40002
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 102
#define _APS_NEXT_COMMAND_VALUE 40003
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif


//FontDemo.rc



// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "winres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// 中文(简体,中国) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""winres.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Menu
//
FONTDEMO MENU
BEGIN
POPUP "&File"
BEGIN
MENUITEM "&Print...", 40001
END
POPUP "&Help"
BEGIN
MENUITEM "&About...", 40002
END
END
#endif // 中文(简体,中国) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED


 //EzFont.h和EzFont.c文件与上一个程序相同。