Static variables for GUI control associated variables?

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User avatar
Scoox
Posts: 125
Joined: 11 May 2014, 09:12
Location: China

Static variables for GUI control associated variables?

18 Sep 2018, 16:57

I''m working on a script which contains several GUIs each having many controls. I don't want to use global variables for control associated variables, instead I'd like to use static variables, but I can't fathom how I should go about it.

I would like to have different functions to perform different tasks:

GuiMainLoad() ;Adds controls to GUI etc
GuiMainShow() ;Shows/hides GUI
GuiMainEvents() ;takes care of control events (gLabel)

GuiMainLoad() is responsible for creating all the GUI controls and so their respective associated variables must be defined as static variables within GuiMainLoad(), but then GuiMainEvents() has no awareness of those static variables because they live in a different function, so what's the use of static variables here?

The only solution I could think of is to put everything inside one multi-purpose function that does different things depending on the parameters passed, but it seems too convoluted:

Code: Select all

#NoEnv
#SingleInstance Force

Global Action_Load := 1
Global Action_Show := 2

GuiMainLoad()
GuiAuxLoad()

GuiMainShow()
GuiAuxShow()

Return

Gui_Main(Action := 0)
{
	Static

	Gui, Main:Default
	If (Action = Action_Init)
	{
		Gui, Font, s16
		Gui, Add, Edit, vEdit gGui_Main x10 y10 w200 , hello world
		Gui, Add, Button, vMyButton1 gGui_Main x10 y50 w200 h40, Button 1
		Gui, Add, Button, vMyButton2 gGui_Main x10 y100 w200 h40, Button 2
		Gui, +AlwaysOnTop
	}
	Else If (Action = Action_Show)
	{
		Gui, Show,, MAIN
	}
	Else ;Control actions (Action = 0)
	{
		If (A_GuiControl = "MyButton1")
		{
			Tooltip You pressed Button 1 on MAIN
		}
		Else If (A_GuiControl = "MyButton2")
		{
			Tooltip You pressed Button 2 on MAIN
		}
		Else If (A_GuiControl = "MyEdit")
		{
			Tooltip You are typing text in Edit box on MAIN
		}
	}
}

Gui_Aux(Action := 0)
{
	Static

	Gui, Aux:Default
	If (Action = Action_Init)
	{
		Gui, Font, s16
		Gui, Add, Edit, vMyEdit gGui_Aux x10 y10 w200 , hello world
		Gui, Add, Button, vMyButton1 gGui_Aux x10 y50 w200 h40, Button 1
		Gui, Add, Button, vMyButton2 gGui_Aux x10 y100 w200 h40, Button 2
		Gui, +AlwaysOnTop
	}
	Else If (Action = Action_Show)
	{
		Gui, Show,, AUX
	}
	Else ;Control actions (Action = 0)
	{
		If (A_GuiControl = "MyButton1")
		{
			Tooltip You pressed Button 1 on AUX
		}
		Else If (A_GuiControl = "MyButton2")
		{
			Tooltip You pressed Button 2 on AUX
		}
		Else If (A_GuiControl = "MyEdit")
		{
			Tooltip You are typing text in Edit box on AUX
		}
	}
}

GuiMainInit()
{
	Gui_Main(Action_Init)
}

GuiMainShow()
{
	Gui_Main(Action_Show)
}

GuiAuxInit()
{
	Gui_Aux(Action_Init)
}

GuiAuxShow()
{
	Gui_Aux(Action_Show)
}
Is there a proper way to do this? Thanks :)
wolf_II
Posts: 2688
Joined: 08 Feb 2015, 20:55

Re: Static variables for GUI control associated variables?

18 Sep 2018, 18:03

Try this:

Code: Select all

#NoEnv
#SingleInstance Force

GuiMainCreate() ; create with statics
GuiMainCreate()
{
	Static
	Gui, Main: New, +AlwaysOnTop, MAIN
    Gui, Font, s16
    Gui, Add, Edit, vEdit gMain_onTyping x10 y10 w200, hello world
    Gui, Add, Button, vMyButton1 x10 y50 w200 h40, 1
    Gui, Add, Button, vMyButton2 x10 y100 w200 h40, 2
}

GuiAUXCreate() ; create with statics
GuiAUXCreate()
{
	Static
	Gui, Aux: New, +AlwaysOnTop, AUX
    Gui, Font, s16
    Gui, Add, Edit, vMyEdit gAUX_onTyping x10 y10 w200, hello world
    Gui, Add, Button, vMyButton1 x10 y50 w200 h40, 1
    Gui, Add, Button, vMyButton2 x10 y100 w200 h40, 2
}
;-------------------------------------------------------------------------------
Gui, Main: Show
Gui, AUX: Show
Return

MainButton1:
    Tooltip You pressed button "1" on MAIN
Return

MainButton2:
    Tooltip You pressed button "2" on MAIN
Return

Main_onTyping:
    Tooltip You are typing text in Edit box on MAIN
Return

AUXButton1:
    Tooltip You pressed button "1" on AUX
Return

AUXButton2:
    Tooltip You pressed button "2" on AUX
Return

AUX_onTyping:
    Tooltip You are typing text in Edit box on AUX
Return


/*
	}
	Else ; Control actions (Action = 0)
	{
		If (A_GuiControl = "MyButton1")
		{
		}
		Else If (A_GuiControl = "MyButton2")
		{
		}
		Else If (A_GuiControl = "MyEdit")
		{
		}
	}

Gui_Aux(Action := 0)

	If (Action = Action_Init)
	{
	}
	Else If (Action = Action_Show)
	{
		Gui, Show
	}
	Else ;Control actions (Action = 0)
	{
		If (A_GuiControl = "MyButton1")
		{
		}
		Else If (A_GuiControl = "MyButton2")
		{
		}
		Else If (A_GuiControl = "MyEdit")
		{

		}
	}

GuiMainInit()
{
	Gui_Main(Action_Init)
}

GuiMainShow()
{
	Gui_Main(Action_Show)
}

GuiAuxInit()
{
	Gui_Aux(Action_Init)
}

GuiAuxShow()
{
	Gui_Aux(Action_Show)
}
I hope that helps.
User avatar
kczx3
Posts: 1640
Joined: 06 Oct 2015, 21:39

Re: Static variables for GUI control associated variables?

18 Sep 2018, 20:58

a great use case for classes or moving to use AHK v2 and the object oriented GUI structure
wolf_II
Posts: 2688
Joined: 08 Feb 2015, 20:55

Re: Static variables for GUI control associated variables?

18 Sep 2018, 22:11

Thanks for inspiration :D

Code: Select all

#NoEnv
#SingleInstance Force

    MainGui := new GUI("Main")
    AUXGui := new GUI("AUX")
    MainGui.Show(50, 50)
    AUXGui.Show(300, 50)

MsgBox
ExitApp



;===============================================================================
class GUI { ; object oriented GUI structure
;===============================================================================
    __New(Name) { ; constructor
        static
        this.Name := Name

        Gui, % this.Name ":New",, %Name%
        Gui, Font, s16
		Gui, Add, Edit, HWNDhEdit w200, Hello, World!
		onTyping := this.Edit_onTyping.Bind(this)
		GuiControl +g, %hEdit%, % onTyping
        Gui, Add, Button, HWNDhButton1 wp hp, 1
        Gui, Add, Button, HWNDhButton2 wp hp, 2
		onClick := this.Button_onClick.Bind(this)
		GuiControl +g, %hButton2%, % onClick
		GuiControl +g, %hButton1%, % onClick
    }

    __Delete() {
        Gui, % this.Name ":Destroy"
    }

    Show(x := "Center", y := "Center") {
        Gui, % this.Name ":Show", x%x% y%y%
    }

    Edit_onTyping() {
        Tooltip, % "You are typing text in Edit box on " this.Name
    }

    Button_onClick() {
        Tooltip, % "You pressed button " A_GuiControl " on " this.Name
    }
}
User avatar
Scoox
Posts: 125
Joined: 11 May 2014, 09:12
Location: China

Re: Static variables for GUI control associated variables?

19 Sep 2018, 03:33

@wolf_II I will try that in a bit, I'm also very much looking forward to AHK v2... I even gave AutoIT a go recently but AHK was more suited to what I'm trying to do because (AutoIT's mouse support is pretty bad).

The code in your first post works but only because the functions don't need to read or write the control associated variable. The following doesn't work, for instance:

Code: Select all

AUXButton2()
{
	Gui, Aux:Default
	GuiControl,, MyEdit, Blah blah blah
}
Variable MyEdit remains local to the function GuiAUXCreate().
User avatar
Scoox
Posts: 125
Joined: 11 May 2014, 09:12
Location: China

Re: Static variables for GUI control associated variables?

19 Sep 2018, 05:53

Using the object oriented GUI version doesn't work either. None of the class methods is able to change, say, the text in the edit control, because it's associated variable scope is limited to the constructor method. Unless I'm missing something.

What I need, ideally, is a variable that's visible to all class members but not outside the class.
swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: Static variables for GUI control associated variables?

19 Sep 2018, 06:19

Code: Select all

#NoEnv
#SingleInstance Force

main := new MainGui()
main.show()
aux := new AuxGui()
aux.show()

Esc::ExitApp

class BaseGui
{
	__New(title) {
		Gui, New, +AlwaysOnTop +HwndhGui, % title
		this.hGui := hGui

		Gui, Font, s16
		
		Gui, Add, Edit, x10 y10 w200 +HwndhEdit, hello world
		this.hEdit := hEdit

		Gui, Add, Button, x10 y50 w200 h40 +HwndhBtn1, Button 1
		this.hBtn1 := hBtn1
		
		Gui, Add, Button, x10 y100 w200 h40 +HwndhBtn2, Button 2
		this.hBtn2 := hBtn2
		return

		GuiClose:
			ExitApp
		return
	}

	__Delete() {
		Gui % this.hGui ": Destroy"
	}

	show() {
		Gui % this.hGui ": Show"
	}

}	

class MainGui extends BaseGui
{
	__New() {
		base.__New("Main")

		fn := ObjBindMethod(this, "edit")
		GuiControl +g, % this.hEdit, % fn
		fn := ObjBindMethod(this, "btn1")
		GuiControl +g, % this.hBtn1, % fn
		fn := ObjBindMethod(this, "btn2")
		GuiControl +g, % this.hBtn2, % fn
	}

	edit(hwnd, event, info) {
		GuiControlGet contents, , % hwnd

		Tooltip You typed "%contents%" in Edit box on MAIN
	}

	btn1(hwnd, event, info) {
		Tooltip You pressed Button 1 on MAIN
	}

	btn2(hwnd, event, info) {
		Tooltip You pressed Button 2 on MAIN
	}
}

class AuxGui extends BaseGui
{
	__New() {
		base.__New("Aux")

		fn := ObjBindMethod(this, "edit")
		GuiControl +g, % this.hEdit, % fn
		fn := ObjBindMethod(this, "btn1")
		GuiControl +g, % this.hBtn1, % fn
		fn := ObjBindMethod(this, "btn2")
		GuiControl +g, % this.hBtn2, % fn
	}

	edit(hwnd, event, info) {
		Tooltip You are typing text in Edit box on AUX
	}

	btn1(hwnd, event, info) {
		Tooltip You pressed Button 1 on AUX
	}

	btn2(hwnd, event, info) {
		Tooltip You pressed Button 2 on AUX
	}
}


User avatar
Scoox
Posts: 125
Joined: 11 May 2014, 09:12
Location: China

Re: Static variables for GUI control associated variables?

19 Sep 2018, 06:35

@swagfag thanks a lot! I manged to do what I'm trying to do using your code but it was by fluke. I'm going to have to do some reading before I can understand what's going on. Things are looking up :)
wolf_II
Posts: 2688
Joined: 08 Feb 2015, 20:55

Re: Static variables for GUI control associated variables?

19 Sep 2018, 07:51

The code in your first post works but only because the functions don't need to read or write the control associated variable.
The code also works because no part of the script has asked to read anything yet.

Please patch as desired, example:

Code: Select all

    Edit_onTyping(HWND) {
        GuiControlGet, outVar,, %HWND%
        Tooltip, % "You are typing @" outVar "@ in Edit box on " this.Title
    }
User avatar
Scoox
Posts: 125
Joined: 11 May 2014, 09:12
Location: China

Re: Static variables for GUI control associated variables?

19 Sep 2018, 07:53

wolf_II wrote:
The code in your first post works but only because the functions don't need to read or write the control associated variable.
The code also works because no part of the script has asked to read anything yet.

Please patch as desired, example:

Code: Select all

    Edit_onTyping(HWND) {
        GuiControlGet, outVar,, %HWND%
        Tooltip, % "You are typing @" outVar "@ in Edit box on " this.Title
    }
Thanks, I'm studying the code now and reading through the classes section of the help. I see that the trick is to use "this." and the control's HWND. It's definitely going to work, really happy about this :D
User
Posts: 407
Joined: 26 Jun 2017, 08:12

Re: Static variables for GUI control associated variables?

19 Sep 2018, 16:46

Is the code below of any use for you?

Image

Code: Select all

GuiNew("1", "x" a_ScreenWidth/2 - 275)
GuiNew("2")
GuiNew("Lala", "x" a_ScreenWidth/2 + 100)
return

GuiNewFunctionButtons:	;_____________ GuiNewFunction Buttons __________________

msgbox, % "Button  ''" a_guicontrol "'' from Window ''" A_gui "'' `r`n`r`nPress ''ok'' to continue!"

if (a_guicontrol = "Get Edit")
{
guicontrolget, TextFound, , % GuiNew("CtrlHwnd", "Win" A_Gui "Edit")
msgbox, % TextFound
}

if (a_guicontrol = "Set Edit")
{
guicontrol, , % GuiNew("CtrlHwnd", "Win" A_Gui "Edit"), % a_gui "-" a_gui "-" a_gui "-" a_gui
}

if (a_guicontrol = "New Window")
{
guicontrolget, TextFound, , % GuiNew("CtrlHwnd", "Win" A_Gui "Edit")
GuiNew(TextFound, "y" a_screenheight/2 + 30)
}

return

GuiNewFunctionClose:	;__________ GuiNewFunction Close _____________

msgbox, % "Gui Window = " a_gui "`r`n`r`nPress ''ok'' to exit App!"

exitapp

return


GuiNew(Name, WinOptions := "")		;___________ Gui New (Function) ______________
{
Static CtrlHwnd := []

if (Name = "CtrlHwnd")
return, CtrlHwnd[WinOptions]

gui, %Name%:Default 
gui, destroy

gui, +LabelGuiNewFunction

gui, add, edit, w150 +HwndTempControlId, % "Edit from ''" Name "'' Window"  

CtrlHwnd["Win" Name "Edit"] := TempControlId

gui, add, Button, gGuiNewFunctionButtons, Get Edit
gui, add, Button, gGuiNewFunctionButtons, Set Edit

gui, add, Button, gGuiNewFunctionButtons, New Window

gui, add, text, , Type the new window name `r`nin the "Edit" box (Example: x)

gui, show, % WinOptions " h200", % Name

}
User
Posts: 407
Joined: 26 Jun 2017, 08:12

Re: Static variables for GUI control associated variables?

19 Sep 2018, 17:15

In the example code below, "y()" function gets values from static vars\objects of "x()" function, without using "Global" declarations at all! (You could use this work around to solve your problem!)

Code: Select all

x()

y()


x(Options := "", O := "", K := "")	;________ x Function ___________
{
Static Test := [], Car

if (Options = "GetVar")
return, (%O%)

if (Options = "GetObject")
return, %O%[K]

Car := "x Function Car is xXx"

Test[1] := "x Function 111"
Test[2] := "x Function 222"
Test[3] := "x Function 333"
}

y()	;________ y Function ___________
{
msgbox, % ""
. x("GetVar", "Car") "`n"
. x("GetObject", "Test", 1)  "`n"
. x("GetObject", "Test", 2)  "`n"
. x("GetObject", "Test", 3)  "`n"
}
User avatar
Scoox
Posts: 125
Joined: 11 May 2014, 09:12
Location: China

Re: Static variables for GUI control associated variables?

19 Sep 2018, 18:31

Thanks @User, some of the mechanisms used in your implementation are similar to my initial idea, but now that I know about classes I think I much prefer classes, they seem much more flexible.
User avatar
Scoox
Posts: 125
Joined: 11 May 2014, 09:12
Location: China

Re: Static variables for GUI control associated variables?

19 Sep 2018, 18:38

swagfag wrote:

Code: Select all

class BaseGui
{
	__New(title) {
		Gui, New, +AlwaysOnTop +HwndhGui, % title
		this.hGui := hGui

		Gui, Font, s16
		
		Gui, Add, Edit, x10 y10 w200 +HwndhEdit, hello world
		this.hEdit := hEdit

		Gui, Add, Button, x10 y50 w200 h40 +HwndhBtn1, Button 1
		this.hBtn1 := hBtn1
		
		Gui, Add, Button, x10 y100 w200 h40 +HwndhBtn2, Button 2
		this.hBtn2 := hBtn2
		return

		GuiClose:
			ExitApp
		return
	}

	__Delete() {
		Gui % this.hGui ": Destroy"
	}

	show() {
		Gui % this.hGui ": Show"
	}

}
I have a couple of questions about GuiClose:

1) Can this label be jumped to from outside the class? Does it need to be unique? e.g. <gui_name>GuiClose (in cases where more than one GUI exists)

2) The more important question: Is there any way I can use a function/method instead of a label?
User avatar
kczx3
Posts: 1640
Joined: 06 Oct 2015, 21:39

Re: Static variables for GUI control associated variables?

19 Sep 2018, 19:53

I think the label can be jumped to from outside the class but not positive.

Yes, it can be a function but not a method. v2 gives you much more options for this.
User
Posts: 407
Joined: 26 Jun 2017, 08:12

Re: Static variables for GUI control associated variables?

19 Sep 2018, 20:30

Scoox wrote:Thanks @User, some of the mechanisms used in your implementation are similar to my initial idea, but now that I know about classes I think I much prefer classes, they seem much more flexible.
I think that "function" would save you a lot of headaches instead "Class"!

But anyway, remember that "Class" is just an object, defining "Class Gui{ }" means that "Gui" variable will contain the reference of a class object!

So, "Gui" variable could be easily overwritten, for example, by functions ByRef parameters, or in case you use something like Gui := "New String", etc, etc, etc, which means that the "Gui" variable will no longer contain the reference of the class object once assigned to it! (to make things worse, a variable that contains class object is automatically made a super global var, which means that it could be easily overwritten by functions!)

Basically, what I want to say is, use something like "Class __Gui{ }" or longer names or whatever!

Good luck with Classes!
swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: Static variables for GUI control associated variables?

20 Sep 2018, 03:44

Scoox wrote:I have a couple of questions about GuiClose:
1) Can this label be jumped to from outside the class? Does it need to be unique? e.g. <gui_name>GuiClose (in cases where more than one GUI exists)
2) The more important question: Is there any way I can use a function/method instead of a label?
i was actually wondering that myself, but couldnt figure out a way to make it work as a method
User wrote:So, "Gui" variable could be easily overwritten, for example, by functions ByRef parameters, or in case you use something like Gui := "New String", etc, etc, etc, which means that the "Gui" variable will no longer contain the reference of the class object once assigned to it! (to make things worse, a variable that contains class object is automatically made a super global var, which means that it could be easily overwritten by functions!)
use #Warn, ClassOverwrite. in v2 ull get an exception the next time u try to instantiate something either way, so meh..
User
Posts: 407
Joined: 26 Jun 2017, 08:12

Re: Static variables for GUI control associated variables?

20 Sep 2018, 08:53

swagfag wrote: so meh..
meh? meh meh? meh meh meh? meh meh meh meh meh?

Haha, are you a goat or something?

meh meh meh meh meh meh meh meh meh meh meh meh meh meh meh meh meh meh meh meh meh ...!
A_AhkUser
Posts: 1147
Joined: 06 Mar 2017, 16:18
Location: France
Contact:

Re: Static variables for GUI control associated variables?

23 Sep 2018, 08:58

swagfag wrote:
Scoox wrote:I have a couple of questions about GuiClose:
1) Can this label be jumped to from outside the class? Does it need to be unique? e.g. <gui_name>GuiClose (in cases where more than one GUI exists)
2) The more important question: Is there any way I can use a function/method instead of a label?
i was actually wondering that myself, but couldnt figure out a way to make it work as a method
See GuiSize Function inside Class Not Executing (especially Helgef's sample code for an example on how using methods instead of a labels)

Cheers.
my scripts
wolf_II
Posts: 2688
Joined: 08 Feb 2015, 20:55

Re: Static variables for GUI control associated variables?

23 Sep 2018, 12:25

@all: I'm following this and prepare for v2, learning classes along the way.

I managed the GuiSize, thx. How exactly do you handle GuiClose() inside the class, if the function is outside? Do you use OnMessage?
OnMessage(0x10, Func("GuiClose").Bind(this.Handle)) ; WM_CLOSE does not work for me, same as all other attempts.

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: RussF, Spawnova and 136 guests