首先,使用menu控件时,菜单项的字体大小使用默认字体大小,且在高DPI缩放比时,会出现字体过度缩放的情况,
如下图为100%缩放比时:
其中,ui资源文件代码如下:
<?xml version="1.0" encoding="utf-8"?>
<Window>
<Font id="0" name="微软雅黑" size="12" default="true" shared="true" />
<Default name="Menu" value="inset="3,4,3,4" itemtextpadding="45,0,0,0" itemtextcolor="#FF333333" itemselectedtextcolor="#FF333333" bkcolor="#FFF9F9F9" itembkcolor="#FFF9F9F9" itemselectedbkcolor="#FFE0E0E0" font="0"" />
<Menu>
<MenuElement text="切换语言" expland="true" height="30" icon="image\switch_lang.png" iconsize="17,17" width="124">
<MenuElement name="Menu_Tray_Lang_zh-CN" text="中文简体" height="30" icon="image\lang_cn.png" iconsize="17,17" width="124"/>
<MenuElement name="Menu_Tray_Lang_en-US" text="English" height="30" icon="image\lang_us.png" iconsize="17,17" width="124"/>
<MenuElement name="Menu_Tray_Lang_zh-TW" text="中文繁體" height="30" icon="image\lang_tw.png" iconsize="17,17" width="124"/>
</MenuElement>
<MenuElement name="Menu_Tray_Exit" height="30" text="退 出" icon="image\quit_app.png" iconsize="17,17" width="124"/>
</Menu>
</Window>
虽然再Default中已经确定了font=“0”,但是在创建菜单时,MenuElement 无法继承该属性,所以MenuElement 的font属性值为-1,在绘制文字时会获取带有default="true"属性的字体,之前有试验过在MenuElement 中添加font="0"属性,但是MenuElement 的font属性值依然为-1,这应该也是一个问题,暂时还没有研究为什么设置font属性后font属性值依然为-1。
依据上面的分析,创建菜单栏时,需要在CPaintManagerUI中添加字体信息,具体代码在UIMenu.cpp文件的CMenuWnd::OnCreate函数中,该函数调用了CDialogBuilder::Create函数,在CDialogBuilder::Create中,对Font属性值的解析是没有问题的,但是在设置默认字体属性时,调用CPaintManagerUI::SetDefaultFont函数时,传入的size值做了一次CDPI::Scale转换,此时将字体做了一次放大,而且此处放大的是字体大小,比如上面font="0"的字体大小时12,此处做了一次转换后,字体大小变为了18,之后再做绘制时系统根据字体大小为18进行绘制就会出现字体过大的问题。
下图是DPI为150%时的相识效果:
可以看出,图中文字的显示比例明显比DPI为100%时要大的多。
问题代码摘录见下:
if( _tcsicmp(pstrClass, _T("Font")) == 0 ) {
nAttributes = node.GetAttributeCount();
int id = -1;
LPCTSTR pFontName = NULL;
int size = 12;
bool bold = false;
bool underline = false;
bool italic = false;
bool defaultfont = false;
bool shared = false;
for( int i = 0; i < nAttributes; i++ ) {
pstrName = node.GetAttributeName(i);
pstrValue = node.GetAttributeValue(i);
if( _tcsicmp(pstrName, _T("id")) == 0 ) {
id = _tcstol(pstrValue, &pstr, 10);
}
else if( _tcsicmp(pstrName, _T("name")) == 0 ) {
pFontName = pstrValue;
}
else if( _tcsicmp(pstrName, _T("size")) == 0 ) {
size = _tcstol(pstrValue, &pstr, 10);
}
else if( _tcsicmp(pstrName, _T("bold")) == 0 ) {
bold = (_tcsicmp(pstrValue, _T("true")) == 0);
}
else if( _tcsicmp(pstrName, _T("underline")) == 0 ) {
underline = (_tcsicmp(pstrValue, _T("true")) == 0);
}
else if( _tcsicmp(pstrName, _T("italic")) == 0 ) {
italic = (_tcsicmp(pstrValue, _T("true")) == 0);
}
else if( _tcsicmp(pstrName, _T("default")) == 0 ) {
defaultfont = (_tcsicmp(pstrValue, _T("true")) == 0);
}
else if( _tcsicmp(pstrName, _T("shared")) == 0 ) {
shared = (_tcsicmp(pstrValue, _T("true")) == 0);
}
}
if( id >= 0 ) {
pManager->AddFont(id, pFontName, size, bold, underline, italic, shared);
if( defaultfont ) pManager->SetDefaultFont(pFontName, pManager->GetDPIObj()->Scale(size), bold, underline, italic, shared);
}
}
duilib源码中的代码片段,其中最后一行代码就是上面分析的将字体大小做了一次放大的地方:
pManager->SetDefaultFont(pFontName, pManager->GetDPIObj()->Scale(size), bold, underline, italic, shared);
应该修改为
pManager->SetDefaultFont(pFontName, size, bold, underline, italic, shared);
修改后的显示效果见下图: