CreateFontIndirect函数简介

C++ 专栏收录该内容
72 篇文章 1 订阅

CreateFontIndirect函数功能

  • 创建一个逻辑字体,创建的字体具有LOGFONT对象确定的特性。创建的字体后边就可以由任何设备环境选择作为当前的字体。
HFONT CreateFontIndirect( 
CONST LOGFONT *lplf   //pointer to logical font structure
);

lplf是一个定义逻辑字体特性的LOGFONT结构指针。LOGFONT结构体定义了字体的特性:

typedef struct tagLOGFONT {
  LONG  lfHeight;  //字体高度
  LONG  lfWidth;  //字体宽度
  LONG  lfEscapement;  //字体显示的角度
  LONG  lfOrientation; //字体的角度
  LONG  lfWeight; //字体的磅数
  BYTE  lfItalic; //斜体字体
  BYTE  lfUnderline; //带下划线字体
  BYTE  lfStrikeOut; //带删除线字体
  BYTE  lfCharSet; //所需字符集
  BYTE  lfOutPrecision; //输出的精度
  BYTE  lfClipPrecision;//裁剪精度
  BYTE  lfQuality;//逻辑字体和输出设备的实际字体间的间距
  BYTE  lfPitchAndFamily; //字体间距和字体集
  TCHAR lfFaceName[LF_FACESIZE]; //字体名称
} LOGFONT, *PLOGFONT;

这里是MSDN上对该结构体的介绍,大家可参考,我不做赘述。

  • 返回值
    如果函数创建成功,返回逻辑字体的句柄,否则返回NULL值。
    当用SelectObject函数选择创建的字体后,GDI的字体映射机制就会将其与已经存在的物理字体进行匹配,如果找不到完全一样的字体,GDI会提供一种选择字体,这种字体大多数特性与要求的特性相符。当不需要这种字体的时候,应该条用DeleteObject函数删除。
    MSDN上的原文是这么写的:

The CreateFontIndirect function creates a logical font with thecharacteristics specified in the LOGFONT structure. When this font is selected by using the Select Object function, GDI’s font mapper attempts to match the logical font with an existing physical font. If it fails to find an exact match, it provides an alternative whose characteristics match as many of the requested characteristics as possible.

  • 用CreateFontIndirect方法创建字体
hdc = BeginPaint(hwnd,&ps);  //前面声明了LOGFONT lonfont;  
GetObject(GetStockObject(SYSTEM_FONT),sizeof(LOGFONT),&logfont);
logfont.lfItalic = true;
logfont.lfItalic=true;//使用斜体  
logfont.lfHeight=16;//字体高度为16PX  
logfont.lfWeight=20;//字体宽度为20PX  
logfont.lfCharSet=GB2312_CHARSET;//国标2312  
wsprintf(logfont.lfFaceName,TEXT("%s"),TEXT("宋体"));  
hfont=CreateFontIndirect(&logfont);//字体为宋体  
SelectObject(hdc,hfont);......//,使用SelectObject添加到HDC环境中,后面就是你要输出的东西 

警示

  • 使用CreateFontIndirect方法创建字体时,一定要注意一点,那就是大多数的东亚的语言有两个字体名称,一个是英语名称一个是本地名称。CreateFont和CreateFontIndirect在本地系统环境上仅识别字体的本地名称,同时识别非本地的字体的应为名称。也就是说,如果用CreateFont和CreateFontIndirect创建一个应为名称的字体不能创建时,那么请尝试一下该字体的本地名称或者将本地系统的环境修改为非东亚地区。利用EnumFonts,EnumFontFamilies和EnumFamiliesEx就可以查找字体的英文名称。
    这是关于EnumFamiliesEx的使用方法MSDN上的说明,供大家参考。

  • Creating a Logical Font

也可以Creating a Logical Font弹出对话框,从而自己选择创建你想要的字体,具体代码如下:

HFONT FAR PASCAL MyCreateFont( void ) 
{ 
    CHOOSEFONT cf; 
    LOGFONT lf; 
    HFONT hfont; 

    // Initialize members of the CHOOSEFONT structure.  

    cf.lStructSize = sizeof(CHOOSEFONT); 
    cf.hwndOwner = (HWND)NULL; 
    cf.hDC = (HDC)NULL; 
    cf.lpLogFont = &lf; 
    cf.iPointSize = 0; 
    cf.Flags = CF_SCREENFONTS; 
    cf.rgbColors = RGB(0,0,0); 
    cf.lCustData = 0L; 
    cf.lpfnHook = (LPCFHOOKPROC)NULL; 
    cf.lpTemplateName = (LPSTR)NULL; 
    cf.hInstance = (HINSTANCE) NULL; 
    cf.lpszStyle = (LPSTR)NULL; 
    cf.nFontType = SCREEN_FONTTYPE; 
    cf.nSizeMin = 0; 
    cf.nSizeMax = 0; 

    // Display the CHOOSEFONT common-dialog box.  

    ChooseFont(&cf); 

    // Create a logical font based on the user's  
    // selection and return a handle identifying  
    // that font.  

    hfont = CreateFontIndirect(cf.lpLogFont); 
    return (hfont); 
} 

会产生一个dialogbox显示可用的字体,当你选中某字体并ok时,chooseFont会用你选择的字体的数据初始化LOGFONT结构体从而用createFontIndirect创建本地字体。

  • 最后出一种最方面最简单的方法解决上述字体本地化问题。
    从根本上来讲,无论东亚还是什么地区字体的差异从根本上来讲都是字符集的不同导致的字体名称略有不同,然而微软会根据系统设置中的location从而设定缺省的字符集,例如,如果系统设置为United States ,则CreateFontIndirect缺省的字符集就是ANSI_CHARSET.
    If an application uses a font with an unknown character set, it should not attempt to translate or interpret strings that are rendered with that font.
    This parameter is important in the font mapping process. To ensure consistent results, specify a specific character set. If you specify a typeface name in the lfFaceName member, make sure that the lfCharSet value matches the character set of the typeface specified in lfFaceName.
    这是MSDN上的原话,所以用到什么字体一定要设置这个字体对应的字符集,这样上边的情况就迎刃而解了。
    我就在这上边吃了一个很大的苦头,引以为戒。特此记录,以备忘。
  • 3
    点赞
  • 2
    评论
  • 5
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

评论 2 您还未登录,请先 登录 后发表或查看评论
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页

打赏作者

KFPA

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值