I miss A_GuiControl in v1 - How to use the GuiControl.Name in functions now?? Topic is solved

Get help with using AutoHotkey (v2 or newer) and its commands and hotkeys
User avatar
JoakimU
Posts: 12
Joined: 07 Apr 2021, 09:45

I miss A_GuiControl in v1 - How to use the GuiControl.Name in functions now??

03 May 2023, 07:47

Hello, I want to use the same Function for several ThisButton.OnEvent("Click", MyFunction) instead of having a separate function for each button.

The function will then read the received name from the button that called the function, where the function then have different outcome depending on the name or text the last clicked button had. I cannot figure out how to use the GuiControl.Name in AHK v2.

Code: Select all

; A_GuiControl is used in AHK v1 to get the value from the last clicked button - How would I do this in AHK 2 when A_GuiControl is now not existing?
Gui, 1: add, text,X10 y9 ,Several Buttons - using same subroutine:
Gui, 1: add, Button, w80 x10  y+10 vFirst_A_FF7777_Red  gClickButton, Button A
Gui, 1: add, Button, w80 x+10 yp+0 vSecond_B_77FF77_green gClickButton, Button B
Gui, 1: add, Button, w80 x+10 yp+0 vThird_C_B0E0FF_blue  gClickButton, Button C
Gui, 1: add, Button, w80 x+10 yp+0 vFourth_D_F088FF_lilac gClickButton, Button D
Gui, 1: add, Button, w80 x+10 yp+0 vFifth_E_F0F070_yellow  gClickButton, Button E
Gui, 1: Add, Progress, Background202020 x10 y+8 w440 h28  cFFFFFF  vColorBox, 100
Gui, 1: Add, Text, BackgroundTrans x10 yp+3 w440 h28 center vTextinfo, Press a button
Gui, 1: Show
ClickButton:
	{  ; Same subroutine for each button. The v-ID (A_GuiControl) will be split into 4 useful variables.
	Var := StrSplit(A_GuiControl, "_")
	_btn := Var[1]
	_val := Var[2]
	_col := Var[3]
	_cnm := Var[4]
	ButtonFunctions(_btn,_val,_col,_cnm)
	Return
	}
ButtonFunctions(_btn_,_val_,_col_,_cnm_)
	{  ; This is a simple function with 4 local variables.
	Gui, Font, s12 w700,
	GuiControl Font, Textinfo ; 				Update the font in the guicontrol vTextinfo
	GuiControl, +c%_col_%, ColorBox, 100 ; 		set_color on the 100% filled progress bar
	GuiControl, , Textinfo, %_btn_% button (%_val_%) pressed. Color is now %_cnm_%. ; Update the Gui text 
	Return
	}
User avatar
mikeyww
Posts: 27214
Joined: 09 Sep 2014, 18:38

Re: I miss A_GuiControl in v1 - How to use the GuiControl.Name in functions now??  Topic is solved

03 May 2023, 09:19

Hello,

If you have a variable for your v2 GUI object, you can add a name property to it.

Code: Select all

#Requires AutoHotkey v2.0
gui1       := Gui()
btn1       := gui1.AddButton('w230', 'Test')
btn1.Name  := 'b1'
btn1.OnEvent('Click', btn_Click)
gui1.Show

btn_Click(btn, info) {
 MsgBox btn.Name
}
User avatar
JoakimU
Posts: 12
Joined: 07 Apr 2021, 09:45

Re: I miss A_GuiControl in v1 - How to use the GuiControl.Name in functions now??

03 May 2023, 14:57

Thank you mikeyww! You nudged me in the right direction :)

It was the way the function was designed. I was using btn_Click(*) I've been using AHK v1 for 15 years and avoided functions but i'm learning it now.

My goal was to have multiple features on each button (this example a "Name" and a "Path") and several different buttons can use the same function.

To make it understandable for myself, I wrote the function this way: btn_Click(controlType, validProperty)

Code: Select all

#Requires AutoHotkey v2.0
; Variables containing "Name" and Directory separated by a "|"
MyDocs := 'Docs|C:\Users\' A_UserName '\Documents\'
MyPics := 'Pics|C:\Users\' A_UserName '\Pictures\'
MyDLs := 'Downloads|C:\Users\' A_UserName '\Downloads\'
; Gui
gui1       := Gui()
btn1       := gui1.AddButton('w230 v' MyDocs , 'My Docs') ; <--- the Names can be set with the v-option, to make the script shorter.
btn2       := gui1.AddButton('w230 v' MyPics , 'My Pictures')
btn3       := gui1.AddButton('w230 v' MyDLs , 'My Downloads)
btn1.OnEvent('Click', btn_Click)
btn2.OnEvent('Click', btn_Click)
btn3.OnEvent('Click', btn_Click)
gui1.Show

btn_Click(controlType, validProperty) {
       ControlVar := StrSplit(controlType.Name, '|')
       msgbox 'You selected: '  ControlVar[1] '`n`n Opens folder:  ' ControlVar[2]
       run ControlVar[2]
}


User avatar
FanaticGuru
Posts: 1908
Joined: 30 Sep 2013, 22:25

Re: I miss A_GuiControl in v1 - How to use the GuiControl.Name in functions now??

03 May 2023, 19:23

JoakimU wrote:
03 May 2023, 14:57
To make it understandable for myself, I wrote the function this way: btn_Click(controlType, validProperty)

Code: Select all

#Requires AutoHotkey v2.0
; Variables containing "Name" and Directory separated by a "|"
MyDocs := 'Docs|C:\Users\' A_UserName '\Documents\'
MyPics := 'Pics|C:\Users\' A_UserName '\Pictures\'
MyDLs := 'Downloads|C:\Users\' A_UserName '\Downloads\'
; Gui
gui1       := Gui()
btn1       := gui1.AddButton('w230 v' MyDocs , 'My Docs') ; <--- the Names can be set with the v-option, to make the script shorter.
btn2       := gui1.AddButton('w230 v' MyPics , 'My Pictures')
btn3       := gui1.AddButton('w230 v' MyDLs , 'My Downloads)
btn1.OnEvent('Click', btn_Click)
btn2.OnEvent('Click', btn_Click)
btn3.OnEvent('Click', btn_Click)
gui1.Show

btn_Click(controlType, validProperty) {
       ControlVar := StrSplit(controlType.Name, '|')
       msgbox 'You selected: '  ControlVar[1] '`n`n Opens folder:  ' ControlVar[2]
       run ControlVar[2]
}

I would do something like this:

Code: Select all

#Requires AutoHotkey v2.0
; Gui
gui1 := Gui()
gui1.MyDocs := gui1.AddButton('w230', 'My Docs')
gui1.MyPics := gui1.AddButton('w230', 'My Pictures')
gui1.MyDLs := gui1.AddButton('w230', 'My Downloads')
gui1.MyDocs.OnEvent('Click', btn_Click)
gui1.MyPics.OnEvent('Click', btn_Click)
gui1.MyDLs.OnEvent('Click', btn_Click)
gui1.Show

; Variables containing Directory
gui1.MyDocs.Path := 'C:\Users\' A_UserName '\Documents\'
gui1.MyPics.Path := 'C:\Users\' A_UserName '\Pictures\'
gui1.MyDLs.Path := 'C:\Users\' A_UserName '\Downloads\'

btn_Click(GuiCtrlObj, Info) {
	MsgBox 'You selected: ' GuiCtrlObj.Text '`n`n Opens folder:  ' GuiCtrlObj.Path
	Run GuiCtrlObj.Path
}

If you want to condense it some, you can do the OnEvent like this:

Code: Select all

(gui1.MyDocs := gui1.AddButton('w230', 'My Docs')).OnEvent('Click', btn_Click)
(gui1.MyPics := gui1.AddButton('w230', 'My Pictures')).OnEvent('Click', btn_Click)
(gui1.MyDLs := gui1.AddButton('w230', 'My Downloads')).OnEvent('Click', btn_Click)

FG
Hotkey Help - Help Dialog for Currently Running AHK Scripts
AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon
Hotstring Manager - Create and Manage Hotstrings
[Class] WinHook - Create Window Shell Hooks and Window Event Hooks
User avatar
FanaticGuru
Posts: 1908
Joined: 30 Sep 2013, 22:25

Re: I miss A_GuiControl in v1 - How to use the GuiControl.Name in functions now??

03 May 2023, 19:44

The above uses a Gui object to store stuff but just in general I would embrace v2 and objects.

Code: Select all

; I would practically never use a | to store multipe data items in a string
; Better to use an object of some sort
; Like an Array
MyDocs 	:= ['Docs', 'C:\Users\' A_UserName '\Documents\']
MyPics 	:= ['Pics', 'C:\Users\' A_UserName '\Pictures\']
MyDLs := ['Downloads', 'C:\Users\' A_UserName '\Downloads\']
MsgBox MyDocs[1] '`t' MyDocs[2]

; Or better an Object
MyDocs 	:= { Name: 'Docs', Path: 'C:\Users\' A_UserName '\Documents\'}
MyPics 	:= { Name: 'Pics', Path: 'C:\Users\' A_UserName '\Pictures\' }
MyDLs := { Name: 'Downloads', Path: 'C:\Users\' A_UserName '\Downloads\' }
MsgBox MyDocs.Name '`t' MyDocs.Path

; Or even better an array of objects
MyStuff := Array()
MyStuff.Push({ Name: 'Docs', Path: 'C:\Users\' A_UserName '\Documents\'})
MyStuff.Push({ Name: 'Pics', Path: 'C:\Users\' A_UserName '\Pictures\' })
MyStuff.Push({ Name: 'Downloads', Path: 'C:\Users\' A_UserName '\Downloads\' })
For Index, Item in MyStuff
	MsgBox Index '`n' Item.Name '`t' Item.Path

Basically there are three very useful ones for data:
  • Object (the base generic object which uses Properties, Methods, and Values)
  • Array (an extension of base object that uses a numbered Index and Values)
  • Map (an extension of base object that uses mapped pairs of string Keys and Values)

Gui is also a specialized type object.

You can mix and match them, nesting them in a very flexible way.

FG
Hotkey Help - Help Dialog for Currently Running AHK Scripts
AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon
Hotstring Manager - Create and Manage Hotstrings
[Class] WinHook - Create Window Shell Hooks and Window Event Hooks
teadrinker
Posts: 4389
Joined: 29 Mar 2015, 09:41
Contact:

Re: I miss A_GuiControl in v1 - How to use the GuiControl.Name in functions now??

03 May 2023, 20:02

There is no need to create additional properties for the buttons, you can do with the existing functionality:

Code: Select all

wnd := Gui()
wnd.MarginX := wnd.MarginY := 30
wnd.AddButton('vButton1    w90',   'OK'  ).OnEvent('Click', OnClick)
wnd.AddButton('vButton2 yp wp' , 'Cancel').OnEvent('Click', OnClick)
wnd.Show()

OnClick(ctrlObj, *) {
    MsgBox 'name: ' . ctrlObj.name . '`ntext: ' . ctrlObj.text
}
 
FanaticGuru wrote:

Code: Select all

gui1 := Gui()
gui1.MyDocs := gui1.AddButton('w230', 'My Docs')
...
gui1.MyDocs.Path := 'C:\Users\' A_UserName '\Documents\'
Or like this:

Code: Select all

gui1 := Gui()
gui1.AddButton('w230 vMyDocs', 'My Docs').OnEvent('Click', btn_Click.Bind(A_MyDocuments))
gui1.Show()

btn_Click(params*) {
    MsgBox 'name: ' . params[2].name . '`nfolder: ' . params[1]
}
User avatar
JoakimU
Posts: 12
Joined: 07 Apr 2021, 09:45

Re: I miss A_GuiControl in v1 - How to use the GuiControl.Name in functions now??

04 May 2023, 03:22

Many good tips here. Thank you all!

Don't know why I have created my own way of "arrays" by StrSplit:ing variables when arrays and objects was already there :crazy:
Anyway I'll go with Objects in this case.

Having .OnEvent on the same row as the button itself and no need for adding properties to buttons via variables was really a good tip! A One-liner instead of 3 lines.
User avatar
FanaticGuru
Posts: 1908
Joined: 30 Sep 2013, 22:25

Re: I miss A_GuiControl in v1 - How to use the GuiControl.Name in functions now??

04 May 2023, 11:46

teadrinker wrote:
03 May 2023, 20:02
Or like this:

Code: Select all

gui1 := Gui()
gui1.AddButton('w230 vMyDocs', 'My Docs').OnEvent('Click', btn_Click.Bind(A_MyDocuments))
gui1.Show()

btn_Click(params*) {
    MsgBox 'name: ' . params[2].name . '`nfolder: ' . params[1]
}

Yes, Bind is another good tool in the toolbox.

If you don't need a static handle to the gui control for other purposes, you can bind an additional path parameter on to your function like this:

Code: Select all

; Gui
gui1 := Gui()
gui1.AddButton('w230', 'My Docs').OnEvent('Click', btn_Click.Bind('C:\Users\' A_UserName '\Documents\'))
gui1.AddButton('w230', 'My Pictures').OnEvent('Click', btn_Click.Bind('C:\Users\' A_UserName '\Pictures\'))
gui1.AddButton('w230', 'My Downloads').OnEvent('Click', btn_Click.Bind('C:\Users\' A_UserName '\Downloads\'))
gui1.Show

btn_Click(Path, GuiCtrlObj, Info) {
	MsgBox 'You selected: ' GuiCtrlObj.Text '`n`n Opens folder:  ' Path
	Run Path
}
The key principle to these examples is that the OnEvent callback function is automatically going to give you a dynamic handle to the gui control that triggered the event.

FG
Hotkey Help - Help Dialog for Currently Running AHK Scripts
AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon
Hotstring Manager - Create and Manage Hotstrings
[Class] WinHook - Create Window Shell Hooks and Window Event Hooks
User avatar
mikeyww
Posts: 27214
Joined: 09 Sep 2014, 18:38

Re: I miss A_GuiControl in v1 - How to use the GuiControl.Name in functions now??

04 May 2023, 11:56

That's a nice one for buttons, though might not work as well for every type of control in every circumstance-- dynamically changing values and so on.

Return to “Ask for Help (v2)”

Who is online

Users browsing this forum: Google [Bot], niCode, ntepa, TAC109 and 50 guests