在某些情况下,应用程序必须能够枚举可用的字体并选择最适合特定操作的字体。应用程序可以通过调用EnumFonts或EnumFontFamilies函数来枚举可用的字体。这些功能将有关可用字体的信息发送到应用程序提供的回调函数。回调函数接收LOGFONT和NEWTEXTMETRIC结构中的信息。(NEWTEXTMETRIC结构包含有关TrueType字体的信息。当回调函数收到有关非TrueType字体的信息时,信息将包含在TEXTMETRIC结构中。)通过使用此信息,应用程序可以将用户的选择限制为只有那些可用的字体。
EnumFontFamilies功能类似于EnumFonts功能,但包含一些额外的功能。EnumFontFamilies允许应用程序利用TrueType字体可用的样式。新增和升级的应用程序应使用EnumFontFamilies而不是EnumFonts.
在以前的Windows版本中,唯一的风格属性是重量和斜体;字体的姓氏中指定了其他任何样式。例如,当应用程序使用EnumFonts函数查询可用的Courier字体时,EnumFonts可能会返回Courier,Courier Bold,Courier Bold Italic和Courier Italic的信息。它不会返回有关可能安装的任何其他Courier字体的信息,因为任何其他Courier字体通常具有不同的姓氏。
TrueType字体围绕字体名称(例如Courier New)和样式名称(例如,斜体,粗体和超粗体)组织。EnumFontFamilies函数枚举与给定姓氏相关联的所有样式,而不仅仅是粗体和斜体属性。例如,当系统包含名为Courier New Extra-Bold的TrueType字体时,EnumFontFamilies将其列为其他Courier New字体。EnumFontFamilies的功能有助于具有许多或不寻常的样式和跨国界的字体的字体。
如果应用程序不提供字体名称,则EnumFonts和EnumFontFamilies功能可在每个可用系列中提供有关一种字体的信息。要枚举设备上下文中的所有字体,应用程序可以为字体名称指定NULL,编译可用字体的列表,然后枚举每种字体中的每种字体。
以下示例使用EnumFontFamilies函数来检索可用的栅格,向量和TrueType字体系列的数量。
UINT uAlignPrev;
int aFontCount[] = { 0, 0, 0 };
char szCount[8];
EnumFontFamilies(hdc,(LPCTSTR)NULL,
(FONTENUMPROC) EnumFamCallBack, (LPARAM) aFontCount);
uAlignPrev = SetTextAlign(hdc, TA_UPDATECP);
MoveToEx(hdc, 10, 50, (LPPOINT)NULL);
TextOut(hdc, 0, 0, "Number of raster fonts: ", 24);
itoa(aFontCount[0], szCount, 10);
TextOut(hdc, 0, 0, szCount, strlen(szCount));
MoveToEx(hdc, 10, 75, (LPPOINT)NULL);
TextOut(hdc, 0, 0, "Number of vector fonts: ", 24);
itoa(aFontCount[1], szCount, 10);
TextOut(hdc, 0, 0, szCount, strlen(szCount));
MoveToEx(hdc, 10, 100, (LPPOINT)NULL);
TextOut(hdc, 0, 0, "Number of TrueType fonts: ", 26);
itoa(aFontCount[2], szCount, 10);
TextOut(hdc, 0, 0, szCount, strlen(szCount));
SetTextAlign(hdc, uAlignPrev);
.
.
.
BOOL FAR PASCAL EnumFamCallBack(lplf, lpntm, FontType, aFontCount)
LPLOGFONT lplf;
LPNEWTEXTMETRIC lpntm;
DWORD FontType;
LPVOID aFontCount;
{
int far * aiFontCount = (int far *) aFontCount;
/*
*记录光栅,TrueType和矢量的数量
* font-count数组中的字体。
*/
if(FontType & RASTER_FONTTYPE)
aiFontCount[0]++;
else if(FontType & TRUETYPE_FONTTYPE)
aiFontCount[2]++;
其他
aiFontCount[1]++;
if(aiFontCount [0] || aiFontCount [1] || aiFontCount [2])
return TRUE;
其他
return FALSE;
UNREFERENCED_PARAMETER( lplf );
UNREFERENCED_PARAMETER( lpntm );
}
此示例使用两个掩码RASTER_FONTTYPE和TRUETYPE_FONTTYPE来确定被枚举的字体的类型。如果设置了RASTER_FONTTYPE位,则字体为栅格字体。如果TRUETYPE_FONTTYPE位被设置,字体是TrueType字体。如果没有设置位,则该字体是矢量字体。当设备(例如激光打印机)支持下载TrueType字体时,将设置第三个掩码DEVICE_FONTTYPE;如果设备是显示适配器,点阵式打印机或其他光栅设备,则为零。应用程序还可以使用DEVICE_FONTTYPE掩码来区分GDI提供的栅格字体与设备提供的字体。Windows可以模拟GDI提供的栅格字体的粗体,斜体,下划线和删除属性,但不能为设备提供的字体。
应用程序还可以在NEWTEXTMETRIC结构的tmPitchAndFamily成员中检查位1和2,以识别TrueType字体。如果位1为0,位2为1,则字体为TrueType字体。
矢量字体分类为OEM_CHARSET而不是ANSI_CHARSET。某些应用程序通过使用此信息来标识向量字体,检查tmCharSet结构的tmCharSet成员。这种分类通常会防止字体映射器选择矢量字体,除非特别要求。(大多数应用程序不再使用矢量字体,因为它们的笔画是单行,并且绘制时间比TrueType字体花费更长的时间,这些字体在早期版本的Windows中提供了许多相同的缩放和旋转功能,需要矢量字体。)