AutoHotkey:基于文本的动态调整大小控件
AutoHotkey: Dynamic resize control based on text
考虑以下片段:
FormatTime, time,
Gui, Add, Text, vcTime,
GuiControl, , cTime, % time
Gui, Show, NoActivate Center AutoSize
AutoSize
基于 Gui, Add, Text, vcTime
的初始值,而不是 GuiControl, , cTime, % time
设置的新值。根据月份等,%time%
长度可能会有所不同。如何自动调整 window 的大小以适应 %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;它只是更改了文本,您仍然需要自己调用 GuiControl Move
并使用新的尺寸。因此,在您的示例中,如果将 AutoSize
替换为 w200
,文本仍将在同一点被截断。
据我所知,并没有真正的 "built-in" 自动方法来根据新文本调整文本控件的大小。最接近的方法是在创建文本控件时使用AHK的初始大小计算:用想要的文本创建一个新的文本控件,使用GuiControlGet
获取新控件的大小,最后设置原控件的大小使用 GuiControl Move
到那个大小。这是一个执行此操作的示例函数,改编自 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
}
哪个适合您的示例:
FormatTime, time,
Gui, Add, Text, HwndTimeHwnd vcTime,
SetTextAndResize(TimeHwnd, time)
Gui, Show, NoActivate Center AutoSize
现在,无论何时您使用 SetTextAndResize
而不是仅仅设置文本,您都可以使用 Gui Show, AutoSize
自动正确调整 window 的大小。请注意,如果您在添加文本控件之前使用 Gui Font
更改了字体,则必须将这些相同的选项传递给 SetTextAndResize
.
或者,当提供 none 时,我查看了 AHK 本身如何计算 Gui Add, Text
文本控件的初始大小,发现它使用 Windows API函数 DrawText
和 DT_CALCRECT
。这是我直接使用它编写的 SetTextAndResize
的另一个实现:
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
}
我不确定它在性能方面与第一种方法相比如何,但一个优点是它根据控件本身获取字体,而不必自己将其提供给函数。
考虑以下片段:
FormatTime, time,
Gui, Add, Text, vcTime,
GuiControl, , cTime, % time
Gui, Show, NoActivate Center AutoSize
AutoSize
基于 Gui, Add, Text, vcTime
的初始值,而不是 GuiControl, , cTime, % time
设置的新值。根据月份等,%time%
长度可能会有所不同。如何自动调整 window 的大小以适应 %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;它只是更改了文本,您仍然需要自己调用 GuiControl Move
并使用新的尺寸。因此,在您的示例中,如果将 AutoSize
替换为 w200
,文本仍将在同一点被截断。
据我所知,并没有真正的 "built-in" 自动方法来根据新文本调整文本控件的大小。最接近的方法是在创建文本控件时使用AHK的初始大小计算:用想要的文本创建一个新的文本控件,使用GuiControlGet
获取新控件的大小,最后设置原控件的大小使用 GuiControl Move
到那个大小。这是一个执行此操作的示例函数,改编自 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
}
哪个适合您的示例:
FormatTime, time,
Gui, Add, Text, HwndTimeHwnd vcTime,
SetTextAndResize(TimeHwnd, time)
Gui, Show, NoActivate Center AutoSize
现在,无论何时您使用 SetTextAndResize
而不是仅仅设置文本,您都可以使用 Gui Show, AutoSize
自动正确调整 window 的大小。请注意,如果您在添加文本控件之前使用 Gui Font
更改了字体,则必须将这些相同的选项传递给 SetTextAndResize
.
或者,当提供 none 时,我查看了 AHK 本身如何计算 Gui Add, Text
文本控件的初始大小,发现它使用 Windows API函数 DrawText
和 DT_CALCRECT
。这是我直接使用它编写的 SetTextAndResize
的另一个实现:
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
}
我不确定它在性能方面与第一种方法相比如何,但一个优点是它根据控件本身获取字体,而不必自己将其提供给函数。