If you are trying to size objects on a VFP form to match a specific font, you have to take into account the current screen DPI setting as well. Consider sizing a Rectangle object to surround a given piece of text. You know the fontname, fontsize, and the actual text string, but you don’t know the dimensions. No problem, you say, I’ll just use FONTMETRIC() and TXTWIDTH() to figure out the size of the text in pixels:

iAvgCharWidth = FONTMETRIC(6, cFontName, cFontSize, "" )
iTextWidth = TXTWIDTH( cString, cFontName, cFontSize, "" ) * iAvgCharWidth

…and now I can size my Rectangle appropriately, you say.

Not so fast. What if your Windows display is set to 120 DPI? The text will be sized differently. You have to take this into account:

*---------------------------------
* Determine the screen DPI:
*---------------------------------
#define LOGPIXELSX 88

declare integer GetDeviceCaps in WIN32API integer HDC, integer item
declare integer GetDC         in WIN32API integer hWnd
*declare integer DeleteDC      in WIN32API integer HDC
declare integer ReleaseDC     in WIN32API integer hWnd, integer HDC

local hdc, screenDPI
hdc    = GetDC(0)
THIS.screenDPI = GetDeviceCaps( m.hdc, LOGPIXELSX )
ReleaseDC( 0, m.hdc )

IF iScreenDPI <> 96
   iTextWidth = INT( (iTextWidth * iScreenDPI)/96 )
ENDIF

I was grappling with issue recently, dealing with a bug reported by someone who said that Pageframe text captions were getting truncated when they set their environment to 120DPI + “Large Fonts”.

Well, this morning I have read a post by the remarkable Charles Petzold about Device Independent Units (DIU) that goes some way (and more) to explaining why we have to do it, because I believe that Visual FoxPro uses actual pixels rather than DIU. His post his worth a read.