Alone Cáfe
There is no limit to learning.
阿龙咖啡
文本和客户区的尺寸(3)

TextOut 函数

TextOut 函数是在客户区指定位置显示文本的 GDI 函数,它的原型如下:

BOOL TextOut(
  HDC hdc,           // 设备环境句柄
  int nXStart,       // 开始位置的 x 坐标
  int nYStart,       // 开始位置的 y 坐标
  LPCTSTR lpString,  // 要显示的字符串
  int cbString       // 要显示字符个数(如果是 Unicode 字符则为原本的两倍)
);

文本的尺寸

1、TEXTMETRIC 结构用于存放字符尺寸的各种值,最常用的有 7 个值:

typedef struct tagTEXTMETRIC { 
  LONG tmHeight;          // 字符高度(tmAscent 与 tmDescent)之和
  LONG tmAscent;          // 基线之上的最大高度
  LONG tmDescent;         // 基线之下的最大高度
  LONG tmInternalLeading; // 内部间距(包含于 tmAscent 之中,通常为了显示重音符号)
  LONG tmExternalLeading; // 外部间距,行间距
  LONG tmAveCharWidth;    // 小写字符的加权平均宽度
  LONG tmMaxCharWidth;    // 最宽的字符的宽度
  // 其他字段
} TEXTMETRIC, *PTEXTMETRIC;

2、GetTextMetrics 函数用于获取字体的尺寸,它的第一个参数是当前的设备环境句柄,第二个参数是要填充的 TEXTMETRIC 结构的地址:

BOOL GetTextMetrics(
  HDC hdc,            // 当前设备环境句柄
  LPTEXTMETRIC lptm   // 要填充的 TEXTMETRIC 结构的地址
);

Windows 运行时,系统字体不会变化。所以程序只需要调用一次 GetSystemMetrics 函数(最好在处理 WM_CREATE 消息的时候)

获取系统字体的宽度和高度的示例代码:

// ......
// cxChar 为平均字符宽度,cyChar 为字符总高度,cxCaps 为大写字符的平均宽度
static int cxChar, cyChar, cxCaps;
TEXTMETRIC tm;
// ......
case WM_CREATE:
    hdc = GetDC(hwnd);

    GetTextMetrics(hdc, &tm);

    cxChar = tm.tmAveCharWidth;
    // tmPitchAndFamily 字段的低位决定字体是否为等宽字体,1为变宽,0为等宽。变宽时 cxCaps 是 cxChar 的1.5倍,等宽时 cxCaps 等于 cxChar
    cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * cxChar / 2;
    cyChar = tm.tmHeight + tm.tmExternalLeading;

    ReleaseDC(hwnd, hdc);
    return 0;
// ......

文本的对齐

调用 SetTextAlign 函数可以指定显示文本使用的坐标从文本区域的何处开始计算,示例如下:

// 指定坐标从文本区域的右上角开始计算
SetTextAlign(hdc, TA_RIGHT | TA_TOP);

客户区的尺寸

当窗口大小发生变化时,Windows 会向窗口过程发送一条 WM_SIZE 消息,相应的 lParam 变量的低位字是客户区的宽度,高位字是客户区的高度。示例代码如下:

// ......
case WM_SIZE:
    cxClient = LOWORD(lParam); // 低位字为客户区宽度
    cyClient = HIWORD(lParam); // 高位字为客户区高度
    
    // WM_SIZE 消息响应代码
    
    return 0;
// ......
赞赏
知识共享许可协议本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名。

发表评论

textsms
account_circle
email

阿龙咖啡

文本和客户区的尺寸(3)
TextOut 函数TextOut 函数是在客户区指定位置显示文本的 GDI 函数,它的原型如下:BOOL TextOut( HDC hdc, // 设备环境句柄 int nXStart, // 开始位置的 x 坐标 in…
扫描二维码继续阅读
2018-05-23