切换系统至UTF-8后为何两个对话框字体权重变为700?
问题背景
我们在多台Windows 10电脑开启UTF-8(beta)代码页后,应用内数百个对话框中,仅有两个出现字体异常。我们通过以下代码临时修复了问题,但存在两个疑问:
- 为何开启UTF-8后突然需要这类修复?
- 为何只有这两个对话框出现问题?
另外,我们在.rc、.cpp及.h文件中均未找到任何相关字体设置。
修复代码
static CFont newFont; void SetDialogFontToNormal(CDialog* c) { c->ModifyStyleEx(0, WS_EX_DLGMODALFRAME); CFont *main = c->GetFont(); LOGFONT lf; main->GetLogFont(&lf); lf.lfWeight = 100; // 原本是700,为何会出现这种情况? newFont.CreateFontIndirectW(&lf); c->SetFont(&newFont, true); for (CWnd* pControl = c->GetWindow(GW_CHILD); pControl; pControl = pControl->GetWindow(GW_HWNDNEXT)) { pControl->SetFont(&newFont, true); } } BOOL DwgEdit::OnInitDialog() { CDialog::OnInitDialog(); SetDialogFontToNormal(this);
异常对话框的资源定义
IDD_DRAWINGEDITOR DIALOGEX 0, 0, 305, 229 STYLE DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME CAPTION "Drawing Editor" FONT 8, "MS Sans Serif" BEGIN LISTBOX IDC_DWGLIST,7,5,104,177,LBS_NOINTEGRALHEIGHT | LBS_DISABLENOSCROLL | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "&Add",IDC_ADDBUTTON,7,186,49,14 .... more controls END
临时解决方法
将资源中的FONT行替换为以下内容后,问题消失:
FONT 8, "MS Shell Dlg", 0, 0, 0x1
正常对话框的资源定义对比
IDD_ACTDRAWING DIALOG 0, 0, 135, 214 STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "Active Drawing" FONT 8, "MS Sans Serif" BEGIN LISTBOX IDC_DWGLIST,0,0,134,176,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP DEFPUSHBUTTON "OK",IDOK,13,195,50,14 PUSHBUTTON "Cancel",IDCANCEL,71,195,50,14 ... END
原因分析
- UTF-8代码页的字体映射变化:开启系统UTF-8(beta)后,Windows的字体匹配逻辑会调整。"MS Sans Serif"是老旧字体,在UTF-8环境下系统可能无法正确加载其常规字重, fallback 到了加粗(700)变体,导致显示异常。而"MS Shell Dlg"是系统推荐的对话框字体,会自动映射到当前系统默认UI字体(如Segoe UI),在UTF-8环境下能稳定加载常规字重。
- 对话框样式差异触发异常:对比异常与正常对话框的STYLE,异常对话框缺少
DS_MODALFRAME样式,多了WS_THICKFRAME。这种差异导致Windows创建对话框时的字体初始化逻辑不同:带DS_MODALFRAME的对话框走标准模态字体加载流程,不带的则触发特殊的字体 fallback 逻辑,在UTF-8环境下出现了字重错误。
内容的提问来源于stack exchange,提问作者Alan Baljeu
相关产品推荐
相关产品推荐

