Jump to content

Automatically shrink a label to its minimum size


boomingranny
 Share

Recommended Posts

I was working on a project where I have a window without a title, so to move the window I use the window background itself,
I have some labels in the window that are right aligned, and they kept getting in the way of the window move..
so I needed a way to shrink the labels to their minimum size, but keep their right alignment.

I did have a look through the forum but didn't find anything that would fit my need exactly.

To make it as easy as possible I have made the function so it can be called the same way you would set a background color or set a font, you can just call it after label creation:
GuiCtrlLabelAutoSize() 
(see the example below)

 

#include <FontConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <WinAPIDlg.au3>
Local $x = 5, $y = 5

;create an Example GUI
$GUI = GUICreate("Label Example",400,300)
GUICtrlCreateLabel("Test label",$x,$y,390,25)
GUICtrlSetFont(-1, 9, $FW_NORMAL, $GUI_FONTUNDER, "Aerial")
GUICtrlSetBkColor(-1,0xAAAAFF)
GUICtrlLabelAutoSize()

$y += 30
GUICtrlCreateLabel("Label 2",$x,$y,390,25)
GUICtrlSetFont(-1, 10,  $FW_BOLD , $GUI_FONTITALIC , "Aerial")
GUICtrlSetBkColor(-1,0xAAAAFF)
GUICtrlLabelAutoSize(-1,"right")

$y += 30
GUICtrlCreateLabel("Label right",$x,$y,390,25)
GUICtrlSetFont(-1, 10, $FW_NORMAL, 0, "Aerial")
GUICtrlSetBkColor(-1,0xAAAAFF)
GUICtrlLabelAutoSize(-1,"right")

$y += 30
GUICtrlCreateLabel("Label also right",$x,$y,390,25)
GUICtrlSetFont(-1, 10, $FW_NORMAL, 0, "Aerial")
GUICtrlSetBkColor(-1,0xAAAAFF)
GUICtrlLabelAutoSize(-1,"right")

$y += 30
GUICtrlCreateLabel("label centred",$x,$y,390,25)
GUICtrlSetFont(-1, 12, $FW_NORMAL, 0, "Times New Roman")
GUICtrlSetBkColor(-1,0xAAAAFF)
GUICtrlLabelAutoSize(-1,"centre")

GUISetState()
Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE

; #FUNCTION# ====================================================================================================================
; Name ..........: GUICtrlLabelAutoSize
; Description ...: Shrinks a label to its minimum size, and aligns (left, right, or centre) within its area
; Author(s)......: Daniel Barnes, with help from the AutoIt help file _WinAPI_GetTextExtentPoint32 example!
; Modified.......: 2018/11/20
; ===============================================================================================================================
Func GUICtrlLabelAutoSize($idLbl=-1,$align="left")
    $sText = GUICtrlRead($idLbl)
    $hwnd = GUICtrlGetHandle($idLbl) ;get the handle of the label control
    If $idLbl = -1 Then $idLbl = _WinAPI_GetDlgCtrlID($hwnd) ;get the ID, if we used -1 (last created control)
    If Not IsHWnd($hwnd) Then ;basic error handling
        SetError(1)
        return
    endif
    Local $hDC = _WinAPI_GetDC($hWnd) ; Get the device context handle of the current window.
    Local $hFont = _SendMessage($hWnd, $WM_GETFONT) ; Retrieve the font with which the control is currently drawing its text.
    Local $hSelectObject = _WinAPI_SelectObject($hDC, $hFont) ; Select the object of the context device.
    Local $tSIZE = _WinAPI_GetTextExtentPoint32($hDC, $sText) ; Retrieve the height & width of a string.
    _WinAPI_SelectObject($hDC, $hSelectObject)
    _WinAPI_ReleaseDC($hWnd, $hDC) ; Release the device context.
    Local $aReturn[2] = [DllStructGetData($tSIZE, 1), DllStructGetData($tSIZE, 2)] ; Set an array with the width & height of the string.
    $hParent = _WinAPI_GetParent ( $hwnd) ;Get the handle of the parent window
    $aPos = ControlGetPos($hParent,"",$idLbl) ;get the position of the label
    Switch $align
        Case "left"
            GUICtrlSetPos($idLbl,$aPos[0],$aPos[1],$aReturn[0],$aReturn[1]) ;resize the label
        Case "right"
            $left = $aPos[0]+$aPos[2]-$aReturn[0]
            GUICtrlSetPos($idLbl,$left,$aPos[1],$aReturn[0],$aReturn[1]) ;resize the label
        Case "centre"
            $left = $aPos[0]+(($aPos[2]-$aReturn[0])/2)
            GUICtrlSetPos($idLbl,$left,$aPos[1],$aReturn[0],$aReturn[1]) ;resize the label
    EndSwitch
EndFunc

 

2018-11-20_0-59-06.png

Edited by boomingranny
added screenshot
Link to comment
Share on other sites

13 hours ago, boomingranny said:

To make it as easy as possible

Loved your code. Tweaked too  ;) 

#include <FontConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <WinAPIDlg.au3>

#include <StaticConstants.au3>
ConsoleWrite('$SS_LEFT = ' & $SS_LEFT & @CRLF)
ConsoleWrite('$SS_CENTER = ' & $SS_CENTER & @CRLF)
ConsoleWrite('$SS_RIGHT = ' & $SS_RIGHT & @CRLF)


Local $x = 5, $y = 5

;create an Example GUI
$GUI = GUICreate("Label Example", 400, 300)
GUICtrlCreateLabel("Test label", $x, $y, 390, 25)
GUICtrlSetFont(-1, 9, $FW_NORMAL, $GUI_FONTUNDER, "Aerial")
GUICtrlSetBkColor(-1, 0xAAAAFF)
GUICtrlLabelAutoSize()

$y += 30
GUICtrlCreateLabel("Label 2", $x, $y, 390, 25, $SS_RIGHT)
GUICtrlSetFont(-1, 10, $FW_BOLD, $GUI_FONTITALIC, "Aerial")
GUICtrlSetBkColor(-1, 0xAAAAFF)
GUICtrlLabelAutoSize(-1)

$y += 30
GUICtrlCreateLabel("Label right", $x, $y, 390, 25, $SS_LEFT) ; but will be owerride by declaration
GUICtrlSetFont(-1, 10, $FW_NORMAL, 0, "Aerial")
GUICtrlSetBkColor(-1, 0xAAAAFF)
GUICtrlLabelAutoSize(-1, "right")

$y += 30
GUICtrlCreateLabel("Label also right", $x, $y, 390, 25, $SS_RIGHT)
GUICtrlSetFont(-1, 10, $FW_NORMAL, 0, "Aerial")
GUICtrlSetBkColor(-1, 0xAAAAFF)
GUICtrlLabelAutoSize(-1)

$y += 30
GUICtrlCreateLabel("label centred", $x, $y, 390, 25, $SS_CENTER)
GUICtrlSetFont(-1, 12, $FW_NORMAL, 0, "Times New Roman")
GUICtrlSetBkColor(-1, 0xAAAAFF)
GUICtrlLabelAutoSize(-1)

GUISetState()
Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE

; #FUNCTION# ====================================================================================================================
; Name ..........: GUICtrlLabelAutoSize
; Description ...: Shrinks a label to its minimum size, and aligns (left, right, or centre) within its area
; Author(s)......: Daniel Barnes, with help from the AutoIt help file _WinAPI_GetTextExtentPoint32 example!
; Modified.......: 2018/11/20
; ===============================================================================================================================
Func GUICtrlLabelAutoSize($idLbl = -1, $align = Default)
    $sText = GUICtrlRead($idLbl)
    $hwnd = GUICtrlGetHandle($idLbl) ;get the handle of the label control
    If $idLbl = -1 Then $idLbl = _WinAPI_GetDlgCtrlID($hwnd) ;get the ID, if we used -1 (last created control)
    If Not IsHWnd($hwnd) Then ;basic error handling
        SetError(1)
        Return
    EndIf

    #Region addendum
    If $align = Default Then
        If BitAND(_WinAPI_GetWindowLong($hwnd, $GWL_STYLE), $SS_RIGHT) = $SS_RIGHT Then
            $align = "RIGHT"
        ElseIf BitAND(_WinAPI_GetWindowLong($hwnd, $GWL_STYLE), $SS_CENTER) = $SS_CENTER Then
            $align = "centre" ; "CENTER"
        ElseIf BitAND(_WinAPI_GetWindowLong($hwnd, $GWL_STYLE), $SS_LEFT) = $SS_LEFT Then
            $align = "LEFT"
        EndIf
    EndIf
    #EndRegion addendum

    Local $hDC = _WinAPI_GetDC($hwnd) ; Get the device context handle of the current window.
    Local $hFont = _SendMessage($hwnd, $WM_GETFONT) ; Retrieve the font with which the control is currently drawing its text.
    Local $hSelectObject = _WinAPI_SelectObject($hDC, $hFont) ; Select the object of the context device.
    Local $tSIZE = _WinAPI_GetTextExtentPoint32($hDC, $sText) ; Retrieve the height & width of a string.
    _WinAPI_SelectObject($hDC, $hSelectObject)
    _WinAPI_ReleaseDC($hwnd, $hDC) ; Release the device context.
    Local $aReturn[2] = [DllStructGetData($tSIZE, 1), DllStructGetData($tSIZE, 2)] ; Set an array with the width & height of the string.
    $hParent = _WinAPI_GetParent($hwnd) ;Get the handle of the parent window
    $aPos = ControlGetPos($hParent, "", $idLbl) ;get the position of the label
    Switch $align
        Case "left"
            GUICtrlSetPos($idLbl, $aPos[0], $aPos[1], $aReturn[0], $aReturn[1]) ;resize the label
        Case "right"
            $left = $aPos[0] + $aPos[2] - $aReturn[0]
            GUICtrlSetPos($idLbl, $left, $aPos[1], $aReturn[0], $aReturn[1]) ;resize the label
        Case "centre"
            $left = $aPos[0] + (($aPos[2] - $aReturn[0]) / 2)
            GUICtrlSetPos($idLbl, $left, $aPos[1], $aReturn[0], $aReturn[1]) ;resize the label
    EndSwitch
EndFunc   ;==>GUICtrlLabelAutoSize

Thanks for sharing @boomingranny.

PS: "centre" is proper, etymologically speaking, but in the computer world, is better to use "center".

Edited by argumentum
etymology

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

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...