销毁字体
同其它GDI资源一样,在程序用完后,字体必须被销毁。在终止程序前如果删除字体失败,将导致资源泄露--孤立的图形资源,占用了珍贵的内存但却不再被应用程序拥有。
为了销毁字体,首先将字体从所在的设备环境里取消选择,这可以通过调用SelectObject来完成。传入的字体是最初调用SelectObject来选择字体时返回的字体。字体取消选择后,调用DeleteObject从系统里删除字体。DeleteObject原型如下:
BOOL DeleteObject (HGDIOBJ hObject);
hObject 表示要删除的字体句柄。
从这个过程可以看出,字体管理不是一个小事情。LOGFONT结构的许多参数可能令人畏惧,但它们赋予了应用程序准确指定字体的巨大能力。
处理字体时的一个问题是判断在具体设备上能够支持什么类型的字体。Windows CE设备提供标准字体集合,但制造商或者用户可能在具体系统上装载了附加字体。幸运地是,Windows提供了枚举系统上所有字体的方法。
枚举字体
为了判断系统上有什么字体可以使用,Windows提供了以下函数:
int EnumFontFamilies (HDC hdc, LPCTSTR lpszFamily, FONTENUMPROC lpEnumFontFamProc, LPARAM lParam);
该函数列举所以字系以及字系里的每个字体。头一个参数是设备环境。第二个参数是需要枚举的字系的名字。如果该参数为NULL,表示枚举每个可以使用的字系。
第三个参数稍微有些不同,是一个指向由应用程序提供的函数的指针。该函数是一个回调函数,由Windows为每个枚举的字体调用。最后一个参数,lParam,是由应用程序使用的普通参数。该值不经修改,直接传给了应用程序回调过程。
虽然回调函数的名字可以随便起,但函数原型必须声明为:
int CALLBACK EnumFontFamProc (LOGFONT *lpelf, TEXTMETRIC *lpntm, DWORD FontType, LPARAM lParam);
传给回调函数的第一个参数是指向LOGFONT结构的指针,用来描述被枚举的字体。第2个参数,指向textmetric的指针,进一步描述该字体。字体类型参数指明字体是光栅字体还是TrueType字体。
FontList示例程序
FontList程序用两种方式使用EnumFontFamilies函数来枚举系统里所有字体
清单2-2
FontList.h
//================================================================
// Header file
//
// Written for the book Programming Windows CE
// Copyright (C) 2003 Douglas Boling
//======================================================================
// Returns number of elements
#define dim(x) (sizeof(x) / sizeof(x[0]))
//----------------------------------------------------------------------
// Generic defines and data types
//
struct decodeUINT { // Structure associates
UINT Code; // messages
// with a function.
LRESULT (*Fxn)(HWND, UINT, WPARAM, LPARAM);
};
struct decodeCMD { // Structure associates
UINT Code; // menu IDs with a
LRESULT (*Fxn)(HWND, WORD, HWND, WORD); // function.
};
//----------------------------------------------------------------------
// Program-specific structures
//
#define FAMILYMAX 24
typedef struct {
int nNumFonts;
TCHAR szFontFamily[LF_FACESIZE];
} FONTFAMSTRUCT;
typedef FONTFAMSTRUCT *PFONTFAMSTRUCT;
typedef struct {
INT yCurrent;
HDC hdc;
} PAINTFONTINFO;
typedef PAINTFONTINFO *PPAINTFONTINFO;
//----------------------------------------------------------------------
// Function prototypes
//
HWND InitInstance (HINSTANCE, LPWSTR, int);
int TermInstance (HINSTANCE, int);
// Window procedures
LRESULT CALLBACK MainWndProc (HWND, UINT, WPARAM, LPARAM);
// Message handlers
LRESULT DoCreateMain (HWND, UINT, WPARAM, LPARAM);
LRESULT DoPaintMain (HWND, UINT, WPARAM, LPARAM);
LRESULT DoDestroyMain (HWND, UINT, WPARAM, LPARAM);