Consider the following snippet:
FormatTime, time,
Gui, Add, Text, vcTime,
GuiControl, , cTime, % time
Gui, Show, NoActivate Center AutoSize
AutoSize
is based on the initial value from Gui, Add, Text, vcTime
and not on the new value set by GuiControl, , cTime, % time
. Depending on months etc., %time%
length can vary. How can I automatically resize the window to adapt to updated values of %time%
?
`
AutoSize
is actually based on the current control sizes when Gui Show
is called. The issue is that the "blank" subcommand to GuiControl
for text controls does not automatically resize the control; it just changes the text and you still have to call GuiControl Move
with a new size yourself. So, in your example, if you replace AutoSize
with w200
the text will still be cut off at the same point.
As far as I know, there's not really a "built-in" automatic way to resize the text control based on the new text. The closest way is to use AHK's initial size calculation when creating a text control: create a new text control with the desired text, use GuiControlGet
to get the size of the new control, and finally set the size of the original control to that size using GuiControl Move
. Here's an example function which does this, adapted from here:
SetTextAndResize(controlHwnd, newText, fontOptions := "", fontName := "") {
Gui 9:Font, %fontOptions%, %fontName%
Gui 9:Add, Text, R1, %newText%
GuiControlGet T, 9:Pos, Static1
Gui 9:Destroy
GuiControl,, %controlHwnd%, %newText%
GuiControl Move, %controlHwnd%, % "h" TH " w" TW
}
Which would fit into your example like so:
FormatTime, time,
Gui, Add, Text, HwndTimeHwnd vcTime,
SetTextAndResize(TimeHwnd, time)
Gui, Show, NoActivate Center AutoSize
Now whenever you use SetTextAndResize
instead of just setting the text you can use Gui Show, AutoSize
to automatically resize the window correctly. Note that if you changed the font with Gui Font
before adding the text control you would have to pass those same options to SetTextAndResize
.
Alternatively, I looked at how AHK itself calculates the initial size of a text control for Gui Add, Text
when none is provided and found it uses the Windows API function DrawText
with DT_CALCRECT
. Here's another implementation of SetTextAndResize
I wrote using this directly:
SetTextAndResize(controlHwnd, newText) {
dc := DllCall("GetDC", "Ptr", controlHwnd)
; 0x31 = WM_GETFONT
SendMessage 0x31,,,, ahk_id %controlHwnd%
hFont := ErrorLevel
oldFont := 0
if (hFont != "FAIL")
oldFont := DllCall("SelectObject", "Ptr", dc, "Ptr", hFont)
VarSetCapacity(rect, 16, 0)
; 0x440 = DT_CALCRECT | DT_EXPANDTABS
h := DllCall("DrawText", "Ptr", dc, "Ptr", &newText, "Int", -1, "Ptr", &rect, "UInt", 0x440)
; width = rect.right - rect.left
w := NumGet(rect, 8, "Int") - NumGet(rect, 0, "Int")
if oldFont
DllCall("SelectObject", "Ptr", dc, "Ptr", oldFont)
DllCall("ReleaseDC", "Ptr", controlHwnd, "Ptr", dc)
GuiControl,, %controlHwnd%, %newText%
GuiControl Move, %controlHwnd%, % "h" h " w" w
}
I'm not sure how it compares to the first method in terms of performance, but one advantage is that it gets the font based on the control itself rather than having to provide it to the function yourself.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With