首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 組合語言

Win32 組合語言教學:字型建立與彩色文字繪製(CreateFont / SetTextColor / SetBkColor)

     編輯:組合語言

教學目標

本篇示範在 WM_PAINT 中建立邏輯字型(CreateFont)、選入裝置環境(SelectObject)、設定文字/背景色(SetTextColor/SetBkColor)、繪製文字(TextOut),並正確還原裝置環境。涵蓋 RGB 色彩宏、LOGFONT 參數對照、GDI 物件生命週期管理。

RGB 色彩宏

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 位元值,避免結構體填充麻煩。

CreateFont 參數完整對照

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" 字體名稱

關鍵參數說明

  • nHeight:負值 = 字元高度(含內部間距),正值 = 字元盒高度。此處 24 為正值。
  • nWidth=16:非零強制寬度,避免 Script 字體過窄導致難以辨識。
  • nWeight:FW_DONTCARE(0) 到 FW_BLACK(900),常用 FW_NORMAL(400)/FW_BOLD(700)。
  • cPitchAndFamily:低 2 位 = Pitch (DEFAULT/FIXED/VARIABLE),高 4 位 = Family (FF_DONTCARE/ROMAN/SWISS/MODERN/SCRIPT/DECORATIVE)。

繪製流程與 GDI 物件管理

.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

關鍵規則

  1. 建立 → 選入 → 使用 → 還原 → 刪除:範例中字型為單次使用,EndPaint 隱含釋放 DC 時系統會自動清理未刪除的字型,但正規寫法應在 WM_DESTROY 呼叫 DeleteObject。
  2. SelectObject 返回舊物件:必須保存以便還原,否則 DC 洩漏導致 GDI 物件耗盡。
  3. SetBkColor 影響 TextOut 背景:若需透明背景,改用 SetBkMode(hdc, TRANSPARENT)。

擴展:CreateFontIndirect 與 LOGFONT

頻繁建立字型時,建議改用 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,效能與可維護性俱佳。

常見錯誤

  • ❌ 忘記還原舊字型 → 後續繪圖異常、GDI 洩漏
  • ❌ 字體名稱拼寫錯誤 → 系統替換預設字體,外觀不符預期
  • ❌ nHeight 正負號搞錯 → 字體大小與預期不符
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved