能否通过编程方式设置Inno Setup向导字体及DialogFontName?
解决方案:通过脚本动态设置对话框字体
由于Inno Setup 5.6.1中[LangOptions]的DialogFontName和[Setup]的DefaultDialogFontName确实不支持运行时常量展开,无法直接通过配置节动态切换字体。要实现非XP系统使用Segoe UI字体的需求,需要通过Windows API在脚本中动态替换对话框及控件的字体。
实现步骤
- 判断系统版本:通过
GetWindowsVersion函数识别是否为XP系统(版本号5.1)。 - 创建目标字体:在非XP系统中创建Segoe UI字体对象。
- 替换现有窗口字体:枚举主窗口及所有子控件,发送
WM_SETFONT消息设置新字体。 - 处理后续窗口:通过窗口钩子捕获新创建的对话框,自动应用字体设置。
完整脚本代码
const WM_SETFONT = $0030; GWL_WNDPROC = -4; LOGPIXELSX = 88; type TFNWndProc = function(hWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; var OldWndProc: TFNWndProc; SegoeUIFont: HFONT; function EnumChildProc(hWnd: HWND; lParam: LPARAM): BOOL; stdcall; begin SendMessage(hWnd, WM_SETFONT, lParam, 1); Result := True; end; procedure SetFontToWindow(hWnd: HWND; Font: HFONT); begin SendMessage(hWnd, WM_SETFONT, Font, 1); EnumChildWindows(hWnd, @EnumChildProc, Font); end; function NewWndProc(hWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; begin if Msg = WM_INITDIALOG then begin SetFontToWindow(hWnd, SegoeUIFont); end; Result := OldWndProc(hWnd, Msg, wParam, lParam); end; function InitializeSetup(): Boolean; var WinVer: TWindowsVersion; DC: HDC; LogPixelsX: Integer; FontHeight: Integer; begin Result := True; GetWindowsVersion(WinVer); // 仅在非XP系统(版本号≠5)启用Segoe UI if WinVer.Major <> 5 then begin DC := GetDC(0); LogPixelsX := GetDeviceCaps(DC, LOGPIXELSX); ReleaseDC(0, DC); // 计算与Inno默认8pt字体匹配的高度 FontHeight := -MulDiv(8, LogPixelsX, 72); // 创建Segoe UI字体 SegoeUIFont := CreateFont(FontHeight, 0, 0, 0, FW_NORMAL, False, False, False, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH or FF_DONTCARE, 'Segoe UI'); if SegoeUIFont <> 0 then begin // 应用字体到向导主窗口 SetFontToWindow(WizardForm.Handle, SegoeUIFont); // 安装窗口过程钩子,处理后续弹出的对话框 OldWndProc := TFNWndProc(GetWindowLongPtr(WizardForm.Handle, GWL_WNDPROC)); SetWindowLongPtr(WizardForm.Handle, GWL_WNDPROC, NativeInt(@NewWndProc)); end; end; end; procedure DeinitializeSetup(); begin // 释放字体资源,避免内存泄漏 if SegoeUIFont <> 0 then begin DeleteObject(SegoeUIFont); end; end;
注意事项
- 该方法会替换向导窗口、自定义页面及大部分标准对话框的字体,但极少数系统原生控件可能不响应
WM_SETFONT消息。 - 字体高度计算确保与Inno Setup默认的8pt字体大小一致,避免界面布局错乱。
- 必须在
DeinitializeSetup中释放字体对象,防止内存泄漏。
内容的提问来源于stack exchange,提问作者catnip
相关产品推荐
相关产品推荐

