| 參數 | 名稱 | 說明 | 常用值 |
| 1 | nHeight | 字體高度 (邏輯單位),負值 = 字符高度 (不含內部導行),正值 = 字符盒高度 | -nPoints * 20 (twips 轉換) |
| 2 | nWidth | 平均字符寬度,0 = 自動按比例 | 0 |
| 3 | nEscapement | 字符基線與水平軸夾角 (0.1 度單位) | 0 |
| 4 | nOrientation | 字符盒與水平軸夾角,通常同 nEscapement | 0 |
| 5 | nWeight | 粗細 (0-1000),400=Normal, 700=Bold | 400 / 700 |
| 6 | bItalic | 斜體 | TRUE/FALSE |
| 7 | bUnderline | 下劃線 | TRUE/FALSE |
| 8 | cStrikeOut | 刪除線 | TRUE/FALSE |
| 9 | nCharSet | 字符集 | ANSI_CHARSET / DEFAULT_CHARSET / GB2312_CHARSET |
| 10 | nOutPrecision | 輸出精度 | OUT_DEFAULT_PRECIS / OUT_TT_PRECIS |
| 11 | nClipPrecision | 裁剪精度 | CLIP_DEFAULT_PRECIS |
| 12 | nQuality | 輸出品質 | DEFAULT_QUALITY / PROOF_QUALITY / CLEARTYPE_QUALITY |
| 13 | nPitchAndFamily | 間距與字體家族 | DEFAULT_PITCH | FF_ROMAN / FF_SWISS / FF_MODERN |
| 14 | lpszFace | 字體名稱 (如 "Tahoma", "微軟正黑體", "Consolas") | 字串指針 |
參數 15-21 為保留/內部用,通常傳 0/NULL。
可縮放字體繪製完整實戰 (MM_ANISOTROPIC + Twips)
目標
在視窗縮放時,文字**保持物理尺寸不變** (如 12pt 永遠是 12pt),而非像素級縮放。
核心代碼
// 1. OnPrepareDC — 設定 Twips 映射模式 (1 邏輯單位 = 1/1440 英吋)
void CMyView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo) {
pDC->SetMapMode(MM_ANISOTROPIC);
pDC->SetWindowExt(1440, 1440); // 邏輯單位 = 1 twip
// 視口範圍 = 每邏輯英寸的像素數 (GetDeviceCaps)
pDC->SetViewportExt(pDC->GetDeviceCaps(LOGPIXELSX),
-pDC->GetDeviceCaps(LOGPIXELSY)); // 負號翻轉 Y 軸
}
// 2. 輔助函數:繪製指定磅值文字
void CMyView::ShowFont(CDC* pDC, int& nPos, int nPoints) {
TEXTMETRIC tm;
CFont font;
// 創建字體:高度 = -nPoints * 20 (twips)
font.CreateFont(-nPoints * 20, 0, 0, 0, 400, FALSE, FALSE, 0,
ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN, "Tahoma");
CFont* pOldFont = pDC->SelectObject(&font);
pDC->GetTextMetrics(&tm); // 獲取字體度量
CString str;
str.Format("%d磅 WINDOWS 中文字體範例 1234567890", nPoints);
CSize size = pDC->GetTextExtent(str);
pDC->TextOut(0, nPos, str); // nPos 為邏輯座標 Y 位置 (twips)
pDC->SelectObject(pOldFont); // 還原字體
// 更新下一行 Y 位置:字體高度 + 外部導行
nPos -= tm.tmHeight + tm.tmExternalLeading;
}
// 3. OnDraw — 循環繪製 12pt 到 24pt
void CMyView::OnDraw(CDC* pDC) {
int nPos = 0;
for (int i = 12; i <= 24; i += 2) {
ShowFont(pDC, nPos, i);
}
}
關鍵點解析
MM_ANISOTROPIC + SetWindowExt(1440,1440) + SetViewportExt(LOGPIXELSX, -LOGPIXELSY) 建立 **1 邏輯單位 = 1 twip** 的映射,與印表機單位一致。
CreateFont 高度參數用 **負值** (-nPoints * 20) 表示「字符高度」(不含內部導行),符合排版標準。
TEXTMETRIC 提供 tmHeight (字體高度)、tmExternalLeading (行間距) 等度量,用於精確換行定位。
- 視窗縮放時,
OnPrepareDC 重新計算 SetViewportExt,文字物理尺寸自動保持不變。
字體度量結構 TEXTMETRIC 速查
typedef struct tagTEXTMETRIC {
int tmHeight; // 字體高度 (含內部導行)
int tmAscent; // 基線以上高度
int tmDescent; // 基線以下高度
int tmInternalLeading; // 內部導行 (重音符空間)
int tmExternalLeading; // 外部導行 (行間距建議值)
int tmAveCharWidth; // 平均字符寬度
int tmMaxCharWidth; // 最大字符寬度
int tmWeight; // 粗細
BYTE tmItalic; // 斜體標誌
BYTE tmUnderlined; // 下劃線標誌
BYTE tmStruckOut; // 刪除線標誌
BYTE tmFirstChar; // 首字符
BYTE tmLastChar; // 末字符
BYTE tmDefaultChar; // 預設字符
BYTE tmBreakChar; // 換行字符
BYTE tmPitchAndFamily; // 間距與家族
BYTE tmCharSet; // 字符集
int tmOverhang; // 合成粗體/斜體額外寬度
int tmDigitizedAspectX; // 水平縱橫比
int tmDigitizedAspectY; // 垂直縱橫比
} TEXTMETRIC;
雷神心法:字體選擇指南
- **UI 介面**:「微軟正黑體」 (Win7+)、"Microsoft YaHei" (Vista+)、"Segoe UI" (Win10+) — 系統預裝、渲染優化、支援 ClearType。
- **程式碼編輯/終端機**:「Consolas」、「Cascadia Code」、「Fira Code」 — 等寬、連字符支援、可讀性強。
- **列印/報表**:「Times New Roman」、「標楷體」 — 經典襯線/無襯線,列印效果穩定。
- **跨平台/嵌入式**:嵌入 TTF 字體檔案 (用
AddFontResourceEx 載入),避免系統缺字。
(MFC 中用 CFont::CreateFontIndirect + LOGFONT 結構更靈活)。
下一篇預告
Day 9:模態對話框與通用控件 (上) — 資源編輯器設計對話框、ClassWizard 綁定變數/消息、DDX/DDV 機制、體育彩票選號器完整實戰 (隨機數種子、去重、排序、UpdateData)。
- 上一篇文章: 《VC++技術內幕》學習筆記(七):GDI 核心 — CDC 設備環境、六大 GDI 物件、庫存物件、SelectObject 保存恢復模式
- 下一篇文章: 《VC++技術內幕》學習筆記(九):模態對話框與通用控件實戰 (上) — 體育彩票選號器完整開發
Copyright ©
程式碼之家 All Rights Reserved