here's a quick utility which I just bashed up for those who (like myself) like to place and size gadgets very precisely depending on the font metrics etc.
The 'GetTextDimensions()' function below is more precise than PB's TextWidth() and TextHeight() functions since it examines any 'overhang' which is added by many fonts when dealing with italic and/or bold styles. Calculating this depends on the nature of the font (raster or true/open type). PB's functions do not take this into account.
The function will either accept a HDC (and uses the font currently selected into the HDC) or an hWnd (in which case it extracts the appropriate font) and returns the relevant dimensions in a SIZE type structure.
Code: Select all
Procedure.l GetTextDimensions(hWndHDC, text$, *sz.SIZE, blnIsHDC = 1)
Protected result, hdc, tm.TEXTMETRIC, abc.ABC, overhang, oldFont, char
If text$ And *sz
If blnIsHDC = 0
hdc = GetDC_(hWndHDC)
If hdc = 0
ProcedureReturn #False
EndIf
oldFont = SelectObject_(hdc, SendMessage_(hWndHDC, #WM_GETFONT, 0, 0))
Else
hdc = hWndHDC
EndIf
;First obtain the 'raw' dimensions. Equivalent to PB's TextWidth() and TextHeight() functions.
GetTextExtentPoint32_(hdc, @text$, Len(text$), *sz)
;Now an adjustment for any 'overhang'. The method of obtaining this depends on the type of font; raster or true/open type.
;For now a quick hack for determining this.
GetTextMetrics_(hdc, tm)
If tm\tmOverhang ;Raster font.
*sz\cx + tm\tmOverhang
Else
char = Asc(Right(text$,1))
GetCharABCWidths_(hdc, char, char, abc)
overhang = abc\abcC
If overHang < 0
*sz\cx - overHang
EndIf
EndIf
;Tidy up.
If blnIsHDC = 0
SelectObject_(hdc, oldFont)
ReleaseDC_(hWndHDC, hdc)
EndIf
EndIf
ProcedureReturn #True
EndProcedure
Code: Select all
;Test.
;=====
selectedFont.s = "Arial"
selectedFontSize = 12
text$ = "Heyho tiddly dee tiddly doo!"
If OpenWindow(0,10,10,600,600,"Test", #PB_Window_ScreenCentered|#PB_Window_SystemMenu)
hWnd = TextGadget(1, 0, 0, 0, 0, text$, #WS_BORDER)
LoadFont(1, selectedFont, selectedFontSize, SelectedFontStyle)
SetGadgetFont(1, FontID(1))
ButtonGadget(2, 500,560, 80, 20, "Choose font")
GetTextDimensions(hWnd, text$, sz.SIZE, 0) ;0 informs the function that we are passing a hWnd as opposed to a HDC.
;Add on border widths etc.
sz\cx + 2*GetSystemMetrics_(#SM_CXBORDER)
sz\cy + 2*GetSystemMetrics_(#SM_CYBORDER)
ResizeGadget(1, (WindowWidth(0)-sz\cx)>>1, (WindowHeight(0)-sz\cy)>>1, sz\cx, sz\cy)
Repeat
Event=WaitWindowEvent()
Select Event
Case #PB_Event_Gadget
Select EventGadget()
Case 2
If FontRequester(selectedFont, selectedFontSize, 0)
FreeFont(1)
selectedFont = SelectedFontName() : selectedFontSize = SelectedFontSize()
LoadFont(1, selectedFont, selectedFontSize, SelectedFontStyle())
SetGadgetFont(1, FontID(1))
GetTextDimensions(hWnd, text$, sz.SIZE, 0) ;0 informs the function that we are passing a hWnd as opposed to a HDC.
;Add on border widths etc.
sz\cx + 2*GetSystemMetrics_(#SM_CXBORDER)
sz\cy + 2*GetSystemMetrics_(#SM_CYBORDER)
ResizeGadget(1, (WindowWidth(0)-sz\cx)>>1, (WindowHeight(0)-sz\cy)>>1, sz\cx, sz\cy)
EndIf
EndSelect
EndSelect
Until Event=#PB_Event_CloseWindow
EndIf