AutoHotkey:基于文本的动态调整大小控制

ant*_*nio 4 controls autohotkey autosize

请考虑以下代码段:

FormatTime, time,
Gui, Add, Text, vcTime, 
GuiControl, , cTime, % time 
Gui, Show, NoActivate Center AutoSize
Run Code Online (Sandbox Code Playgroud)

AutoSize是基于初始值Gui, Add, Text, vcTime而不是基于新值设置的GuiControl, , cTime, % time.根据月份等,%time%长度可能会有所不同.如何自动调整窗口大小以适应更新后的值%time%?`

Jos*_*bst 6

AutoSize实际上是基于Gui Show调用时的当前控件大小.问题是GuiControl文本控件的"空白"子命令不会自动调整控件的大小 ; 它只是更改文本,你仍然需要自己调用GuiControl Move新的大小.所以,在你的榜样,如果更换AutoSizew200的文本仍将在同一点切断.

据我所知,并没有真正的"内置"自动方式来根据新文本调整文本控件的大小.最接近的方法是在创建文本控件时使用AHK的初始大小计算:使用所需文本创建新文本控件,用于GuiControlGet获取新控件的大小,最后使用将原始控件的大小设置为该大小GuiControl Move.这是一个示例函数,它执行此操作,从此处改编:

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
}
Run Code Online (Sandbox Code Playgroud)

哪个适合你的例子:

FormatTime, time,
Gui, Add, Text, HwndTimeHwnd vcTime,
SetTextAndResize(TimeHwnd, time)
Gui, Show, NoActivate Center AutoSize
Run Code Online (Sandbox Code Playgroud)

现在,无论何时使用SetTextAndResize而不是仅设置文本,您都可以使用它Gui Show, AutoSize来自动调整窗口大小.请注意,如果Gui Font在添加文本控件之前更改了字体,则必须将相同的选项传递给SetTextAndResize.

另外,我看着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
}
Run Code Online (Sandbox Code Playgroud)

我不确定它在性能方面与第一种方法相比如何,但一个优点是它可以根据控件本身获取字体,而不必自己将其提供给函数.