如何使用CreateFontA设置字体大小?

use*_*644 0 c++ winapi gdi

我不习惯CreateFontA,但我正在为一个使用这个功能的游戏做一个模组,我也必须使用它。

我设法更改字体,但更改字体大小时遇到​​一些麻烦。

我想使用11px的字体,我该如何实现呢?我尝试将宽度和高度设置为 11,但出现了严重错误。

Jer*_*fin 6

答案是(或者至少可以是)有些不平凡。

首先,您可以选择两个单独的高度:字符本身的高度,或“正常”字符所在的单元格的高度(但是,例如,带有下降部的字母y通常会延伸到单元格之外)。因此,对于相同大小的字体,字符单元通常会比字符本身的大小稍大。

要根据字符单元高度选择字体,请传递一个正数作为高度。要根据字符本身的高度进行选择,请传递一个负数(其绝对值将用作高度)。

因此,我们假设您希望字符本身的高度为 11 磅(因此我们需要为高度传递一个负数),并且您希望宽度为当前字体的默认值。我们还假设您正在处理 MM_TEXT 模式,其中逻辑单元等于一个像素。

由于 Windows 使用该术语,1 点是 1/72英寸(注意:72 点表示英寸并不通用 - 例如,有些使用 72.72 点表示英寸 - 请随意修改以下代码如果您需要遵守“点”的不同定义)。

因此,要计算尺寸,我们可以首先检索屏幕上每英寸(垂直)的像素数,然后计算正确数量的点的像素数:

static const int points_per_inch = 72;
int pixels_per_inch = GetDeviceCaps(hDC, LOGPIXELSY);
int pixels_height = - (points * pixels_per_inch / points_per_inch);
Run Code Online (Sandbox Code Playgroud)

[微软有一个MulDiv功能可以确保计算中不会出现中间值溢出,但除非您使用的是 16 位机器或真正巨大的字体,否则这主要是寻找问题的解决方案。]

由于我们需要默认宽度,因此我们将传递 0 作为宽度。

所以,我们最终得到这样的结果:

HFONT font = CreateFont(pixels_height, 0, // size
                        0, 0, 0, // normal orientation
                        FW_NORMAL,   // normal weight--e.g., bold would be FW_BOLD
                        false, false, false, // not italic, underlined or strike out
                        DEFAULT_CHARSET,
                        OUT_OUTLINE_PRECIS, // select only outline (not bitmap) fonts
                        CLIP_DEFAULT_PRECIS,
                        CLEARTYPE_QUALITY,
                        VARIABLE_PITCH | FF_SWISS,
                        "Arial");
Run Code Online (Sandbox Code Playgroud)