Jump to content

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


 Share

Recommended Posts

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?

Link to comment
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
Link to comment
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

Link to comment
Share on other sites

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
Link to comment
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

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...