Page 1 of 1

How do I make Gui Control Objects?

Posted: 28 Feb 2023, 02:53
by blue_fields
Hi Everyone,

I'm having trouble understanding the v2 reference documentation for creating gui control objects. Basically I just want to make a GUI with text where when some action occurs, like clicking a button or moving a mouse to a certain area on the screen, the text will change color or maybe change into a new message. I have successfully used the ControlSetText function to change the text, but I think I need to use Gui Control Objects to change other properties of the text. Here's my code currently:

Code: Select all

MyGui := Gui()
MyGui.SetFont("s12")
MyText := MyGui.Add("Text", "x10 y10", "Initial GUI text")
MyButton := MyGui.Add("Button", "x10 y50", "Click me!")
MyButton.OnEvent("Click", MyButton_Click)
MyGui.Show("Center")

MyButton_Click(*) {  
    ControlSetText("New button text", MyText)
}
How could I, for example, change the text colour to green (#00FF00) when I click the button?

Re: How do I make Gui Control Objects?  Topic is solved

Posted: 28 Feb 2023, 03:55
by neogna2
There are several ways to do it.

When you use OnEvent the callback function will pass along parameters.
https://www.autohotkey.com/docs/v2/lib/GuiOnEvent.htm#Click
Ctrl_Click(GuiCtrlObj, Info)
The first parameter is the gui control object that was clicked. In your case MyButton.
Once you have that object you can access its properties to get the gui object and from there get the text control and change its value

Code: Select all

MyButton_Click(CtlObj, *) {  
  CtlObj.Gui["text"].Value := "new text"
}
An alternative in this case is to use the MyText variable to access the control object. That's possible because you created the control object in the global context (auto execute section). Which enables you to access it directly inside the function. (If you had created the control object inside another function you'd have to declare it global there for this to work.)

Code: Select all

MyButton_Click(*) {  
  MyText.Value := "new text"
}
To change the text color use the SetFont method
https://www.autohotkey.com/docs/v2/lib/GuiControl.htm#SetFont
MyText.SetFont("cRed")
or
CtlObj.Gui["text"].SetFont("cRed")

Re: How do I make Gui Control Objects?

Posted: 28 Feb 2023, 03:58
by autoexec
MyText.Opt("c00FF00")

Re: How do I make Gui Control Objects?

Posted: 28 Feb 2023, 12:12
by blue_fields
tysm this was extremely helpful.

Could you tell more about specifically the Gui["text"] element here? What is this exactly and why does it work?

Code: Select all

CtlObj.Gui["text"].Value := "new text"

Re: How do I make Gui Control Objects?

Posted: 28 Feb 2023, 13:49
by swagfag
huh, didnt even know this was a feature. apparently u can pass the same kind of windowText string ud use in a call to WinExist(..., 'the_windows_text_to_look_for') to Gui::__Item and it will perform the lookup with lowest priority, obeying whatever SetTitleMatchMode settings are in effect for that particular calling thread
  1. https://github.com/AutoHotkey/AutoHotkey/blob/27a2d5f2ae392c9d2cf2ef1a2f136659831749b8/source/script_gui.cpp#L390
  2. https://github.com/AutoHotkey/AutoHotkey/blob/27a2d5f2ae392c9d2cf2ef1a2f136659831749b8/source/script_gui.cpp#L7937-L7938
not sure why 10 different ways of looking up AHK controls need to exist, but what do i know

Re: How do I make Gui Control Objects?

Posted: 28 Feb 2023, 14:44
by kczx3
swagfag wrote:
28 Feb 2023, 13:49
not sure why 10 different ways of looking up AHK controls need to exist, but what do i know
Agreed but oh well.

Re: How do I make Gui Control Objects?

Posted: 28 Feb 2023, 15:04
by neogna2
blue_fields wrote:
28 Feb 2023, 12:12
Could you tell more about specifically the Gui["text"] element here? What is this exactly and why does it work?
Each gui control object has methods and properties and the property Gui retrieves the control's parent GUI window object.
So to get a control's parent Gui object we can do MyGui := CtlObj.Gui

Each Gui also has methods and properties and in this case we use property __Item which "retrieves the GuiControl object associated with the specified name, text, ClassNN or HWND." The syntax is MyGui[Name]

Now, my earlier post mistakenly assumed that the string "text" in Gui["text"] retrieved the control because it is a text control, but I was mistaken (misremembered the syntax). It really only worked because the content of the control contained the string "text" in this particular case. Sorry about that confusion.

To really match against the type of control we could instead use classNN "Static1" like this Gui["Static1"]
(Check the text control with WindowSpy and you'll see that it shows as "Static1"). But that can get messy if there's multiple text controls in one gui (Static1, Static2, ...).

A less messy way is to name the control and then later use that name to access the control
MyGui.Add("Text", "vSomeName", "Initial GUI text")
MyGui["SomeName"].Value := "new text"


I guess the other approach of using a variable to name and later retrieve the gui control is more popular though
MyText := MyGui.Add("Text", "", "Initial GUI text")
MyText.Value := "new text"

Re: How do I make Gui Control Objects?

Posted: 28 Feb 2023, 20:16
by blue_fields
thanks again, really appreciate the info here