Page 6 of 6

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

Posted: 25 May 2018, 11:48
by MannyKSoSo
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
} } }

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

Posted: 20 May 2020, 16:31
by toralf
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.

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

Posted: 20 May 2020, 18:00
by burque505
@toralf, thank you very much for updating this, I use AutoXYWH() a lot.
Regards,
burque505

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

Posted: 12 Oct 2020, 02:34
by hasantr
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.

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

Posted: 13 Mar 2021, 08:42
by mslonik
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 (🐘)

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

Posted: 09 Aug 2021, 07:14
by oldbrother
Are we going to have V2 version?

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

Posted: 26 Aug 2021, 13:16
by Alguimist
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
        }
    }
}

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

Posted: 04 Feb 2024, 11:04
by xMaxrayx
wish if we have native future with this