AutoXYWH() - Move control automatically when GUI resized

Post your working scripts, libraries and tools
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: 792
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: 1357
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

Return to “Scripts and Functions”

Who is online

Users browsing this forum: Gaia and 31 guests