I'm trying to calculate font height for the the Win32 API CreateFont() function. I'm creating a font structure (hFont) that is later used in the DrawText() function for determining the vertical height of a word wrapped string displayed in a specific font.
My problem is that I'm not getting accurate results returned from DrawText() and I believe (???) this is due to bad fontheight calculation on my part.
Here's what I have so far - watch line wrap:
Assuming pcText (to be used for DrawText output), pcFontName, pnFontSize (in points), and lnBold (font weight), and boolean llItalic, llUnderline, and llStrikeThru variables contain font specific info ...
My ultimate goals are to use DrawText() to:
a. Determine the max amount of vertical space required to display a word wrapped string in order to create an autosizing editbox
b. Use DrawText() with the DT_MODIFYSTRING parm to get back trimmed strings with elllipsis (...) when I need to display more text than will fit in a specific rectangle. I can get this to work with single line strings - but not with strings that wrap and/or have carriage returns.
Any ideas appreciated,
Malcolm
My problem is that I'm not getting accurate results returned from DrawText() and I believe (???) this is due to bad fontheight calculation on my part.
Here's what I have so far - watch line wrap:
Assuming pcText (to be used for DrawText output), pcFontName, pnFontSize (in points), and lnBold (font weight), and boolean llItalic, llUnderline, and llStrikeThru variables contain font specific info ...
Code:
* DrawText() constants
#define DT_LEFT 0
#define DT_CENTER 1
#define DT_TOP 0
#define DT_RIGHT 2
#define DT_WORDBREAK 16 && wordwrap
#define DT_EXTERNALLEADING 0x200 && includes font’s external leading in the line height
#define DT_CALCRECT 0x400 && calculate height without displaying text
#define DT_EDITCONTROL 0x2000 && use editbox height and wrapping calculations
#define DT_MODIFYSTRING 0x10000 && update text with ellipses
#define DT_NOPREFIX 0x800 && disable & expansion to _
#define DT_END_ELLIPSIS 0x8000 && ellipsis at end of text
#define DT_PATH_ELLIPSIS 0x4000 && ellipsis in middle of string (for paths)
#define DT_WORD_ELLIPSIS 0x40000 && ellipsis at end of text on word boundry
* CreateFont() constants
#define ANSI_CHARSET 0
#define OUT_DEFAULT_PRECIS 0
#define OUT_DEVICE_PRECIS 5
#define OUT_OUTLINE_PRECIS 8
#define CLIP_DEFAULT_PRECIS 0
#define CLIP_STROKE_PRECIS 2
#define DEFAULT_QUALITY 0
#define PROOF_QUALITY 2
#define DEFAULT_PITCH 0
#define FW_BOLD 700 && use to bold
* GetDeviceCaps() constants
#define LOGPIXELSY 90
* determine font height
* NOTE: - MulDiv( pnFontSize, GetDeviceCaps( hDC, LOGPIXELSY ), 72 )
local lnFontHeight
lnFontHeight = - int( pnFontSize * GetDeviceCaps( hDC, LOGPIXELSY ) / 72 )
* create a new font to use for our text calculations
local hFont
hFont = CreateFont( ;
lnFontHeight, 0, 0, 0, lnBold, llItalic, llUnderLine, llStrikeThru, ;
ANSI_CHARSET,OUT_OUTLINE_PRECIS, CLIP_STROKE_PRECIS, PROOF_QUALITY, DEFAULT_PITCH, pcFontName )
* select new font into the device context and delete the old one
= DeleteObject( SelectObject( hdc, hFont ) )
* build DrawText() style flags
lnDTflags = DT_LEFT + DT_WORDBREAK + DT_CALCRECT + DT_EDITCONTROL + ;
DT_MODIFYSTRING + DT_NOPREFIX + DT_WORD_ELLIPSIS + DT_EXTERNALLEADING
* determine size of pcText with specified pnWidth
* NOTE: Bounding rectangle defined by left, top, right, bottom coordinates vs. height, width.
* NOTE: We set bottom to a large value - if we set it too short then out height will be clipped.
local lcRect, lnHeight
lcRect = n2dw( 0 ) + n2dw( 0 ) + n2dw( pnWidth ) + n2dw( 1200 )
lnHeight = DrawText( hDC, @pcText, len( pcText ), @lcRect, lnDTflags )
* release system resources
= DeleteObject( hFont )
= ReleaseDC( hWindow, hDC )
* return height
return lnHeight
My ultimate goals are to use DrawText() to:
a. Determine the max amount of vertical space required to display a word wrapped string in order to create an autosizing editbox
b. Use DrawText() with the DT_MODIFYSTRING parm to get back trimmed strings with elllipsis (...) when I need to display more text than will fit in a specific rectangle. I can get this to work with single line strings - but not with strings that wrap and/or have carriage returns.
Any ideas appreciated,
Malcolm