Jump to content

Simple way to center text vertically, horizontally, or both?


Recommended Posts

I'm trying to figure out if there is some simple way to display text in a GUI such that the text is centered vertically, horizontally, or both. I've tried using different GUI control styles, but nothing seems to work. I realize that I can probably achieve this effect by changing the "left" and "top" parameters, but I wonder if there is a better (or, at least different) way to accomplish this goal. Here is my example code:

#include <ButtonConstants.au3>
#include <StaticConstants.au3>
Const $iGUIWidth = 800
Const $iGUIHeight = 200
Local $hLabelMessage
Local $hGui

$hGui = GUICreate("Testing", $iGUIWidth, $iGUIHeight, -1, -1, -1, -1)
GUISetFont(20)
GUISetState()
$hLabelMessage = GUICtrlCreateLabel("Vertically centered", -1, -1, -1, -1, BitOR($SS_CENTER, $BS_CENTER))
Sleep(900)
GUICtrlDelete($hLabelMessage)
$hLabelMessage = GUICtrlCreateLabel("Horizontally centered", -1, -1, -1, -1, BitOR($SS_CENTER, $BS_CENTER))
Sleep(900)
GUICtrlDelete($hLabelMessage)
$hLabelMessage = GUICtrlCreateLabel("Both vertically and horizontally centered", -1, -1, -1, -1, BitOR($SS_CENTER, $BS_CENTER))
Sleep(900)

Any help with this would be most appreciated. Thank you.

Link to comment
Share on other sites

  • Moderators

AlexChernavsky,

Like this: ;)

#include <StaticConstants.au3>

Const $iGUIWidth = 800
Const $iGUIHeight = 200

$hGui = GUICreate("Testing", 800, 200)
GUISetFont(20)
GUISetState()
$hLabelMessage = GUICtrlCreateLabel("Vertically centered", 0, 0, 800, 200, $SS_CENTERIMAGE)
Sleep(900)
GUICtrlDelete($hLabelMessage)
$hLabelMessage = GUICtrlCreateLabel("Horizontally centered", 0, 0, 800, 200, $SS_CENTER)
Sleep(900)
GUICtrlDelete($hLabelMessage)
$hLabelMessage = GUICtrlCreateLabel("Both vertically and horizontally centered", 0, 0, 800, 200, BitOR($SS_CENTER, $SS_CENTERIMAGE))
Sleep(900)

All clear? :)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

  • Moderators

AlexChernavsky,

Never be afraid to ask if you run into problems - that is why we are here. ;)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

PS Just a quick follow-up, Suppose I changed the third GuiCntrlCreateLabel to look like this:

$hLabelMessage = GUICtrlCreateLabel("Both vertically" & @CRLF & "and horizontally centered", 0, 0, $iGUIWidth, $iGUIHeight, BitOR($SS_CENTER, $SS_CENTERIMAGE))

Now it doesn't seem to work. The carriage return and line feed seem to be ignored. What can be done here?

Thanks again.

Link to comment
Share on other sites

  • Moderators

AlexChernavsky,

Then you need my StringSize UDF (look in my sig for the link) and a bit of maths: ;)

#include <StaticConstants.au3>
#include "StringSize.au3"

Const $iGUIWidth = 800
Const $iGUIHeight = 200

$hGui = GUICreate("Testing", 800, 200)
GUISetFont(20)
GUISetState()
$hLabelMessage = GUICtrlCreateLabel("Vertically centered", 0, 0, 800, 200, $SS_CENTERIMAGE)
Sleep(900)
GUICtrlDelete($hLabelMessage)
$hLabelMessage = GUICtrlCreateLabel("Horizontally centered", 0, 0, 800, 200, $SS_CENTER)
Sleep(900)
GUICtrlDelete($hLabelMessage)

; Get the size of label needed to hold the text
$aRet = _StringSize("Both vertically" & @CRLF & "and horizontally centered", 20)
; Work out where it needs to be on the GUI
$iX = ($iGUIWidth - $aRet[2]) / 2
$iY = ($iGUIHeight - $aRet[3]) / 2
; And create it
$hLabelMessage = GUICtrlCreateLabel("Both vertically" & @CRLF & "and horizontally centered", $iX, $iY, $aRet[2], $aRet[3], $SS_CENTER)
Sleep(900)

Looks close enough. :)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

  • Moderators

AlexChernavsky,

My pleasure. :)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Melba23, I have another follow-up question, if you don't mind. I tried to implement your "_StringSize" technique in the program that I am writing, but I ran into a problem. Here is some sample code:

Opt("MustDeclareVars", 1)
#include <ButtonConstants.au3>
#include <StaticConstants.au3>
#include "StringSize.au3"
#include <array.au3>

Const $iGUIWidth = 300
Const $iGUIHeight = 160
Local $hLabelMessage
Local $hGui
Local $sTempGUIMessage
Local $aStringSizeArray
Local $iXPosition
Local $iYPosition

$hGui = GUICreate("Reaction Time Test", $iGUIWidth, $iGUIHeight, -1, -1, -1, -1) ; Display the GUI that will contain the problem sets and the feedback for the test-taker
GUISetFont(20)
GUISetState()
$sTempGUIMessage = " Correct!" & @CRLF & "520" & " ms"
$aStringSizeArray = _StringSize($sTempGUIMessage, 20)
; Work out where the string needs to be positioned in the GUI
$iXPosition = ($iGUIWidth - $aStringSizeArray[2]) / 2
$iYPosition = ($iGUIHeight - $aStringSizeArray[3]) / 2
$hLabelMessage = GUICtrlCreateLabel($sTempGUIMessage, $iXPosition, $iYPosition, $aStringSizeArray[2], $aStringSizeArray[3], $SS_CENTER)
Sleep(5000) ; Display the feedback in the GUI for a little less than a second
GUICtrlDelete($hLabelMessage)

Seems like it should work, right? But here is what the resulting GUI looks like:

http://chernavsky.dreamhosters.com/temp/autoit_gui.jpg

What am I doing wrong?

Thanks again for your help.

Link to comment
Share on other sites

  • Moderators

AlexChernavsky,

What am I doing wrong?

Nothing. Windows is correctly calculating the length of the text and then refusing to fit it into a label of the exactly the same size. :wacko:

I am looking into it and will respond as soon as I can - I believe I can see a solution but I need to test it thoroughly first. :)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

  • Moderators

AlexChernavsky,

The solution I thought I could see was in fact not valid. :(

If you are interested in what I have been doing to investigate the problem then read the spoiler below - if not then here is a method that will work for you:

#include <StaticConstants.au3>

Const $iGUIWidth = 300
Const $iGUIHeight = 160

$sTempGUIMessage = " Correct!" & @CRLF & "520" & " ms"

$hGui = GUICreate("Testing", $iGUIWidth, $iGUIHeight)
GUISetFont(20)
GUISetState()

; Create the label asking Windows to size it
$cLabel = GUICtrlCreateLabel($sTempGUIMessage, -1, -1, Default, Default, $SS_CENTER)
; And get its size
$aPos = ControlGetPos($hGUI, "", $cLabel)
; Calculate the position
$iX = ($iGUIWidth - $aPos[2]) / 2
$iY = ($iGUIHeight - $aPos[3]) / 2
; And move the label
ControlMove($hGUI, "", $cLabel, $iX, $iY)
GUICtrlSetBkColor(-1, 0xCCFFCC)
Sleep(1000)

So you can continue your script. :)

M23

The UDF uses the GetTextExtentPoint32W function to measure the text in pixels. It seems that in some very specific cases the returned value is actually less than the minimum value required for a label to accept the text. Windows actually adds a small margin to the right and bottom of a label to account for sloping italic fonts or letter with a drop tail (like "y") - my UDF does the same thing but in this case the margin was 1 pixel too small! :(

I am trying to find what Windows uses to determine the border size - I fear it is within the font file and accessing it would greatly add to the complexity of the UDF. So I will probably just increase the margin a tadge - after all this is the first complaint I have had. It seems you managed to find one of these specific cases! :D

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Melba23, thanks for the solution. I had already come up with a work-around, but I'm not sure if it will scale properly if the font-size or GUI size (or both) change. I use 23 instead of 20 for the second parameter to _StringSize. I discovered this "solution" just by trial-and-error.

Is there a way to modify the _StringSize function itself by adding 1 to the size, in pixels? I looked at your code, but I couldn't quite figure out how to do it.

Thanks.

Link to comment
Share on other sites

  • Moderators

AlexChernavsky,

As I said above, it was the particular combination of those characters in that font size that caused the problem - changing the font size is almost certain to prevent the problem. What I have been looking for is an explanation of exactly why these combinations exist and how to recognise them. :wacko:

You can, of course, very easily make a SWAG* adjustment to the UDF return - just change this section: ;)

# lines 219-222
Else ; No wrapping required
    ; Create return array (add drop margin to height)
    Local $avSize_Info[4] = [$sText, $iLine_Height, $iLine_Width, ($asLines[0] * $iLine_Height) + 4]
EndIf

To this:

Else ; No wrapping required
    ; Create return array - add margins to width and height
    Local $avSize_Info[4] = [$sText, $iLine_Height, $iLine_Width + 12, ($asLines[0] * $iLine_Height) + 4]
EndIf

But this is a random "magic value" fix - I am trying to find something more concrete to determine the value to add. From my experimentation the required value does not seem to have any linear relationship with font size or line length. So I will keep looking. :)

M23

* SWAG - Scientific Wild Ass Guess, better than a straight WAG, but not by much! ;)

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

  • 8 years later...
  • Moderators

SharkyEXE,

I cannot see - because the dialog is hiding the line - but I would imagine that you have not changed the font size value passed to the StringSize UDF and so it is calculating for the original 20pt font size. If you want it to calculate the correct values for the new font size that line should read:

$aRet = _StringSize("Both vertically" & @CRLF & "and horizontally centered", 10)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Melba23

Hello

1) See full stroke - FonSize 20 and FontSize 10

FontSize_20_Normal.jpg

FontSize_10_Not_centered.jpg

If possible, please make automate calculation if change FontSize

Thank You!

2) I split your code

and your fix 

$aRet = _StringSize("Both vertically" & @CRLF & "and horizontally centered", 10)

See down

#include <StaticConstants.au3>
#include "StringSize.au3"

Const $iGUIWidth = 800
Const $iGUIHeight = 200

$hGui = GUICreate("Testing", 800, 200)
GUISetFont(10)
GUISetState()
$hLabelMessage = GUICtrlCreateLabel("Vertically centered", 0, 0, 800, 200, $SS_CENTERIMAGE)
Sleep(900)
GUICtrlDelete($hLabelMessage)
$hLabelMessage = GUICtrlCreateLabel("Horizontally centered", 0, 0, 800, 200, $SS_CENTER)
Sleep(900)
GUICtrlDelete($hLabelMessage)

; Get the size of label needed to hold the text
$aRet = _StringSize("Both vertically" & @CRLF & "and horizontally centered", 10)
; Work out where it needs to be on the GUI
$iX = ($iGUIWidth - $aRet[2]) / 2
$iY = ($iGUIHeight - $aRet[3]) / 2
; And create it
$hLabelMessage = GUICtrlCreateLabel("Both vertically" & @CRLF & "and horizontally centered", $iX, $iY, $aRet[2], $aRet[3], $SS_CENTER)
Sleep(9000000)

Run code and super, good, but do not see word centered in window

"Both vertically" & @CRLF & "and horizontally centered"

See picture with line and size

With_line.jpg

Edited by SharkyEXE
Link to comment
Share on other sites

  • Moderators

SharkyEXE,

I see the "centred" word on my screen. As explained earlier in the thread, at times the Windows seems to return a width value for a string which does then not fit the text when displayed! Despite lots of experimentation I cannot find a reliable solution - it seems to be a combination of specific font sizes and specific display parameters.

I suggest you add a couple of pixels to the "width" value returned by the StringSize UDF - which does already add a few pixels as a margin in both directions:

; Get the size of label needed to hold the text
$aRet = _StringSize("Both vertically" & @CRLF & "and horizontally centered", 10)
; Add a couple of pixels to the width
$aRet[2] += 2

Not the most elegant of solutions, but the only one I can offer you.

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Melba23

Hello

I modify code (add in code in post)

your code in your post

; Get the size of label needed to hold the text
$aRet = _StringSize("Both vertically" & @CRLF & "and horizontally centered", 10)
; Add a couple of pixels to the width
$aRet[2] += 2

Finaly code

#include <StaticConstants.au3>
#include "StringSize.au3"

Const $iGUIWidth = 800
Const $iGUIHeight = 200

$hGui = GUICreate("Testing", 800, 200)
GUISetFont(10)
GUISetState()
$hLabelMessage = GUICtrlCreateLabel("Vertically centered", 0, 0, 800, 200, $SS_CENTERIMAGE)
Sleep(900)
GUICtrlDelete($hLabelMessage)
$hLabelMessage = GUICtrlCreateLabel("Horizontally centered", 0, 0, 800, 200, $SS_CENTER)
Sleep(900)
GUICtrlDelete($hLabelMessage)

; Get the size of label needed to hold the text
$aRet = _StringSize("Both vertically" & @CRLF & "and horizontally centered", 10)
; Add a couple of pixels to the width
$aRet[2] += 2
; Work out where it needs to be on the GUI
$iX = ($iGUIWidth - $aRet[2]) / 2
$iY = ($iGUIHeight - $aRet[3]) / 2
; And create it
$hLabelMessage = GUICtrlCreateLabel("Both vertically" & @CRLF & "and horizontally centered", $iX, $iY, $aRet[2], $aRet[3], $SS_CENTER)
Sleep(9000000)

See picture, thank you, good!

Снимок29.jpg

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