字体创建和选择
“ 字体 通用”对话框简化了创建和选择字体的过程。 通过初始化 CHOOSEFONT 结构并调用 CHOOSEFONT 函数,应用程序可以支持以前需要多行自定义代码的相同字体选择接口。 (有关“ 字体 ”常用对话框的详细信息,请参阅 通用对话框库。)
用户选择
大多数字体创建和选择操作都涉及用户。 例如,字处理应用程序允许用户为标题、脚注和正文文本选择唯一字体。 当用户使用“ 字体 ”对话框选择字体并按“ 确定” 按钮后, CHOOSEFONT 函数将使用所请求字体的属性初始化 LOGFONT 结构的成员。 若要将此字体用于文本输出操作,应用程序必须先创建一个逻辑字体,然后在其设备上下文中选择该字体。 逻辑字体是应用程序提供的理想字体的说明。 开发人员可以通过调用 CreateFont 或 CreateFontIndirect 函数来创建逻辑字体。 在这种情况下,应用程序将调用 CreateFontIndirect 并提供指向由 CHOOSEFONT 初始化的 LOGFONT 结构的指针。 通常,调用 CreateFontIndirect 的效率更高,因为 CreateFont 需要多个参数,而 CreateFontIndirect 只需要一个指向 LOGFONT 的指针。
应用程序必须从存储在设备内部的字体及其资源已加载到操作系统的字体中查找最接近的匹配项,然后应用程序才能真正开始使用逻辑字体绘制文本。 存储在设备或操作系统中的字体称为 物理字体。 查找与指定逻辑字体最匹配的物理字体的过程称为字体映射。 当应用程序调用 SelectObject 函数并提供标识逻辑字体的句柄时,将发生此过程。 使用内部算法执行字体映射,该算法将请求的逻辑字体的属性与可用物理字体的属性进行比较。 当字体映射器算法完成搜索并确定最接近的可能匹配时, SelectObject 函数将返回,应用程序可以开始使用新字体绘制文本。
SetMapperFlags 函数指定字体映射器算法是否仅搜索纵横比与物理设备匹配的物理字体。 设备的纵横比是由设备上像素的宽度和高度构成的比率。
系统字体 (也称为 shell 或默认字体) 是用于标题栏、菜单和对话框中文本的字体。
特殊字体选择注意事项
尽管大多数字体选择操作都涉及用户,但在某些情况下,这并不成立。 例如,开发人员可能需要在应用程序中使用唯一字体在控件窗口中绘制文本。 若要选择适当的字体,应用程序必须能够确定哪些字体可用,创建描述其中一种可用字体的逻辑字体,然后在相应的设备上下文中选择该字体。
应用程序可以使用 EnumFonts 或 EnumFontFamilies 函数枚举可用字体。 建议使用 EnumFontFamilies,因为它枚举与姓氏关联的所有样式。 这对于具有多种或不同寻常样式的字体以及跨越国际边界的字体非常有用。
应用程序枚举可用字体并找到适当的匹配项后,它应使用字体枚举函数返回的值来初始化 LOGFONT 结构的成员。 然后,它可以调用 CreateFontIndirect 函数,向其传递指向初始化的 LOGFONT 结构的指针。 如果 CreateFontIndirect 函数成功,则应用程序可以通过调用 SelectObject 函数来选择逻辑字体。 初始化 LOGFONT 结构的成员时,请务必在 lfCharSet 成员中指定特定的字符集。 此成员在字体映射过程中非常重要,如果未正确初始化此成员,结果将不一致。 如果在 LOGFONT 结构的 lfFaceName 成员中指定字样名称,请确保 lfCharSet 值与 lfFaceName 中指定的字样字符集匹配。 例如,如果要选择诸如 MS Mincho 的字体,则必须将 lfCharSet 设置为SHIFTJIS_CHARSET预定义值。
许多东亚语言的字体有两个字样名称:英文名称和本地化名称。 CreateFont、 CreateFontIndirect 和 CreateFontIndirectEx 采用与语言匹配的系统区域设置的本地化字样名称,但采用所有其他系统区域设置的英语字样名称。 最好的方法是尝试一个名称,如果失败,请尝试另一个名称。 请注意,如果系统区域设置与字体的语言不匹配,EnumFontFamilies 和 EnumFontFamiliesEx 将返回英文字样名称。 从 Windows 2000 开始,这不再是问题,因为 CreateFont、CreateFontIndirect 和 CreateFontIndirectEx 的字体映射器可识别字样名称,而不考虑区域设置。