|
I just noticed that you have a function to change the font in a screen. Since I had to do something like this myself recently I looked at your implementation.
There is a bug in the function resulting from Microsoft's failure to document anything right. I know because I had an identical bug in my own implementation for over a year before I found out what was wrong.
You start the function (as I did) by grabbing the TEXTMETRIC for the old and new fonts. Then when you are converting you use (tmNew.tmAveCharWidth / tmOld.tmAveCharWidth) as your normalization ratio. This is the problem. In windows Dialog units ARE calculated using the average character width HOWEVER, the REAL average character width is used, not the "AveCharWidth" in the text metric (which is actually just the width of 'x')
Believe it or not, this does make a significant difference, both functionally and cosmeticly. Here is a snippet from my code that made all the difference in fixing this:
// grab old and new text metrics
TEXTMETRIC tmOld;
TEXTMETRIC tmNew;
CDC * pDC = pWnd->GetDC();
CFont* pSavedFont = pDC->SelectObject(pWnd->GetFont());
pDC->GetTextMetrics(&tmOld);
SIZE size;
size = pDC->GetTextExtent(_T("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"),52);
// tmAveCharWidth is actually an approximation based on getting the width of "x". The system
// doesn't use these approximations at the low level when it converts between dialog units
// and pixels. To do this conversion properly we have to calculate the actual average.
tmOld.tmAveCharWidth = (size.cx/26+1)/2;
pDC->SelectObject(pFont);
pDC->GetTextMetrics(&tmNew);
size = pDC->GetTextExtent(_T("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"),52);
// tmAveCharWidth is actually an approximation based on getting the width of "x". The system
// doesn't use these approximations at the low level when it converts between dialog units
// and pixels. To do this conversion properly we have to calculate the actual average.
tmNew.tmAveCharWidth = (size.cx/26+1)/2; |
|