Here's a function (from the PowerBuilder Foundation Class) that will the width & height (in pixels) of a string when rendered by Windows.
You need a Windows "size" structure. Here's exported PB source code showing an example:
type os_size from structure
long l_cx
long l_cy
end type
Here are the external function declarations for four WinAPI functions the of_GetTextSize function will call:
Function Boolean GetTextExtentPoint32W ( &
ULong hdcr, String lpString, Long nCount, &
ref os_size size ) Library "GDI32.DLL"
Function ULong SelectObject ( &
ULong hdc, ULong hWnd ) Library "GDI32.DLL"
Function ULong GetDC ( &
ULong hWnd ) Library "USER32.DLL"
Function Integer ReleaseDC ( &
ULong hWnd, ULong hDC ) Library "USER32.DLL"
Here's the of_GetTextSize function:
//////////////////////////////////////////////////////////////////////////////
// Public Function: of_GetTextSize
//
// Arguments:
// Window aw_obj (by reference) Window where temporary text will be created
// String as_Text The text to be sized.
// String as_FontFace The font used.
// Integer ai_FontSize The point size of the font.
// Boolean ab_Bold True - Bold, False - Normal.
// Boolean ab_Italic True - Yes, False - No.
// Boolean ab_Underline True - Yes, False - No.
// Integer ai_Height (by reference) The height of the object in pixels
// Integer ai_Width (by reference) The width of the object in pixels
//
// Returns: Integer 1 if successful, -1 if an error occurrs
//
// Description:
// Calculates the size of a text object in pixels
//////////////////////////////////////////////////////////////////////////////
// Rev. History Version
// 5.0 Initial version
// 5.0.03 Changed Uint variables to Ulong for NT4.0 compatibility
// 8.0 Not deleting statictext object under certain conditions.
//////////////////////////////////////////////////////////////////////////////
/*
* Open Source PowerBuilder Foundation Class Libraries
*
* Copyright (c) 2004-2017, All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted in accordance with the MIT License
*
* https://opensource.org/licenses/MIT
*
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals and was originally based on software copyright (c)
* 1996-2004 Sybase, Inc. http://www.sybase.com. For more
* information on the Open Source PowerBuilder Foundation Class
* Libraries see https://github.com/OpenSourcePFCLibraries
*/
//////////////////////////////////////////////////////////////////////////////
Integer li_Size, li_Len, li_Return, &
li_WM_GETFONT = 49 // hex 0x0031
ULong lul_Hdc, lul_Handle, lul_hFont
StaticText lst_Temp
os_size lstr_Size
// Datawindow syntax specifies font point size is negative
li_Size = -1 * ai_FontSize
if IsNull(aw_obj) Or Not IsValid (aw_obj) then
return -1
end if
// Create a dummy StaticText Object on the window
// containing text with the desired characteristics
li_Return = aw_obj.OpenUserObject(lst_Temp)
If li_Return = 1 Then
lst_Temp.FaceName = as_FontFace
lst_Temp.TextSize = li_Size
If ab_Bold Then
lst_Temp.Weight = 700
Else
lst_Temp.Weight = 400
End If
lst_Temp.Italic = ab_Italic
lst_Temp.Underline = ab_Underline
li_Len = Len(as_Text)
// Get the handle of the StaticText Object and create a Device Context
lul_Handle = Handle(lst_Temp)
lul_Hdc = GetDC(lul_Handle)
// Get the font in use on the Static Text
lul_hFont = Send(lul_Handle, li_WM_GETFONT, 0, 0)
// Select it into the device context
SelectObject(lul_Hdc, lul_hFont)
// Get the size of the text.
If Not GetTextExtentpoint32W(lul_Hdc, as_Text, li_Len, lstr_Size ) Then
aw_obj.CloseUserObject(lst_Temp)
Return -1
End If
ai_Height = lstr_Size.l_cy
ai_Width = lstr_Size.l_cx
ReleaseDC(lul_Handle, lul_Hdc)
li_Return = aw_obj.CloseUserObject(lst_Temp)
End if
Return li_Return
That should get you started, if you want.
A very interesting problem with a lot of factors to take into account. Perhaps you or someone else will find it useful.
Regards, John