AutoXYWH() - Move control automatically when GUI resized

Post your working scripts, libraries and tools
tmplinshi
Posts: 1269
Joined: 01 Oct 2013, 14:57

AutoXYWH() - Move control automatically when GUI resized

20 Dec 2013, 06:39

This is a simple version of Anchor() by Titan.

Old version
[/color]

Modified version by toralf:

Code: Select all

; =================================================================================
; 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")
; ---------------------------------------------------------------------------------
; Version: 2015-5-29 / Added 'reset' option (by tmplinshi)
;          2014-7-03 / toralf
;          2014-1-2  / tmplinshi
; requires AHK version : 1.1.13.01+
; =================================================================================
AutoXYWH(DimSize, cList*){       ; http://ahkscript.org/boards/viewtopic.php?t=1079
  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
        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
} } }
Example:

Code: Select all

#Include, AutoXYWH.ahk

Gui, +Resize
Gui, Add, Edit, ve1 w150 h100
Gui, Add, Button, 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
	AutoXYWH("wh", "e1")
	AutoXYWH("y", "b1")
return
Last edited by tmplinshi on 28 May 2015, 22:57, edited 11 times in total.
Rindis
Posts: 210
Joined: 23 Dec 2013, 13:58
Location: Norway

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

23 Dec 2013, 14:28

Hi
I can't get this to work. I get an error saying "Call to non existent function" in this line:

cInfo[ctrl] := { _x:(_x), _y:(_y), _w:(_w), _h:(_h), _a:StrSplit(_a) }


Cheers
tmplinshi
Posts: 1269
Joined: 01 Oct 2013, 14:57

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

23 Dec 2013, 14:31

Hello, Rindis
Please use latest version of AHK. Download link: http://l.autohotkey.net/AutoHotkey_L_Install.exe
User avatar
gregster
Posts: 1395
Joined: 30 Sep 2013, 06:48

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

23 Dec 2013, 14:33

As far as I know, StrSplit() - as a function - is relatively new to AHK (the corresponding command is older) . You probably need AHK 1.1.13.01, like it is mentioned in the script header. So, update...!
Rindis
Posts: 210
Joined: 23 Dec 2013, 13:58
Location: Norway

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

23 Dec 2013, 14:39

:oops: Thank. Now updated and its working

Cheers
toralf
Posts: 506
Joined: 27 Apr 2014, 21:08
Location: Germany

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

25 Jun 2014, 13:41

Dear tmplinshi,

your code is nice, but it doesn't support fractions of dimensions, e.g. w0.5 = control gets only half of the gui width change.
Have you considered to expend your function in this direction?
ciao
toralf
User avatar
joedf
Posts: 6502
Joined: 29 Sep 2013, 17:08
Facebook: J0EDF
Google: +joedf
GitHub: joedf
Location: Canada, Quebec
Contact:

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

25 Jun 2014, 15:03

Nice!
@toralf true... But then, doesn't anchor do that?
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]
toralf
Posts: 506
Joined: 27 Apr 2014, 21:08
Location: Germany

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

25 Jun 2014, 15:37

@joedf
Yes, but much more complicated. The lastest version of Anchor() is very complex code (i assume it got further optimized for speed). This version is simple and uses the latest features of AHK. And it allows to give a list of controls at once.

I went ahead an made a mod.

Code: Select all

; =================================================================================
; Function:     AutoXYWH
;   Move and resize control automatically when GUI resized.
; Parameters:
;   ctrl_list  - ControlID list separated by "|".
;                ControlID can be a control HWND, associated variable name or ClassNN.
;   Attributes - Can be one or more of x/y/w/h  followed by fractions
;   Redraw     - True to redraw controls
; Examples:
;   AutoXYWH("Btn1|Btn2", "xy")
;   AutoXYWH(hEdit      , "w0.5 h0.75")
; ---------------------------------------------------------------------------------
; Release date: 2014-6-25           http://ahkscript.org/boards/viewtopic.php?t=1079
; Author      : tmplinshi (mod by toralf)
; requires AHK version : 1.1.13.01+
; =================================================================================
AutoXYWH(ctrl_list, Attributes="wh", Redraw = False){
    static cInfo := {}
    Loop, Parse, ctrl_list, |
    {
        ctrl := A_Gui ":" A_LoopField
        If ( cInfo[ctrl].x = "" ){
            GuiControlGet, i, %A_Gui%:Pos, %A_LoopField%
            a := RegExReplace(Attributes, "i)[^xywh]")  
            fx := fy := fw := fh := 0
            Loop, Parse, a
                If !RegExMatch(Attributes, "i)" A_LoopField "\s*\K[\d.-]+", f%A_LoopField%)
                  f%A_LoopField% := 1
            cInfo[ctrl] := { x:ix, fx:fx, y:iy, fy:fy, w:iw, fw:fw, h:ih, fh:fh, gw:A_GuiWidth, gh:A_GuiHeight, a:StrSplit(a) }
        }Else If ( cInfo[ctrl].a.1) {
            x := (A_GuiWidth  - cInfo[ctrl].gw) * cInfo[ctrl].fx + cInfo[ctrl].x
            y := (A_GuiHeight - cInfo[ctrl].gh) * cInfo[ctrl].fy + cInfo[ctrl].y
            w := (A_GuiWidth  - cInfo[ctrl].gw) * cInfo[ctrl].fw + cInfo[ctrl].w
            h := (A_GuiHeight - cInfo[ctrl].gh) * cInfo[ctrl].fh + cInfo[ctrl].h
            For i, a in cInfo[ctrl]["a"]
                Options .= a %a% A_Space
            GuiControl, % A_Gui ":" (Redraw ? "MoveDraw" : "Move"), % A_LoopField, % Options
        }
    }
}
Last edited by toralf on 30 Jun 2014, 22:22, edited 4 times in total.
ciao
toralf
User avatar
joedf
Posts: 6502
Joined: 29 Sep 2013, 17:08
Facebook: J0EDF
Google: +joedf
GitHub: joedf
Location: Canada, Quebec
Contact:

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

25 Jun 2014, 15:55

nice mod! :D
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]
guest3456
Posts: 2423
Joined: 09 Oct 2013, 10:31

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

25 Jun 2014, 16:03

can probably use this at the top of scripts requiring later AHK versions:

Code: Select all

if (A_AhkVersion < "1.1.13.01")
   MsgBox, This script/func requires AHK v1.1.13.01 or greater
http://ahkscript.org/docs/Variables.htm#AhkVersion

tmplinshi
Posts: 1269
Joined: 01 Oct 2013, 14:57

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

26 Jun 2014, 06:06

@toralf
Thanks for share. Your version looks much better.
toralf
Posts: 506
Joined: 27 Apr 2014, 21:08
Location: Germany

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

26 Jun 2014, 08:06

Fame is all to you, you started this.

here is a another mod with variadic list. I removed the redraw option.

Code: Select all

; =================================================================================
; Function: AutoXYWH
;   Move and resize control automatically when GUI resizes.
; Parameters:
;   DimSize - Can be one or more of x/y/w/h  [followed by a fraction]
;   cList   - variadic list of ControlIDs separated
;             ControlID can be a control HWND, associated variable name, ClassNN or displayed text.
; Examples:
;   AutoXYWH("xy", "Btn1", "Btn2")
;   AutoXYWH("w0.5 h 0.75", hEdit, "displayed text", "vLabel", "Button1")
; ---------------------------------------------------------------------------------
; Release date: 2014-6-26           http://ahkscript.org/boards/viewtopic.php?t=1079
; Author      : tmplinshi (mod by toralf)
; requires AHK version : 1.1.13.01+
; =================================================================================
AutoXYWH(DimSize, cList*){
    static cInfo := {}
    For i, ctrl in cList {
        ctrlID := A_Gui ":" ctrl
        If ( cInfo[ctrlID].x = "" ){
            GuiControlGet, i, %A_Gui%:Pos, %ctrl%
            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 }
        }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%:MoveDraw, % ctrl, % Options
}    }    }
Last edited by toralf on 30 Jun 2014, 22:23, edited 4 times in total.
ciao
toralf
User avatar
joedf
Posts: 6502
Joined: 29 Sep 2013, 17:08
Facebook: J0EDF
Google: +joedf
GitHub: joedf
Location: Canada, Quebec
Contact:

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

26 Jun 2014, 09:42

Nice! It's shaping!
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]
just me
Posts: 5519
Joined: 02 Oct 2013, 08:51
Location: Germany

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

27 Jun 2014, 07:38

Awesome code! But, since vLabels, ClassNNs, and text are permitted as control identifiers, I suggest to consider the Gui.
toralf
Posts: 506
Joined: 27 Apr 2014, 21:08
Location: Germany

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

27 Jun 2014, 08:00

I was thinking of it too, but GuiControlGet works on the default Gui. I decided to leave it to the user to define a differnt Gui as default

Code: Select all

Gui, GuiName:Default
just before the function is called *not tested*. I assume in most cases this will not be nessecary, because the GuiSize thread will be set it's own Gui as the default. So only in the rare cases that you want to control a second gui size by resizing the first gui you would need to define a different default gui. (do not even know if that would work, since A_GuiWidth and A_GuiHeight would be of the first gui)
Does this makes sense?
Overall, I believe it is not required. Do you agree?
ciao
toralf
just me
Posts: 5519
Joined: 02 Oct 2013, 08:51
Location: Germany

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

27 Jun 2014, 08:48

It's permitted to use the same vLabel and control text in different Guis. Also, ClassNNs like Edit1 or Button1 aren't necessarily unique. But only the first of two or more identical control identifiers will be stored, and possibly used for the wrong Gui. That's what I thought about.
toralf
Posts: 506
Joined: 27 Apr 2014, 21:08
Location: Germany

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

28 Jun 2014, 12:11

Good point. I'll fix it.
ciao
toralf
toralf
Posts: 506
Joined: 27 Apr 2014, 21:08
Location: Germany

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

28 Jun 2014, 20:06

I hope I fixed both of my two functions above. Could not test it yet, I'm only on my phone.
ciao
toralf
just me
Posts: 5519
Joined: 02 Oct 2013, 08:51
Location: Germany

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

30 Jun 2014, 03:21

It's working on A32, U32, and U64.
toralf
Posts: 506
Joined: 27 Apr 2014, 21:08
Location: Germany

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

01 Jul 2014, 14:36

This version removes some of the flickering by reducing the MoveDraw to only controls of class 'Button' (since Groupboxes are of class 'Button').

Code: Select all

AutoXYWH(DimSize, cList*){  ; http://ahkscript.org/boards/viewtopic.php?t=1079
  static cInfo := {}
  If !cInfo[A_Gui].ClassNN.MaxIndex() {
    WinGet, CH, ControlListHwnd, 
    WinGet, CN, ControlList, 
    ACH := StrSplit(CH, "`n"), ACN := StrSplit(CN, "`n")
    Loop, % ACH.MaxIndex()
      If InStr(ACN[A_Index], "Button")   ;GroupBox have a ClassNN of 'Button'
        cInfo[A_Gui , "ClassNN" , ACH[A_Index]] := 1
  }
  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 := cInfo[A_Gui,"ClassNN",Hwnd] ? "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
} } }
ciao
toralf

Return to “Scripts and Functions”

Who is online

Users browsing this forum: TAC109 and 18 guests