在 MFC 對話框應用中,修改 Edit、Static 等控件字體是常見需求。本文提供兩種創建字體的方法,並詳細說明字體對象生命周期管理的關鍵細節。
// MyDialog.h
class CMyDialog : public CDialogEx {
// ...
protected:
CFont m_Font; // 成員變量:隨對話框生命周期
CEdit m_ControlEdit; // DDX_Control 綁定的控件變量
};
// MyDialog.cpp
BOOL CMyDialog::OnInitDialog() {
CDialogEx::OnInitDialog();
// 創建字體:150 = 15 點 (單位:0.1點), "華文行楷"
m_Font.CreatePointFont(150, _T("華文行楷"), NULL);
// 應用到控件
m_ControlEdit.SetFont(&m_Font, FALSE); // FALSE = 不立即重繪
return TRUE;
}
CFont m_Font 必須作為類成員變量,不能在函數內部定義局部變量 (離開作用域會析構,導致控件使用無效字體)CreatePointFont 參數:nPointSize (0.1點為單位)、字體名稱、可選 CDC*SetFont 第二參數 bRedraw:TRUE 立即重繪,FALSE 延後 (推薦在 OnInitDialog 用 FALSE)
BOOL CMyDialog::OnInitDialog() {
CDialogEx::OnInitDialog();
// 完整參數創建
m_Font.CreateFont(
-11, // nHeight: 負值 = 字符高度 (含內部間距), 正值 = 輸出高度
0, // nWidth: 0 = 自動匹配最寬字符
0, // nEscapement: 字符基線與水平線夾角 (0.1度)
0, // nOrientation: 字符內部傾斜角度
FW_NORMAL, // nWeight: 粗細 (FW_DONTCARE/THIN/NORMAL/BOLD/HEAVY)
FALSE, // bItalic: 斜體
FALSE, // bUnderline: 下劃線
0, // cStrikeOut: 刪除線
ANSI_CHARSET, // nCharSet: 字符集
OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY,
FF_SWISS, // nPitchAndFamily: 變寬字體 + 瑞士字體族
_T("Arial") // lpszFacename: 字體名稱
);
// 獲取控件指針並設置
CEdit* pEdit = (CEdit*)GetDlgItem(IDC_EDIT1);
if (pEdit) pEdit->SetFont(&m_Font, FALSE);
return TRUE;
}
| 參數 | 常用值 | 說明 |
|---|---|---|
| nHeight | -12, -16, -20 | 負值 = 字符高度 (推薦),對應點數約為 |nHeight| * 72 / 96 |
| nWeight | FW_NORMAL(400), FW_BOLD(700) | FW_DONTCARE(0) 到 FW_HEAVY(900) |
| bItalic | TRUE/FALSE | 斜體 |
| bUnderline | TRUE/FALSE | 下劃線 |
| cStrikeOut | TRUE/FALSE | 刪除線 |
| nCharSet | ANSI_CHARSET, DEFAULT_CHARSET | GB2312 中文用 DEFAULT_CHARSET 或 CHINESEBIG5_CHARSET |
| nPitchAndFamily | FF_DONTCARE | DEFAULT_PITCH | 高 4 位字體族,低 4 位字符間距 |
| 錯誤代碼 | 現象 | 原因 | 修正 |
|---|---|---|---|
| CFont m_Font; // 局部變量 | 字體不生效/程式崩潰 | 對象析構,HFONT 失效 | 改為類成員變量 |
| SetFont(&m_Font, TRUE) | 閃爍/重繪異常 | OnInitDialog 中多次重繪 | 用 FALSE,最後統一 Invalidate |
| CreateFont 高度正值 | 字體過大/不準確 | 正值 = 輸出高度 (含外部間距) | 用負值指定字符高度 |
| 字體名稱拼寫錯誤 | 使用系統默認字體 | CreateFont 失敗靜默回退 | 用 EnumFontFamiliesEx 驗證名稱 |
void CMyDialog::OnButtonChangeFont() {
// 刪除舊字體 (可選,CFont 析構會自動 DeleteObject)
// m_Font.DeleteObject();
// 創建新字體
m_Font.CreatePointFont(200, _T("微軟雅黑"));
// 重新應用
m_ControlEdit.SetFont(&m_Font, TRUE); // 立即重繪
// 可選:調整控件大小適應新字體
CRect rect;
m_ControlEdit.GetClientRect(&rect);
CClientDC dc(&m_ControlEdit);
CFont* pOld = dc.SelectObject(&m_Font);
CSize sz = dc.GetTextExtent(_T("測試文本"));
dc.SelectObject(pOld);
m_ControlEdit.SetWindowPos(NULL, 0, 0, sz.cx + 10, sz.cy + 10, SWP_NOMOVE | SWP_NOZORDER);
}
CFont m_Font掌握 MFC 字體自定義,能讓你的對話框界面更專業、更符合品牌視覺規範。