AutoXYWH() - Move control automatically when GUI resized

Post your working scripts, libraries and tools
User avatar
joedf
Posts: 6599
Joined: 29 Sep 2013, 17:08
Facebook: J0EDF
Google: +joedf
GitHub: joedf
Location: Canada, Quebec
Contact:

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

12 Oct 2016, 15:09

Hmmm, true... it is unspecified. I am assuming it is on a simple "attribution" basis?
Image Image Image Image Image
Windows 10 x64 Professional, Intel i5-8500 @ 3.00 GHz, 16GB DDR4 3200 MHz, NVIDIA GTX 1060 6GB | [About Me] | [ASPDM - StdLib Distribution]
[Populate the AHK MiniCity!] | [Qonsole - Quake-like console emulator] | [LibCon - Autohotkey Console Library] | [About the AHK Foundation]
tmplinshi
Posts: 1278
Joined: 01 Oct 2013, 14:57

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

12 Oct 2016, 23:28

Are there any license restrictions (for using it in a commercial application) for this one?
NO
egocarib
Posts: 99
Joined: 21 May 2015, 18:21

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

20 Oct 2016, 07:24

Using the lastest AHKv2, I get a "no object to invoke" error at the beginning of the outer For loop on this line:

Code: Select all

If ( cInfo[ctrlID].x = "" ){
I fixed the issue by adding the following line immediately before it:

Code: Select all

if !IsObject(cInfo[ctrlID]), cInfo[ctrlID] := {}
Not sure if you intended for AHKv2 compatibility or not, but I figured I'd mention the fix in case it's helpful to anyone else. (The AHKv2 documentation actually links to this thread).
User avatar
Alguimist
Posts: 297
Joined: 05 Oct 2015, 16:41
Contact:

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

13 Jan 2018, 11:57

GuiControl, Move moves the control relatively to the parent window. Controls placed in a Tab3 control are then misplaced because the parent window is a child dialog. This issue can be solved with a modified version of AutoXYWH:

Code: Select all

#NoEnv
#SingleInstance Force

Gui +Resize
Gui Add, Tab3, x8 y8 w598 h160, Tab 1|Tab 2
Gui Tab, 1
Gui Add, Button, x513 y40 w80 h24, 1
Gui Add, Button, x513 y73 w80 h24, 2
Gui Tab
Gui Add, Button, x513 y176 w80 h23, 3
Gui Show, w613 h210, Window
Return

GuiSize:
    If (A_EventInfo == 1) {
        Return
    }

    AutoXYWH("w", "SysTabControl321")
    AutoXYWH("xt", "Button1")
    AutoXYWH("x", "Button2")
    AutoXYWH("x", "Button3")
Return

GuiEscape:
GuiClose:
    ExitApp

AutoXYWH(DimSize, cList*) {
    Static cInfo := {}
 
    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%
                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 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
        }
    }
}
Notice the use of the "t" option.
toralf
Posts: 511
Joined: 27 Apr 2014, 21:08
Location: Germany

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

13 Jan 2018, 15:59

Thanks for the addition
ciao
toralf
pramach
Posts: 49
Joined: 24 Jan 2018, 08:20

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

31 Jan 2018, 10:11

Hi

I needed to add an additional init code line, otherwise I got an warning

Code: Select all

If (cInfo[ctrlID].x = "") {
            ix := iy := iw := ih := 0	;; added to prevent warning
---------------------------
TimeReport.ahk
---------------------------
Warning in #include file "AutoXYWH.ahk":
This variable has not been assigned a value.

Specifically: ix (a local variable)

Line#
045: hParentWnd := DllCall("GetParent", "Ptr", hWnd, "Ptr")
046: VarSetCapacity(RECT, 16, 0)
047: DllCall("GetWindowRect", "Ptr", hParentWnd, "Ptr", &RECT)
048: DllCall("MapWindowPoints", "Ptr", 0, "Ptr", DllCall("GetParent", "Ptr", hParentWnd, "Ptr"), "Ptr", &RECT, "UInt", 1)
049: ix := ix - NumGet(RECT, 0, "Int")
050: iy := iy - NumGet(RECT, 4, "Int")
051: }
---> 053: 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}
054: }
054: Else
054: if (cInfo[ctrlID].a.1)
054: {
055: dgx := dgw := A_GuiWidth - cInfo[ctrlID].gw, dgy := dgh := A_GuiHeight - cInfo[ctrlID].gh
056: Options := ""
057: For i,dim in cInfo[ctrlID]["a"]

For more details, read the documentation for #Warn.
---------------------------
OK
---------------------------
Just for info.

And thanks for code providing.
ahklearner
Posts: 283
Joined: 23 Jan 2015, 01:49

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

06 Feb 2018, 06:21

where can I find the updated and latest version, please :)
pramach
Posts: 49
Joined: 24 Jan 2018, 08:20

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

07 Feb 2018, 01:48

where can I find the updated and latest version, please :)
First post of this thread.

I just added the additional init line (ix:= iy:= ...) after the "if" as mentioned in my post above yours.
It works exactly the same with and without my init line, however if you have a #Warn statement in your main script than you got the warning like I have posted too.
With these init line, you don't get THIS warning (but maybe others in other functions or lines of your code).
pramach
Posts: 49
Joined: 24 Jan 2018, 08:20

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

07 Feb 2018, 02:46

what about create a loop or setinterval? and check always the size?
To do what ?

The GuiSize is already a kind of trigger called by AHK in case the GUI is resized.
User avatar
SL5
Posts: 401
Joined: 12 May 2015, 02:10
GitHub: sl5net
Contact:

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

07 Feb 2018, 02:54

what about create a loop or setinterval? and check always the size?
The GuiSize is already a kind of trigger called by AHK in case the GUI is resized.
sorry i missunderstud.
may close the control and start again?
pramach
Posts: 49
Joined: 24 Jan 2018, 08:20

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

07 Feb 2018, 03:11

sorry i missunderstud.
may close the control and start again?
Sorry but now I do not understand your wish !
pramach
Posts: 49
Joined: 24 Jan 2018, 08:20

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

07 Feb 2018, 03:13

Btw, du kannst auch im deutschen Forum einen Thread dazu eröffnen ;-)
ahklearner
Posts: 283
Joined: 23 Jan 2015, 01:49

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

07 Feb 2018, 05:22

Please help me with this.

What should be correct version for this
AutoXYWH("why", "e1","e2")
AutoXYWH("yw", "b1","b2","b3","b4")


Code: Select all

#Include, AutoXYWH.ahk

Gui, +Resize
Gui, Add, Edit, ve1 w600 h100
Gui, Add, Edit, ve2 w600 h100

Gui, Add, Button, x10 Y+10 w150 vb1 gResize, Resize
Gui, Add, Button, x+10 w150 vb2 gResize, Resize
Gui, Add, Button, x+10 vb3 w150 gResize, Resize
Gui, Add, Button, x+10 vb4 w150 gResize, Resize
Gui, Show, AutoSize
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

AutoXYWH("why", "e1","e2")
AutoXYWH("yw", "b1","b2","b3","b4")

return

pramach
Posts: 49
Joined: 24 Jan 2018, 08:20

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

07 Feb 2018, 06:06

Don't know if this is the most elegant way to solve it ...
But I would do it like that.

As the clist in AutoXYWH function is not optional, you have to pass an empty control list.

Code: Select all

Gui, Add, Edit, ve1 w600 h100 x10 y10
Gui, Add, Edit, ve2 w600 h100

Gui, Add, Button, x10 Y+10 w150 vb1 gResize, Resize
Gui, Add, Button, x+10 w150 vb2 gResize, Resize
Gui, Add, Button, x+10 vb3 w150 gResize, Resize
Gui, Add, Button, x+10 vb4 w150 gResize, Resize
Gui, +Resize
Gui, Show, AutoSize
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

	AutoXYWH("w", "e1", "e2")	; to keep width of edit fields
	h := (A_GuiHeight - 50 ) / 2		; calculate height of edit fields,  (assumption !!) -50 = 2 edit fields with space above, below & between + space for buttons
	y := 5
	Loop, 2	; for each edit field
	{
		GuiControl, MoveDraw, % "e" A_Index, % "h" h "y" y
		y += h
	}

	AutoXYWH("y*", "b1", "b2", "b3", "b4" )	; to keep Y line of buttons at bottom
	w := (A_GuiWidth - 50 ) / 4		; calculate width of button,  -50 = 4 buttons a 10 space left, right & between
	x := 10
	Loop, 4	; for each button
	{
		GuiControl, MoveDraw, % "b" A_Index, % "w" w "x" x
		x += w
	}
return

GuiEscape:
GuiClose:
	; end of application
	ExitApp

wolf_II
Posts: 2161
Joined: 08 Feb 2015, 20:55

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

07 Feb 2018, 06:15

Try this:

Code: Select all

AutoXYWH("wh0.5", "e1")
AutoXYWH("wh0.5y0.5", "e2")
AutoXYWH("*w0.25y", "b1")
AutoXYWH("*w0.25yx0.25", "b2")
AutoXYWH("*w0.25yx0.5", "b3")
AutoXYWH("*w0.25yx0.75", "b4")
I hope that helps.
ahklearner
Posts: 283
Joined: 23 Jan 2015, 01:49

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

07 Feb 2018, 06:24

Thanks a lot "wolf_II & pramach" for guidance.
I appreciate your time and efforts.
Try this:

Code: Select all

AutoXYWH("wh0.5", "e1")
AutoXYWH("wh0.5y0.5", "e2")
AutoXYWH("*w0.25y", "b1")
AutoXYWH("*w0.25yx0.25", "b2")
AutoXYWH("*w0.25yx0.5", "b3")
AutoXYWH("*w0.25yx0.75", "b4")
I hope that helps.
User avatar
kczx3
Posts: 660
Joined: 06 Oct 2015, 21:39

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

18 Mar 2018, 20:32

GuiControl, Move moves the control relatively to the parent window. Controls placed in a Tab3 control are then misplaced because the parent window is a child dialog. This issue can be solved with a modified version of AutoXYWH:

Code: Select all

#NoEnv
#SingleInstance Force

Gui +Resize
Gui Add, Tab3, x8 y8 w598 h160, Tab 1|Tab 2
Gui Tab, 1
Gui Add, Button, x513 y40 w80 h24, 1
Gui Add, Button, x513 y73 w80 h24, 2
Gui Tab
Gui Add, Button, x513 y176 w80 h23, 3
Gui Show, w613 h210, Window
Return

GuiSize:
    If (A_EventInfo == 1) {
        Return
    }

    AutoXYWH("w", "SysTabControl321")
    AutoXYWH("xt", "Button1")
    AutoXYWH("x", "Button2")
    AutoXYWH("x", "Button3")
Return

GuiEscape:
GuiClose:
    ExitApp

AutoXYWH(DimSize, cList*) {
    Static cInfo := {}
 
    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%
                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 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
        }
    }
}
Notice the use of the "t" option.
Thank you for this!
burque505
Posts: 626
Joined: 22 Jan 2017, 19:37

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

20 Mar 2018, 11:26

Alguimist, thanks for the mod with the "t" option.
For this code:

Code: Select all

GuiSize:
    If (A_EventInfo == 1) {
        Return
    }

    AutoXYWH("w", "SysTabControl321")
    AutoXYWH("xt", "Button1")
    AutoXYWH("x", "Button2")
    AutoXYWH("x", "Button3")
Return
A resized GUI looks like this:
Mod1.PNG
Mod1.PNG (19.46 KiB) Viewed 723 times
For this code:

Code: Select all

GuiSize:
    If (A_EventInfo == 1) {
        Return
    }

    AutoXYWH("w", "SysTabControl321")
    AutoXYWH("xt", "Button1")
    AutoXYWH("xt", "Button2")
    AutoXYWH("x", "Button3")
Return
A resized GUI looks nice and even:
Mod2.PNG
Mod2.PNG (19.26 KiB) Viewed 723 times
And for this code, with the "t" option added for the bottom button, well ;) look Ma, no Button3!:

Code: Select all

GuiSize:
    If (A_EventInfo == 1) {
        Return
    }

    AutoXYWH("w", "SysTabControl321")
    AutoXYWH("xt", "Button1")
    AutoXYWH("xt", "Button2")
    AutoXYWH("xt", "Button3")
Return
Whoops.PNG
Whoops.PNG (17.6 KiB) Viewed 723 times
I notice that Window Spy reports:
Tab1 is "Button1",
Button1 is "Button 1",
Button2 is "Button2",
Tab2 is "SysTabControl321",
Button3 is "Button3".

I'm betting that's something more to do with Window Spy than it is with the function.

This seems to me like it will be a useful addition to the toolbox, thank you!
Regards,
burque505
User avatar
kczx3
Posts: 660
Joined: 06 Oct 2015, 21:39

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

20 Mar 2018, 11:58

I would never recommend using the variable name or control class when using this function. You should always specify the hwnd of the control. There is no reason not to as it uniquely identifies it. Any control inside a tab 3 control will have to have the "t" option.

Return to “Scripts and Functions”

Who is online

Users browsing this forum: Bing [Bot] and 44 guests