用CFontHolder.Select要小心: 如果你只用第一个参数,那也罢了,如果要用后两个参数,改变当前字体的显示比例,就要小心了。
首先:
用 IFont-Set_Size()来设置字体时,系统会进行舍入处理,
比如:设置10,再Get_Size就变成9.75。
这是正常的,至少你再设置一次9.75,它不会再变化。
问题:
当用Select改变映射模式,舍入规则可能就不一样了,因为度量单元的标准不同了。
比如:先设置10,然后Select,改变了字体的显示比例,你会发现,取出来的不是 9.75,而是其它值,具体和你的比例有关。
如果在取Size前,用SelectObject把旧的Font放回去呢?仍然不行,CFontHolder并没管这一套。
具体情况可以试,一句话,多次Select,显示比例变来变去,而多次舍入(也可以称之为最近值逼近)之后,你的Size变化就大了,可能会越变越小。
解决很简单,下面给一种方案:
假定你需要选入字体,进行字高的计算(采用GetTextMetric)
封装一下CFontHolder的Select方法:
比如在你的字体处理类如:CM_Font提供一种安全方式(CM_Font中聚合有一个CFontHolder指针)。
void CM_Font::SafeGetMetric(CDC * pDC, long cyLogical, long cyHimetric,TEXTMETRIC &tm)
{
if ( m_pFH == NULL || pDC == NULL)
return;
CY cyOld;
m_pFH->m_pFont->get_Size(&cyOld);
CFont* pOldFont = m_pFH->Select(pDC,cyLogical,cyHimetric);
pDC->
GetTextMetrics(tm); DefaultSelect(pDC);
pDC->SelectObject(pOldFont);
m_pFH->m_pFont->put_Size(cyOld);
}
void CM_Font::DefaultSelect(CDC * pDC)
{
if ( m_pFH == NULL || pDC == NULL)
return;
m_pFH->Select(pDC, (long)(pDC->GetDeviceCaps(LOGPIXELSY)), HIMETRIC_PER_INCH);
}
1:调用SafeGetMetric来安全获取Metric值,而不改变输入值。
2:至于DefaultSelect,那要看你的当前环境,哪个是当前默认的映射模式。
查看本文来源