Sign in to follow this  
Followers 0
AndyS01

Find how many pixels a control's text string will use

5 posts in this topic

I'm trying to find out how many pixels a text string will take so that when I create an edit control to hold it, I can re-size the control to be exactly the right width and height. I need both the height and the width.

Looking on line, I see 2 flavors of the GetTextMetrics() API:

BOOL GetTextMetrics(
    HDC hdc,            // handle to DC
    LPTEXTMETRIC lptm   // text metrics
);
and
XText GetTextMetrics(string inText, double inWidth, double inHeight, DrawOptions inOptions);

Neither of these look like what I want.

I found an on-line example that almost does what I want, but it creates a font instead of using whichever font is being used for a specified control:

Func getStringHpixels($id, $sString = "Hello world ABCDEFGHIJKLMNOPQRSTUVWXYZ")
    Local $hGUI, $hGraphic, $hBrush, $hFormat, $hFamily, $hFont, $tLayout, $aInfo, $new

    $hGUI = GUICtrlGetHandle($id)

    _GDIPlus_Startup()
    $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI)
    $hBrush = _GDIPlus_BrushCreateSolid(0xFF00007F)
    $hFormat = _GDIPlus_StringFormatCreate()
    $hFamily = _GDIPlus_FontFamilyCreate("Arial")
    $hFont = _GDIPlus_FontCreate($hFamily, 12, 2)
    $tLayout = _GDIPlus_RectFCreate()
    $aInfo = _GDIPlus_GraphicsMeasureString($hGraphic, $sString, $hFont, $tLayout, $hFormat)

    $new = $aInfo[0]
    ConsoleWrite("+++: width = " & DllStructGetData($new, "Width") & @CRLF)
    ConsoleWrite("+++: Height = " & DllStructGetData($new, "Height") & @CRLF)
    
    ; Clean up resources
    _GDIPlus_FontDispose($hFont)
    _GDIPlus_FontFamilyDispose($hFamily)
    _GDIPlus_StringFormatDispose($hFormat)
    _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_Shutdown()

    exit (1)
EndFunc   ;==>getStringHpixels

If I could get the font being used by the control, I could use this code, but I couldn't find any API functions to do this.

Is there an AutoIt API that does what I want?

Share this post


Link to post
Share on other sites



I found this on the forums a while ago, sorry I can't remember who wrote it.

Func _GetTextLabelWidth($s_WinText, $s_TextFont, $i_FontSize, $i_FontWeight = -1)
    Local Const $DEFAULT_CHARSET = 0 ; ANSI character set
    Local Const $OUT_CHARACTER_PRECIS = 2
    Local Const $CLIP_DEFAULT_PRECIS = 0
    Local Const $PROOF_QUALITY = 2
    Local Const $FIXED_PITCH = 1
    Local Const $RGN_XOR = 3
    Local Const $LOGPIXELSY = 90


    $h_WinTitle = "Get Label Width"
    If $i_FontWeight = "" Or $i_FontWeight = -1 Then $i_FontWeight = 600 ; default Font weight
    Local $h_GUI = GUICreate($h_WinTitle, 10, 10, -100, -100, $WS_POPUPWINDOW, $WS_EX_TOOLWINDOW)
    Local $hDC = DllCall("user32.dll", "int", "GetDC", "hwnd", $h_GUI)

    Local $intDeviceCap = DllCall("gdi32.dll", "long", "GetDeviceCaps", "int", $hDC[0], "long", $LOGPIXELSY)
    $intDeviceCap = $intDeviceCap[0]

    Local $intFontHeight = DllCall("kernel32.dll", "long", "MulDiv", "long", $i_FontSize, "long", $intDeviceCap, "long", 72)
    $intFontHeight = -$intFontHeight[0]

    Local $hMyFont = DllCall("gdi32.dll", "hwnd", "CreateFont", "int", $intFontHeight, _
            "int", 0, "int", 0, "int", 0, "int", $i_FontWeight, "int", 0, _
            "int", 0, "int", 0, "int", $DEFAULT_CHARSET, _
            "int", $OUT_CHARACTER_PRECIS, "int", $CLIP_DEFAULT_PRECIS, _
            "int", $PROOF_QUALITY, "int", $FIXED_PITCH, "str", $s_TextFont)
    DllCall("gdi32.dll", "hwnd", "SelectObject", "int", $hDC[0], "hwnd", $hMyFont[0])

    Local $res = DllStructCreate("int;int")

    Local $ret = DllCall("gdi32.dll", "int", "GetTextExtentPoint32", "int", $hDC[0], "str", $s_WinText, "long", StringLen($s_WinText), "ptr", DllStructGetPtr($res))

    Local $intLabelWidth = DllStructGetData($res,1)

    GUIDelete($h_GUI)
    Return $intLabelWidth
EndFunc

Share this post


Link to post
Share on other sites

You could try using UDF, it's designed for lables, but could probably be used for this purpose as well.


If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

Trancexx had a good example as well..

#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6

#include <WinAPI.au3>

; Make GUI
GUICreate("StringSize", 600, 400)
GUISetBkColor(0) ; black magic GUI

; First example:
Global $sLabelText = "Pa Da Pam Pam..."
Global $aLabelTextSize = _StringSize($sLabelText, 14)
GUICtrlCreateLabel($sLabelText, 10, 20, $aLabelTextSize[0], $aLabelTextSize[1]) ; create label in calculated size
GUICtrlSetFont(-1, 14) ; set wanted font
GUICtrlSetBkColor(-1, 0xFFFFFF) ; make the background white

; Print size
ConsoleWrite($aLabelTextSize[0] & " x " & $aLabelTextSize[1] & @CRLF)

; Secand example:
$sLabelText = "abcdehmma"
$aLabelTextSize = _StringSize($sLabelText, 60, 800)
GUICtrlCreateLabel($sLabelText, 10, 80, $aLabelTextSize[0], $aLabelTextSize[1]) ; create label in calculated size
GUICtrlSetFont(-1, 60, 800) ; set wanted font
GUICtrlSetBkColor(-1, 0xFFFFFF) ; make the background white

; Print size
ConsoleWrite($aLabelTextSize[0] & " x " & $aLabelTextSize[1] & @CRLF)

; Third example:
$sLabelText = "First line of the text" & @LF & "Second line of the text" & @CRLF & "Third line of the text" & @CRLF & "Fourth line of the text. See ya!"
$aLabelTextSize = _StringSize($sLabelText, 17, 700, 2, "Tahoma", 4)
GUICtrlCreateLabel($sLabelText, 10, 220, $aLabelTextSize[0], $aLabelTextSize[1]) ; create label in calculated size
GUICtrlSetFont(-1, 17, 700, 2, "Tahoma", 4) ; set wanted font
GUICtrlSetBkColor(-1, 0xFFFFFF) ; make the background white

; Print size
ConsoleWrite($aLabelTextSize[0] & " x " & $aLabelTextSize[1] & @CRLF)

; Show GUI
GUISetState()
; Wait for the exit
While GUIGetMsg() <> -3
WEnd


; FUNCTION
Func _StringSize($sText, $iSize = 8.5, $iWeight = 400, $iAttrib = 0, $sName = "", $iQuality = 2)
    Local Const $LOGPIXELSY = 90
    Local $fItalic = BitAND($iAttrib, 2)
    Local $hDC = _WinAPI_GetDC(0)
    Local $hFont = _WinAPI_CreateFont(-_WinAPI_GetDeviceCaps($hDC, $LOGPIXELSY) * $iSize / 72, 0, 0, 0, $iWeight, $fItalic, BitAND($iAttrib, 4), BitAND($iAttrib, 8), 0, 0, 0, $iQuality, 0, $sName)
    Local $hOldFont = _WinAPI_SelectObject($hDC, $hFont)
    Local $tSIZE
    If $fItalic Then $sText &= " "
    Local $iWidth, $iHeight
    Local $aArrayOfStrings = StringSplit($sText, @LF, 2)
    For $sString In $aArrayOfStrings
        $tSIZE = _WinAPI_GetTextExtentPoint32($hDC, $sString)
        If DllStructGetData($tSIZE, "X") > $iWidth Then $iWidth = DllStructGetData($tSIZE, "X")
        $iHeight += DllStructGetData($tSIZE, "Y")
    Next
    _WinAPI_SelectObject($hDC, $hOldFont)
    _WinAPI_DeleteObject($hFont)
    _WinAPI_ReleaseDC(0, $hDC)
    Local $aOut[2] = [$iWidth, $iHeight]
    Return $aOut
EndFunc   ;==>_StringSize
Edited by picea892

Share this post


Link to post
Share on other sites

Actually, I needed to get the size of the string (in pixels), based on the control's font. So I used a function called _GUICtrlGetFont() (from _GUICtrlGetFont) to get the font information, then called _StringSize(), like this:

$aFontInfo = _GUICtrlGetFont($hGUI)
$aStrInfo = _StringSize($sString, $aFontInfo[0], $aFontInfo[1], $aFontInfo[2], $aFontInfo[3])

Then I use that when creating my control, like this:

$id = GUICtrlCreateEdit("", $x, $y, $aStrInfo[2], $aStrInfo[3], $flags)
GUICtrlSetData($id, $aStrInfo[0])

Thanks for the help

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0