本篇示範在 WM_PAINT 中建立邏輯字型(CreateFont)、選入裝置環境(SelectObject)、設定文字/背景色(SetTextColor/SetBkColor)、繪製文字(TextOut),並正確還原裝置環境。涵蓋 RGB 色彩宏、LOGFONT 參數對照、GDI 物件生命週期管理。
RGB MACRO Red, Green, Blue
XOR EAX, EAX
MOV AH, Blue
SHL EAX, 8
MOV AH, Green
MOV AL, Red
ENDM
呼叫 RGB 200, 200, 50 後 EAX=0032C8C8h (BGR 順序),直接傳遞給 SetTextColor/SetBkColor。此宏將 3 個 8 位元色道打包為單一 32 位元值,避免結構體填充麻煩。
INVOKE CreateFont,
24, ; nHeight : 字體高度 24 邏輯單位
16, ; nWidth : 寬度 16 (0=自動)
0, ; nEscapement : 字元旋轉角度 (0.1 度單位)
0, ; nOrientation : 字體基線旋轉
400, ; nWeight : FW_NORMAL (400)
0, ; cItalic : 非斜體
0, ; cUnderline : 無底線
0, ; cStrikeOut : 無刪除線
OEM_CHARSET, ; cCharSet : 系統預設字元集
OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY,
DEFAULT_PITCH OR FF_SCRIPT, ; 可變寬度 + Script 字體家族
ADDR FontName ; "Script" 字體名稱
FW_DONTCARE(0) 到 FW_BLACK(900),常用 FW_NORMAL(400)/FW_BOLD(700)。.ELSEIF uMsg==WM_PAINT
INVOKE BeginPaint, hWnd, ADDR ps
MOV hdc, EAX
INVOKE CreateFont, ... ; 建立邏輯字型 → HFONT
INVOKE SelectObject, hdc, EAX ; 選入 DC,返回舊 HFONT
MOV hfont, EAX ; 保存舊字型
RGB 200, 200, 50 ; 文字色:淡黃
INVOKE SetTextColor, hdc, EAX
RGB 0, 0, 255 ; 背景色:藍
INVOKE SetBkColor, hdc, EAX
INVOKE TextOut, hdc, 0, 0, ADDR TestString, SIZEOF TestString
INVOKE SelectObject, hdc, hfont ; 還原舊字型
INVOKE EndPaint, hWnd, ADDR ps
EndPaint 隱含釋放 DC 時系統會自動清理未刪除的字型,但正規寫法應在 WM_DESTROY 呼叫 DeleteObject。SetBkMode(hdc, TRANSPARENT)。頻繁建立字型時,建議改用 CreateFontIndirect + LOGFONT 結構體:
LOGFONT STRUCT
lfHeight LONG ?
lfWidth LONG ?
lfEscapement LONG ?
lfOrientation LONG ?
lfWeight LONG ?
lfItalic BYTE ?
lfUnderline BYTE ?
lfStrikeOut BYTE ?
lfCharSet BYTE ?
lfOutPrecision BYTE ?
lfClipPrecision BYTE ?
lfQuality BYTE ?
lfPitchAndFamily BYTE ?
lfFaceName BYTE 32 DUP(?)
LOGFONT ENDS
一次填寫結構體,多次呼叫 CreateFontIndirect,效能與可維護性俱佳。