How to pass variables into Gui's callback function and how to terminate another function within one function? Topic is solved

Get help with using AutoHotkey (v2 or newer) and its commands and hotkeys
Kodakku
Posts: 6
Joined: 06 May 2023, 19:35

How to pass variables into Gui's callback function and how to terminate another function within one function?

06 May 2024, 23:54

Hello everyone.

Since I’m not a programmer, I don’t understand a lot of the content in the programming manual. Could you please teach me with simple examples?

First question: How to pass variables into Gui's callback function?

I do not want to redefine the variables cfgFileDir and cfgArrRB inside the saveRbIni function. How to pass the variables cfgFileDir and cfgArrRB into the saveRbIni function?

My configuration file is named "text.ini" and has the following content:

Code: Select all

[RB]
bp = 6
lv75 = 7
lv50 = 5
lv35 = 2
lv20 = 2
lv1 = 2
My script is as follows:

Code: Select all

SetWorkingDir(A_ScriptDir)
#SingleInstance Force
CoordMode("Pixel", "Window")
SetTitleMatchMode("RegEx")
^!v::
{
    cfgRead(fileDir, section, arr) {
        for key in arr
            RBGui[key].value := IniRead(fileDir, section, key)
    }
    cfgSave(guiObj, fileDir, section, arr) {
        for key in arr {
            guiValue := guiObj[key].value
            if (guiValue != IniRead(fileDir, section, key)) {
                IniWrite(guiValue, fileDir, section, key)
            }
        }
    }
    cfgFileDir := "text.ini"
    cfgArrRB := ["bp", "lv75", "lv50", "lv35", "lv20", "lv1"]

    RBGui := Gui("AlwaysOnTop Resize", "test")
    RBGui.Add("GroupBox", "h195 w180", "RB_Cfg")
    RBGui.Add("Text", "XM+5 YM+20", "BP")
    RBGui.Add("Edit", "w30 h17 XP+110 YP-2")
    RBGui.Add("UpDown", "vbp Range0-6 Wrap", 2)
    RBGui.Add("Text", "XM+5 YM+45", "Lv.75")
    RBGui.Add("Edit", "w30 h17 XP+110 YP-2")
    RBGui.Add("UpDown", "vlv75 Range0-7 Wrap", 6)
    RBGui.Add("Text", "XM+5 YM+70", "Lv.50")
    RBGui.Add("Edit", "w30 h17 XP+110 YP-2")
    RBGui.Add("UpDown", "vlv50 Range0-7 Wrap", 5)
    RBGui.Add("Text", "XM+5 YM+95", "Lv.35")
    RBGui.Add("Edit", "w30 h17 XP+110 YP-2")
    RBGui.Add("UpDown", "vlv35 Range0-7 Wrap", 2)
    RBGui.Add("Text", "XM+5 YM+120", "Lv.20")
    RBGui.Add("Edit", "w30 h17 XP+110 YP-2")
    RBGui.Add("UpDown", "vlv20 Range0-7 Wrap", 2)
    RBGui.Add("Text", "XM+5 YM+145", "Lv.1")
    RBGui.Add("Edit", "w30 h17 XP+110 YP-2")
    RBGui.Add("UpDown", "vlv1 Range0-7 Wrap", 2)
    RBGui.Add("Button", "default XM+110 YM+165", "OK").OnEvent("Click", rbFunc)
    RBGui.Add("Button", "-default XM+10 YM+165", "Save_Cfg").OnEvent("Click", saveRbIni)
    cfgRead(cfgFileDir, "RB", cfgArrRB)
    RBGui.Show()

    saveRbIni(*) {
        cfgFileDir := "text.ini"
        cfgArrRB := ["bp", "lv75", "lv50", "lv35", "lv20", "lv1"]
        cfgSave(RBGui, cfgFileDir, "RB", cfgArrRB)
    }

    rbFunc(*) {
        Saved := RBGui.Submit()
        RBGui.Destroy()
        ; ...
    }
}

Second question: How to terminate another function within one function?

Start the autoFunc and errFind functions. The autoFunc function contains multiple color judgment operations within a lot of loops. Regardless of where the autoFunc function is currently running, how can I terminate the autoFunc function and continue to the next iteration when the errFind function detects an error?

Code: Select all

^!c::
{
    autoFunc() {
        ; ...
        loop {
            Sleep(1000)
            if (1 = 1) {
                break
            }
        }
        loop {
            Sleep(1000)
            if (2 = 2) {
                break
            }
        }
        ; ...
        loop {
            Sleep(1000)
            if (9999 = 9999) {
                break
            }
        }
    }

    errFind(a, b, c) {
        ; ...
        SetTimer(() => errFind(a, b, c), -10000)
    }

    a := 1, b := 2, c := 3

    errFind(a, b, c)
    loop {
        autoFunc()
    }
}
User avatar
boiler
Posts: 17188
Joined: 21 Dec 2014, 02:44

Re: How to pass variables into Gui's callback function and how to terminate another function within one function?

07 May 2024, 02:48

Kodakku wrote: Hello everyone.
Could you please teach me with simple examples?

First question: How to pass variables into Gui's callback function?
Example:

Code: Select all

#Requires AutoHotkey v2.0
bp := 6
MyGui := Gui()
MyGui.Add('Button', 'w100 h60', 'Go').OnEvent('Click', MyFunc.Bind(bp))
MyGui.Show

MyFunc(val, *) {
	MsgBox 'The passed value is ' val
}

Kodakku wrote: Second question: How to terminate another function within one function?

Regardless of where the autoFunc function is currently running, how can I terminate the autoFunc function and continue to the next iteration when the errFind function detects an error?
Here is an example of terminating anywhere within a function when an error is encountered. Perhaps you can adapt that to your case.

Code: Select all

#Requires AutoHotkey v2.0
MyFunc

MyFunc(*) {
	Try {
		MsgBox 'Hello'
		WinActivate 'Non-existent window'
		MsgBox 'This will not display'
	}
	Catch
		return
}
Kodakku
Posts: 6
Joined: 06 May 2023, 19:35

Re: How to pass variables into Gui's callback function and how to terminate another function within one function?

09 May 2024, 04:51

boiler wrote:
07 May 2024, 02:48
Example:

Code: Select all

#Requires AutoHotkey v2.0
bp := 6
MyGui := Gui()
MyGui.Add('Button', 'w100 h60', 'Go').OnEvent('Click', MyFunc.Bind(bp))
MyGui.Show

MyFunc(val, *) {
	MsgBox 'The passed value is ' val
}

Thank you, I solved it using BoundFunc.
Are there other methods? I don’t understand "An "event sink", or object to bind events to. If EventObj is specified, OnEvent, OnNotify and OnCommand can be used to register methods of EventObj to be called when an event is raised.", and I didn’t find any examples. It seems that I can pass in an object, so I can also assign variables to the properties of the object, and then call it?
Is the syntax of AutoHotkey similar to C or C++? I think I should learn a programming language similar to AutoHotkey first…

boiler wrote:
07 May 2024, 02:48
Here is an example of terminating anywhere within a function when an error is encountered. Perhaps you can adapt that to your case.

Code: Select all

#Requires AutoHotkey v2.0
MyFunc

MyFunc(*) {
	Try {
		MsgBox 'Hello'
		WinActivate 'Non-existent window'
		MsgBox 'This will not display'
	}
	Catch
		return
}

The autoFunc function will never throw an error (so the try function cannot catch errors), but it may not be able to exit the loop due to unsuccessful color finding (only successful color finding will exit this loop). So, I want to terminate the autoFunc function through the errFind function (get the current situation of unsuccessful color finding through color finding).
User avatar
boiler
Posts: 17188
Joined: 21 Dec 2014, 02:44

Re: How to pass variables into Gui's callback function and how to terminate another function within one function?

09 May 2024, 05:45

Kodakku wrote: Are there other methods? I don’t understand "An "event sink", or object to bind events to. If EventObj is specified, OnEvent, OnNotify and OnCommand can be used to register methods of EventObj to be called when an event is raised.", and I didn’t find any examples. It seems that I can pass in an object, so I can also assign variables to the properties of the object, and then call it?
No, the EventObj wouldn’t contain just properties. It would need to contain methods (like functions in a class object), so that those could be registered to be called by your events instead of functions. I don’t see a reason why you need to consider using that approach, especially since you apparently are not using class objects yet. For what reason would you want to use another approach than registering functions to be called by your events?

Kodakku wrote: Is the syntax of AutoHotkey similar to C or C++? I think I should learn a programming language similar to AutoHotkey first…
I suppose the syntax regarding objects in C++ is similar enough to AHK in that if you learned that, the objects in AHK would make more sense to you, and it always helps to know another language, especially one like C++, but if your goal is just to learn AHK better, that seems to be a very inefficient way of doing it. I would just spend more time learning about objects in AHK, especially class objects if you think you need/want to understand that better.

Kodakku wrote: The autoFunc function will never throw an error (so the try function cannot catch errors), but it may not be able to exit the loop due to unsuccessful color finding (only successful color finding will exit this loop). So, I want to terminate the autoFunc function through the errFind function (get the current situation of unsuccessful color finding through color finding).
Maybe someone will be able to suggest exactly how to accomplish that.
Kodakku
Posts: 6
Joined: 06 May 2023, 19:35

Re: How to pass variables into Gui's callback function and how to terminate another function within one function?

12 May 2024, 06:23

boiler wrote:
09 May 2024, 05:45
No, the EventObj wouldn’t contain just properties. It would need to contain methods (like functions in a class object), so that those could be registered to be called by your events instead of functions. I don’t see a reason why you need to consider using that approach, especially since you apparently are not using class objects yet. For what reason would you want to use another approach than registering functions to be called by your events?

Sorry, I realized that my previous idea was problematic.
I want to modify the value (number, string, boolean) of a variable outside the callback function through the callback function, but it seems that this problem cannot be solved by BoundFunc (only by declaring the variable as a global variable inside the callback function, but in this way, all these variables have to be declared as global variables).
In addition, I don’t know how to register the method of an object for an event (for example, writing OnEvent(“Click”, obj.Method) will throw an error), so I want to ask…

boiler wrote:
09 May 2024, 05:45
I suppose the syntax regarding objects in C++ is similar enough to AHK in that if you learned that, the objects in AHK would make more sense to you, and it always helps to know another language, especially one like C++, but if your goal is just to learn AHK better, that seems to be a very inefficient way of doing it. I would just spend more time learning about objects in AHK, especially class objects if you think you need/want to understand that better.

I think the AHK manual is aimed at people with some programming foundation. Some parts of the manual are a bit difficult for me to understand (no offense to the manual authors, it’s because I don’t know programming). I also want to learn other programming languages, write some programs myself (such as presetting some formulas to calculate experimental data, automatically decompressing the compressed packages in the compressed package, and automatically creating a new folder to download files according to the download url), and learn to select hardware. At present, it seems that many non-programmers are learning Python, and Python programming seems to be the simplest (the least number of statements but need to learn many libraries). After learning C, i could choose hardware (but C does not support object-oriented programming), C++ supports object-oriented programming. Many people have opposite views on whether to learn C or C++. Of course, a small number of people think that both should be learned. I want to choose a language as the foundation, hoping to learn it and then i can get twice the result with half the effort learning other languages.

boiler wrote:
09 May 2024, 05:45
Maybe someone will be able to suggest exactly how to accomplish that.

At present, I solve this problem through a global variable err. When the errFind function finds an error, it modifies the value of err. Every loop of the autoFunc function will check the value of err to determine whether to exit the function. But it’s troublesome to add judgment for every loop, so I don’t know if I can modify the loop to check the value of err before each loop.
User avatar
boiler
Posts: 17188
Joined: 21 Dec 2014, 02:44

Re: How to pass variables into Gui's callback function and how to terminate another function within one function?  Topic is solved

12 May 2024, 08:10

Kodakku wrote: I don’t know how to register the method of an object for an event (for example, writing OnEvent(“Click”, obj.Method) will throw an error)
That is the proper way (except for using curly quotes instead of straight quotes). You must have made some other mistake, such as not instantiating the class or not allowing the method to receive (or ignore using *) the parameter that would be sent to it. Demonstration:

Code: Select all

#Requires AutoHotkey v2.0
MC := MyClass()
MyGui := Gui()
MyGui.Add('Button', 'w150 h50', 'Click me').OnEvent('Click', MC.MyMethod)
MyGui.Show

class MyClass {
	MyMethod(*) {
		MsgBox 'Hello'
	}
}
Kodakku
Posts: 6
Joined: 06 May 2023, 19:35

Re: How to pass variables into Gui's callback function and how to terminate another function within one function?

13 May 2024, 18:52

boiler wrote:
12 May 2024, 08:10

Code: Select all

#Requires AutoHotkey v2.0
MC := MyClass()
MyGui := Gui()
MyGui.Add('Button', 'w150 h50', 'Click me').OnEvent('Click', MC.MyMethod)
MyGui.Show

class MyClass {
	MyMethod(*) {
		MsgBox 'Hello'
	}
}
Thank you! :D
I indeed did not write * in the parameter list of the method in the class.

Return to “Ask for Help (v2)”

Who is online

Users browsing this forum: cunningwolf, User-AutoHotkey and 29 guests