AutoXYWH() - Move control automatically when GUI resized

Post your working scripts, libraries and tools for AHK v1.1 and older
MannyKSoSo
Posts: 440
Joined: 28 Apr 2018, 21:59

Re: AutoXYWH() - Move control automatically when GUI resized

25 May 2018, 11:48

Hello, I greatly appreciate the function you have made for the control of resizing, however in my script I am having a problem with getting things to resize the way I want to. Right now I only have 3 out of the 8 controls created that I want. Basically I want each control to be re sizable for a selectable area (which is not implemented yet), which it does what its suppose to, except when I adjust the other controls. The first one "Light" works just fine, then when you do "Name" and "Coords" issues appear as they start going over one another, unless you readjust the "light" size again which then fixes the problem. Was just curious how I would be able to fix this problem and have the controls not overlap each other. Thanks.

Code: Select all

#SingleInstance Force

Gui, Color,, Yellow
Gui, Add, Button, x2 y2 w70 h20 gLight vLightBttn, Light
Gui, Add, Edit, x2 y25 w70 h20 vLight -VScroll
Gui, Add, Button, x72 y2 w70 h20 vNameBttn gName, Name
Gui, Add, Edit, x72 y25 w70 h20 vName -VScroll
Gui, Add, Button, x1050 y150 w50 h20 gCoordates
Gui, Add, Button, x142 y2 w70 h20 vCoordsBttn gCoords, Coords
Gui, Add, Edit, x142 y25 w70 h20 vCoords -VScroll
Gui +LastFound
Winset, TransColor, Yellow 255
Gui, Show, xcenter ycenter w1100 h200
Return

GuiClose:
ExitApp
Return

Coordates:
WinGetPos, XPositions, YPositions
GuiControlGet, Positions, Pos, Light
MsgBox % XPositions ":" YPositions ":" Positionsw ":" Positionsh
Return

Light:
Gui, Submit, NoHide
GuiControlGet, Field,, Light
WinGetPos, Xpos, Ypos
GuiControlGet, GBPos, Pos, Light
GBPosx+=GBPosw
GBPosy+=GBPosh
MouseMove, GBPosw, GBPosh,, R
	Loop,
	{
		MouseGetPos, X, Y
		wThis := X-GBPosx+GBPosw
		hThis := Y-GBPosy+GBPosh-47
		GuiControl, Move, Light, w%wThis% h%hThis%
		wthis+=3
		GuiControl, Move, Name, x%wThis%
		GuiControl, Move, NameBttn, x%wThis%
		GuiControlGet, Temp, Pos, Name
		wThis+=Tempw
		GuiControl, Move, Coords, x%wThis%
		GuiControl, Move, CoordsBttn, x%wThis%
		Sleep 10
	}
	Until GetKeyState("LButton")
Return

Name:
Gui, Submit, NoHide
GuiControlGet, Field,, Name
WinGetPos, Xpos, Ypos
GuiControlGet, GBPos, Pos, Name
GBPosx+=GBPosw
GBPosy+=GBPosh
MouseMove, GBPosw, GBPosh,, R
	Loop,
	{
		MouseGetPos, X, Y
		wThis := X-GBPosx+GBPosw
		hThis := Y-GBPosy+GBPosh-47
		GuiControl, Move, Name, w%wThis% h%hThis%
		wthis+=3
		GuiControl, Move, Coords, x%wThis%
		GuiControl, Move, CoordsBttn, x%wThis%
		Sleep 10
	}
	Until GetKeyState("LButton")
Return
	
Coords:
Gui, Submit, NoHide
GuiControlGet, Field,, Coords
WinGetPos, Xpos, Ypos
GuiControlGet, GBPos, Pos, Coords
GBPosx+=GBPosw
GBPosy+=GBPosh
MouseMove, GBPosw, GBPosh,, R
	Loop,
	{
		MouseGetPos, X, Y
		wThis := X-GBPosx+GBPosw
		hThis := Y-GBPosy+GBPosh-47
		GuiControl, Move, Coords, w%wThis% h%hThis%
		Sleep 10
	}
	Until GetKeyState("LButton")
Return

GuiSize:
AutoXYWH("xwh", "Light" "Name" "NameBttn" "Coords" "CoordsBttn")
AutoXYWH("xwh", "Name" "Coords" "CoordsBttn")
Return

; =================================================================================
; Function: AutoXYWH
;   Move and resize control automatically when GUI resizes.
; Parameters:
;   DimSize - Can be one or more of x/y/w/h  optional followed by a fraction
;             add a '*' to DimSize to 'MoveDraw' the controls rather then just 'Move', this is recommended for Groupboxes
;   cList   - variadic list of ControlIDs
;             ControlID can be a control HWND, associated variable name, ClassNN or displayed text.
;             The later (displayed text) is possible but not recommend since not very reliable 
; Examples:
;   AutoXYWH("xy", "Btn1", "Btn2")
;   AutoXYWH("w0.5 h 0.75", hEdit, "displayed text", "vLabel", "Button1")
;   AutoXYWH("*w0.5 h 0.75", hGroupbox1, "GrbChoices")
; ---------------------------------------------------------------------------------
; Release date: 2014-7-03          
; Author      : tmplinshi (mod by toralf)
; requires AHK version : 1.1.13.01+
; =================================================================================
AutoXYWH(DimSize, cList*){       ; http://ahkscript.org/boards/viewtopic.php?t=1079
  static cInfo := {}
  For i, ctrl in cList {
    ctrlID := A_Gui ":" ctrl
    If ( cInfo[ctrlID].x = "" ){
        GuiControlGet, i, %A_Gui%:Pos, %ctrl%
        GuiControlGet, Hwnd, %A_Gui%:Hwnd, %ctrl%
        MMD := InStr(DimSize, "*") ? "MoveDraw" : "Move"
        fx := fy := fw := fh := 0
        For i, dim in (a := StrSplit(RegExReplace(DimSize, "i)[^xywh]")))
            If !RegExMatch(DimSize, "i)" dim "\s*\K[\d.-]+", f%dim%)
              f%dim% := 1
        cInfo[ctrlID] := { x:ix, fx:fx, y:iy, fy:fy, w:iw, fw:fw, h:ih, fh:fh, gw:A_GuiWidth, gh:A_GuiHeight, a:a , m:MMD}
    }Else If ( cInfo[ctrlID].a.1) {
        dgx := dgw := A_GuiWidth  - cInfo[ctrlID].gw  , dgy := dgh := A_GuiHeight - cInfo[ctrlID].gh
        For i, dim in cInfo[ctrlID]["a"]
            Options .= dim (dg%dim% * cInfo[ctrlID]["f" dim] + cInfo[ctrlID][dim]) A_Space
        GuiControl, % A_Gui ":" cInfo[ctrlID].m , % ctrl, % Options
} } }
toralf
Posts: 868
Joined: 27 Apr 2014, 21:08
Location: Germany

Re: AutoXYWH() - Move control automatically when GUI resized

20 May 2020, 16:31

I updated the code with all the additions made by Alguimist and pramach and added some tiny code improvements myself.

Code: Select all

  #NoEnv
  #SingleInstance Force
  #Warn

  Gui +Resize +MinSize
  Gui Add, Tab3, x80 y80 w298 h160 vTab, Tab 1|Tab 2
  Gui Tab, 1
  Gui Add, Button, x213 y120 w80 h24 vBtn1, 1
  Gui Add, Button, x213 y153 w80 h24 vBtn2, 2
  Gui Tab
  Gui Add, Button, x213 y256 w80 h23 vBtn3, 3
  Gui Show, , AutoXYWH Test Window
Return

GuiSize:
  AutoXYWH("w h0.5", "Tab")
  AutoXYWH("t x h0.5", "Btn1")
  AutoXYWH("t x y0.5", "Btn2")
  AutoXYWH("x y0.5 h0.5", "Btn3")
Return

GuiEscape:
GuiClose:
    ExitApp

; =================================================================================
; Function: AutoXYWH
;   Move and resize control automatically when GUI resizes.
; Parameters:
;   DimSize - Can be one or more of x/y/w/h  optional followed by a fraction
;             add a '*' to DimSize to 'MoveDraw' the controls rather then just 'Move', this is recommended for Groupboxes
;             add a 't' to DimSize to tell AutoXYWH that the controls in cList are on/in a tab3 control
;   cList   - variadic list of ControlIDs
;             ControlID can be a control HWND, associated variable name, ClassNN or displayed text.
;             The later (displayed text) is possible but not recommend since not very reliable 
; Examples:
;   AutoXYWH("xy", "Btn1", "Btn2")
;   AutoXYWH("w0.5 h 0.75", hEdit, "displayed text", "vLabel", "Button1")
;   AutoXYWH("*w0.5 h 0.75", hGroupbox1, "GrbChoices")
;   AutoXYWH("t x h0.5", "Btn1")
; ---------------------------------------------------------------------------------
; Version: 2020-5-20 / small code improvements (toralf)
;          2018-1-31 / added a line to prevent warnings (pramach)
;          2018-1-13 / added t option for controls on Tab3 (Alguimist)
;          2015-5-29 / added 'reset' option (tmplinshi)
;          2014-7-03 / mod by toralf
;          2014-1-02 / initial version tmplinshi
; requires AHK version : 1.1.13.01+    due to SprSplit()
; =================================================================================

AutoXYWH(DimSize, cList*){   ;https://www.autohotkey.com/boards/viewtopic.php?t=1079
  Static cInfo := {}

  If (DimSize = "reset")
    Return cInfo := {}

  For i, ctrl in cList {
    ctrlID := A_Gui ":" ctrl
    If !cInfo.hasKey(ctrlID) {
      ix := iy := iw := ih := 0	
      GuiControlGet i, %A_Gui%: Pos, %ctrl%
      MMD := InStr(DimSize, "*") ? "MoveDraw" : "Move"
      fx := fy := fw := fh := 0
      For i, dim in (a := StrSplit(RegExReplace(DimSize, "i)[^xywh]"))) 
        If !RegExMatch(DimSize, "i)" . dim . "\s*\K[\d.-]+", f%dim%)
          f%dim% := 1

      If (InStr(DimSize, "t")) {
        GuiControlGet hWnd, %A_Gui%: hWnd, %ctrl%
        hParentWnd := DllCall("GetParent", "Ptr", hWnd, "Ptr")
        VarSetCapacity(RECT, 16, 0)
        DllCall("GetWindowRect", "Ptr", hParentWnd, "Ptr", &RECT)
        DllCall("MapWindowPoints", "Ptr", 0, "Ptr", DllCall("GetParent", "Ptr", hParentWnd, "Ptr"), "Ptr", &RECT, "UInt", 1)
        ix := ix - NumGet(RECT, 0, "Int")
        iy := iy - NumGet(RECT, 4, "Int")
      }

      cInfo[ctrlID] := {x:ix, fx:fx, y:iy, fy:fy, w:iw, fw:fw, h:ih, fh:fh, gw:A_GuiWidth, gh:A_GuiHeight, a:a, m:MMD}
    } Else {
      dgx := dgw := A_GuiWidth - cInfo[ctrlID].gw, dgy := dgh := A_GuiHeight - cInfo[ctrlID].gh
      Options := ""
      For i, dim in cInfo[ctrlID]["a"]
        Options .= dim (dg%dim% * cInfo[ctrlID]["f" . dim] + cInfo[ctrlID][dim]) A_Space
      GuiControl, % A_Gui ":" cInfo[ctrlID].m, % ctrl, % Options
} } }
@tmplinshi: may I ask you to update the first post? Thanks a lot in advance.
ciao
toralf
burque505
Posts: 1734
Joined: 22 Jan 2017, 19:37

Re: AutoXYWH() - Move control automatically when GUI resized

20 May 2020, 18:00

@toralf, thank you very much for updating this, I use AutoXYWH() a lot.
Regards,
burque505
hasantr
Posts: 933
Joined: 05 Apr 2016, 14:18
Location: İstanbul

Re: AutoXYWH() - Move control automatically when GUI resized

12 Oct 2020, 02:34

toralf wrote:
20 May 2020, 16:31
I updated the code with all the additions made by Alguimist and pramach and added some tiny code improvements myself.

Code: Select all

  #NoEnv
  #SingleInstance Force
  #Warn

  Gui +Resize +MinSize
  Gui Add, Tab3, x80 y80 w298 h160 vTab, Tab 1|Tab 2
  Gui Tab, 1
  Gui Add, Button, x213 y120 w80 h24 vBtn1, 1
  Gui Add, Button, x213 y153 w80 h24 vBtn2, 2
  Gui Tab
  Gui Add, Button, x213 y256 w80 h23 vBtn3, 3
  Gui Show, , AutoXYWH Test Window
Return

GuiSize:
  AutoXYWH("w h0.5", "Tab")
  AutoXYWH("t x h0.5", "Btn1")
  AutoXYWH("t x y0.5", "Btn2")
  AutoXYWH("x y0.5 h0.5", "Btn3")
Return

GuiEscape:
GuiClose:
    ExitApp

; =================================================================================
; Function: AutoXYWH
;   Move and resize control automatically when GUI resizes.
; Parameters:
;   DimSize - Can be one or more of x/y/w/h  optional followed by a fraction
;             add a '*' to DimSize to 'MoveDraw' the controls rather then just 'Move', this is recommended for Groupboxes
;             add a 't' to DimSize to tell AutoXYWH that the controls in cList are on/in a tab3 control
;   cList   - variadic list of ControlIDs
;             ControlID can be a control HWND, associated variable name, ClassNN or displayed text.
;             The later (displayed text) is possible but not recommend since not very reliable 
; Examples:
;   AutoXYWH("xy", "Btn1", "Btn2")
;   AutoXYWH("w0.5 h 0.75", hEdit, "displayed text", "vLabel", "Button1")
;   AutoXYWH("*w0.5 h 0.75", hGroupbox1, "GrbChoices")
;   AutoXYWH("t x h0.5", "Btn1")
; ---------------------------------------------------------------------------------
; Version: 2020-5-20 / small code improvements (toralf)
;          2018-1-31 / added a line to prevent warnings (pramach)
;          2018-1-13 / added t option for controls on Tab3 (Alguimist)
;          2015-5-29 / added 'reset' option (tmplinshi)
;          2014-7-03 / mod by toralf
;          2014-1-02 / initial version tmplinshi
; requires AHK version : 1.1.13.01+    due to SprSplit()
; =================================================================================

AutoXYWH(DimSize, cList*){   ;https://www.autohotkey.com/boards/viewtopic.php?t=1079
  Static cInfo := {}

  If (DimSize = "reset")
    Return cInfo := {}

  For i, ctrl in cList {
    ctrlID := A_Gui ":" ctrl
    If !cInfo.hasKey(ctrlID) {
      ix := iy := iw := ih := 0	
      GuiControlGet i, %A_Gui%: Pos, %ctrl%
      MMD := InStr(DimSize, "*") ? "MoveDraw" : "Move"
      fx := fy := fw := fh := 0
      For i, dim in (a := StrSplit(RegExReplace(DimSize, "i)[^xywh]"))) 
        If !RegExMatch(DimSize, "i)" . dim . "\s*\K[\d.-]+", f%dim%)
          f%dim% := 1

      If (InStr(DimSize, "t")) {
        GuiControlGet hWnd, %A_Gui%: hWnd, %ctrl%
        hParentWnd := DllCall("GetParent", "Ptr", hWnd, "Ptr")
        VarSetCapacity(RECT, 16, 0)
        DllCall("GetWindowRect", "Ptr", hParentWnd, "Ptr", &RECT)
        DllCall("MapWindowPoints", "Ptr", 0, "Ptr", DllCall("GetParent", "Ptr", hParentWnd, "Ptr"), "Ptr", &RECT, "UInt", 1)
        ix := ix - NumGet(RECT, 0, "Int")
        iy := iy - NumGet(RECT, 4, "Int")
      }

      cInfo[ctrlID] := {x:ix, fx:fx, y:iy, fy:fy, w:iw, fw:fw, h:ih, fh:fh, gw:A_GuiWidth, gh:A_GuiHeight, a:a, m:MMD}
    } Else {
      dgx := dgw := A_GuiWidth - cInfo[ctrlID].gw, dgy := dgh := A_GuiHeight - cInfo[ctrlID].gh
      Options := ""
      For i, dim in cInfo[ctrlID]["a"]
        Options .= dim (dg%dim% * cInfo[ctrlID]["f" . dim] + cInfo[ctrlID][dim]) A_Space
      GuiControl, % A_Gui ":" cInfo[ctrlID].m, % ctrl, % Options
} } }
@tmplinshi: may I ask you to update the first post? Thanks a lot in advance.
Thanks. That was very nice.
User avatar
mslonik
Posts: 144
Joined: 21 Feb 2019, 04:38
Location: Poland
Contact:

Re: AutoXYWH() - Move control automatically when GUI resized

13 Mar 2021, 08:42

Hello,

thank you for this great piece of code.

I wonder what am I missing out? With reference example I'm able to get controls out of a GUI:

Code: Select all

#SingleInstance,Force
#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
#Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.


Gui, +Resize
Gui, Add, Edit, 	Hwnde1hwnd ve1 w150 h100
Gui, Add, Button, 	Hwndb1hwnd vb1 gResize, Resize
Gui, Show
return

Resize:
GuiControl, Move, e1, h50
AutoXYWH("reset") ; Needs to reset if you changed the Control size manually.
return

GuiSize:
If (A_EventInfo = 1) ; The window has been minimized.
	Return
if (A_EventInfo = 2) ; The window has been maximized.
{
	MsgBox, , Size of maximized window, % "A_GuiWidth: " . A_GuiWidth . "`nA_GuiHeight: " . A_GuiHeight
}
AutoXYWH("wh",e1hwnd)
GuiControlGet, Oute1, Pos, % e1hwnd
AutoXYWH("y", b1hwnd)
GuiControlGet, Outb1, Pos, % b1hwnd
;MsgBox, , Size of GUI, % "A_GuiWidth: " . A_GuiWidth . "`nA_GuiHeight: " . A_GuiHeight . "`nPosition e1: " . Oute1X . A_Space . Oute1Y . A_Space . Oute1W . A_Space . Oute1H 
;. "`nPosition b1: " . Outb1X . A_Space . Outb1Y . A_Space . Outb1W . A_Space . Outb1H
return
Sequence which moves controls outside of visible area of GUI:

1. Click "Maximize" window (system) button.
2. Click "Resize" control (GUI button).
3. Click "Restore Down" window (system) button.
4. Click "Maximize" window (system) button.

If you like you can uncomment the last MsgBox to get comparison between sizes of GUI and sizes of controls.

Please shed some light on this issue. Is it somehow related to operating system itself?

Kind regards, mslonik (🐘)

My scripts on this forum: Hotstrings Diacritic O T A G L E
Please become my patreon: Patreon👍
Written in AutoHotkey text replacement tool: Hotstrings.technology
Courses on AutoHotkey :ugeek:
User avatar
oldbrother
Posts: 273
Joined: 23 Oct 2013, 05:08

Re: AutoXYWH() - Move control automatically when GUI resized

09 Aug 2021, 07:14

Are we going to have V2 version?
User avatar
Alguimist
Posts: 428
Joined: 05 Oct 2015, 16:41
Contact:

Re: AutoXYWH() - Move control automatically when GUI resized

26 Aug 2021, 13:16

AutoSize is a variant of AutoXYWH, now compatible with High-DPI.

For controls placed in a Tab3 control, add "t" to the parameters. The control's positioning will be calculated relatevily to the inner window of the tab.

Code: Select all

; Original: http://ahkscript.org/boards/viewtopic.php?t=1079
AutoSize(DimSize, cList*) {
    Static cInfo := {}
    Local

    If (DimSize = "reset") {
        Return cInfo := {}
    }

    For i, ctrl in cList {
        ctrlID := A_Gui . ":" . ctrl
        If (cInfo[ctrlID].x = "") {
            GuiControlGet i, %A_Gui%: Pos, %ctrl%
            MMD := InStr(DimSize, "*") ? "MoveDraw" : "Move"
            fx := fy := fw := fh := 0
            For i, dim in (a := StrSplit(RegExReplace(DimSize, "i)[^xywh]"))) {
                If (!RegExMatch(DimSize, "i)" . dim . "\s*\K[\d.-]+", f%dim%)) {
                    f%dim% := 1
                }
            }

            If (InStr(DimSize, "t")) {
                GuiControlGet hWnd, %A_Gui%: hWnd, %ctrl%
                hWndParent := DllCall("GetParent", "Ptr", hWnd, "Ptr")
                VarSetCapacity(RECT, 16, 0)
                DllCall("GetWindowRect", "Ptr", hWndParent, "Ptr", &RECT)
                DllCall("MapWindowPoints", "Ptr", 0, "Ptr"
                , DllCall("GetParent", "Ptr", hWndParent, "Ptr"), "Ptr", &RECT, "UInt", 1)
                ix -= (NumGet(RECT, 0, "Int") * 96) // A_ScreenDPI
                iy -= (NumGet(RECT, 4, "Int") * 96) // A_ScreenDPI
            }

            cInfo[ctrlID] := {x: ix, fx: fx, y: iy, fy: fy, w: iw, fw: fw, h: ih, fh: fh, gw: A_GuiWidth, gh: A_GuiHeight, a: a, m: MMD}

        } Else If (cInfo[ctrlID].a.1) {
            dgx := dgw := A_GuiWidth - cInfo[ctrlID].gw
            dgy := dgh := A_GuiHeight - cInfo[ctrlID].gh

            Options := ""
            For i, dim in cInfo[ctrlID]["a"] {
                Options .= dim . (dg%dim% * cInfo[ctrlID]["f" . dim] + cInfo[ctrlID][dim]) . A_Space
            }

            GuiControl, % A_Gui ":" cInfo[ctrlID].m, % ctrl, % Options
        }
    }
}
User avatar
xMaxrayx
Posts: 163
Joined: 06 Dec 2022, 02:56
Contact:

Re: AutoXYWH() - Move control automatically when GUI resized

04 Feb 2024, 11:04

wish if we have native future with this
-----------------------ヾ(•ω•`)o------------------------------
https://github.com/xmaxrayx/

Return to “Scripts and Functions (v1)”

Who is online

Users browsing this forum: No registered users and 142 guests