一、问题的提出
在之前的编程中,我们对行距的使用,是定义了一个宏常量!
#define LINEHEIGHT 15
第一个问题:这是我们进过多次测试后得出的比较合适行距,大家可以试试其他的行距。
但是这样话,如果工程很大的话,有上万行代码的时候,就会定义很多的宏,所以呢,我们就希望可以让windows为我们动态的计算合适的行距。
第二个问题:那个15的单位是什么呢,是15像素,还是15英寸,也许有人会说,这还用想,肯定是15像素了,但其实是不对的,这是和映射关系有关的。
从上图我们可以看到,根据不同的映射方式,得到的实际尺寸是不同的,默认的是像素,还有其他的单位。
二、文本尺寸的测量
函数:GetTextMetri
函数功能:
GetTextMetrics 函数将当前字体的信息填充到指定缓冲区(TEXTMETRIC 结构)
API 函数原型:
BOOL GetTextMetrics(
_In_ HDC hdc,
_Out_ LPTEXTMETRIC lptm
);
复制代码
参数解析:
参数 含义
hdc 设备环境句柄
lptm 指向 TEXTMETRIC 结构的指针,该结构用于获得字体信息
返回值:
1. 如果函数调用成功,返回值是非 0;
2. 如果函数调用失败,返回值是 0。
备注:
1. 要确定一种字体是否为 TrueType 字体,可以通过调用 GetTextMetrics 函数,然后检查 TEXTMETRIC.tmPitchAndFamily 的值是否为 TMPF_TRUETYPE
2. 注意,调用 GetDC 函数返回的是一个未初始化的 DC,它具有“系统”(一个位图字体)作为默认字体。因此你需要先选择一种字体到 DC
TEXTMETRIC 结构
typedef struct tagTEXTMETRIC {
LONG tmHeight;
LONG tmAscent;
LONG tmDescent;
LONG tmInternalLeading;
LONG tmExternalLeading;
LONG tmAveCharWidth;
LONG tmMaxCharWidth;
LONG tmWeight;
LONG tmOverhang;
LONG tmDigitizedAspectX;
LONG tmDigitizedAspectY;
TCHAR tmFirstChar;
TCHAR tmLastChar;
TCHAR tmDefaultChar;
TCHAR tmBreakChar;
BYTE tmItalic;
BYTE tmUnderlined;
BYTE tmStruckOut;
BYTE tmPitchAndFamily;
BYTE tmCharSet;
} TEXTMETRIC, *PTEXTMETR
成员 含义
**tmHeight 字符高度(tmAscent + tmDescent)
tmAscent 字符上部高度(基线以上)
tmDescent 字符下部高度(基线以下)
tmInternalLeading 内部间距(包含在 tmHeight 中),该间距通常被用于显示重音符号
tmExternalLeading 外部间距,这个值是字体设计者建议在两行文字间留出的空间大小
tmAveCharWidth 1. 字体中小写字符的平均宽度(一般定义为字母 x 的宽度)
2. 字体中大写字符的平均宽度一般是该值的 1.5 倍计算
3. 此值不包括字体所需要的加粗和倾斜字符
tmMaxCharWidth 字体中最宽字符的宽度
tmWeight 字体的粗细轻重程度**
tmOverhang 加入某些拼接字体上的附加高度
tmDigitizedAspectX 字体设计所针对的设备水平方向
tmDigitizedAspectY 字体设计所针对的设备垂直方向
tmFirstChar 为字体定义的第一个字符
tmLastChar 为字体定义的最后一个字符
tmDefaultChar 字体中所没有字符的替代字符
tmBreakChar 定义文本对齐截断操作所显示的字符
tmItalic 如果该值非零,则为斜体字体
tmUnderlined 如果该值非零,则为带下横线字体
tmStruckOut 如果该值非零,则为带删除线字体(字符中间画一条线)
tmPitchAndFamily 1. 如果低位为 0,表示等宽字体,小写和大写字母平均宽度一样
2. 如果低位为 1,表示变宽字体,大写字母是小写平均宽度的 3/2 倍
tmCharSet 字体的字符集
转自鱼c论坛
这里那,我们需要掌握给结构的前7个成员,结合下面的图片理解。
TEXTMETRIC tm;
static int cxChar, cyChar;
switch (message)
{
case WM_CREATE:
hdc = GetDC(hwnd);
GetTextMetrics(hdc, &tm);
cxChar = tm.tmAveCharWidth;
cyChar = tm.tmHeight + tm.tmExternalLeading;
ReleaseDC(hwnd, hdc);
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
for (int i = 0; i < 10; i++)
{
StringCchPrintf(szBuffer, 128, TEXT("%d: %s"), i + 1, TEXT("爱心天使的守护!"));
StringCchLength(szBuffer, 128, &iTarget);
TextOut(hdc, cxChar, i*cyChar, szBuffer, lstrlen(szBuffer));
}
EndPaint(hwnd, &ps);
return 0;
我们可以通过以上的调用来动态获取当前字符的大小,所以切记不要去猜测字符的大小。