Gui Onevent - is it possible to use the Goto function?

Get help with using AutoHotkey (v2 or newer) and its commands and hotkeys
AHK_user
Posts: 515
Joined: 04 Dec 2015, 14:52
Location: Belgium

Gui Onevent - is it possible to use the Goto function?

Post by AHK_user » 16 Sep 2021, 17:48

Currently, the onEvent asks a function to fire if the event is raised, not a label.

Is it possible to cheat and use the Goto function to force a label activation?
Goto.Bind("ButtonOK") and (*) => Goto("ButtonOK") does not seem to work...

I know that this is not the best practice, but I am currently working on the convertor and it is the easiest to try to mimic the V1 way of work to avoid other complications.

Code: Select all

myGui := Gui()
ogcButtonOK := myGui.Add("Button", , "OK")
ogcButtonOK.OnEvent("Click", Goto.Bind("ButtonOK"))  ; xm puts it at the bottom left corner.
myGui.Show()
return

ButtonOK:
{ ; V1toV2: Added bracket
oSaved := myGui.Submit()  ; Save each control's contents to its associated variable.
MsgBox("test")
ExitApp

} ; Added bracket in the end
swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: Gui Onevent - is it possible to use the Goto function?

Post by swagfag » 16 Sep 2021, 18:10

goto is a keyword(with special syntax rules). u can forget about using it

why dont u just do this instead?

Code: Select all

myGui := Gui()
ogcButtonOK := myGui.Add("Button", , "OK")
ogcButtonOK.OnEvent("Click", ButtonOK)  ; xm puts it at the bottom left corner.
myGui.Show()
return

ButtonOK(*)
{ ; V1toV2: Added bracket
global
oSaved := myGui.Submit()  ; Save each control's contents to its associated variable.
MsgBox("test")
ExitApp

} ; Added bracket in the end
AHK_user
Posts: 515
Joined: 04 Dec 2015, 14:52
Location: Belgium

Re: Gui Onevent - is it possible to use the Goto function?

Post by AHK_user » 17 Sep 2021, 15:07

I indeed started to do it like that, but As A_GuiEvent is used a lot, I started to include it by binding it to the function.
This works with a lot of convertions, but it is bad practice for clean code, as v2 has superior methods.
But in cases where one label is used for multiple events, this could become possible complex... :crazy: :crazy: :crazy:

And I haven`t taken into account that in V1, it is also possible to call functions if the glabel does not exist, those functions should be converted to a (*) parameter.
Maybe it is a better idea to try to set global variables like A_GuiEvent before calling the function. is it possible to do that inside the onevent line?

Because a label does not work the same as a function, there are some situations that are hard to convert, certainly if a label is used inside another label.

As V2 gui works on a whole different way, it is not easy to convert complex scripts. But it is already interesting to be able to convert the simple code and accept that you need to correct the handling a little bit...

Below an example of a conversion where it goes wrong, but it is suprising how good it already works:

V1 code

Code: Select all

Gui, Add, Text,, Pick a file to launch from the list below.`nTo cancel, press ESCAPE or close this window.
Gui, Add, ListBox, vMyListBox gMyListBox w640 r10
Gui, Add, Button, Default, OK
Loop, C:\*.*  ; Change this folder and wildcard pattern to suit your preferences.
{
    GuiControl,, MyListBox, %A_LoopFileFullPath%
}
Gui, Show
return

MyListBox:
if (A_GuiEvent != "DoubleClick")
    return
; Otherwise, the user double-clicked a list item, so treat that the same as pressing OK.
; So fall through to the next label.
ButtonOK:
GuiControlGet, MyListBox  ; Retrieve the ListBox's current selection.
MsgBox, 4,, Would you like to launch the file or document below?`n`n%MyListBox%
IfMsgBox, No
    return
; Otherwise, try to launch it:
Run, %MyListBox%,, UseErrorLevel
if (ErrorLevel = "ERROR")
    MsgBox Could not launch the specified file. Perhaps it is not associated with anything.
return

GuiClose:
GuiEscape:
ExitApp
v2 code:

Code: Select all

myGui := Gui()
myGui.OnEvent("Close", GuiClose)
myGui.OnEvent("Escape", GuiClose)
myGui.Add("Text", , "Pick a file to launch from the list below.`nTo cancel, press ESCAPE or close this window.")
ogcMyListBox := myGui.Add("ListBox", "vMyListBox  w640 r10")
ogcMyListBox.OnEvent("DoubleClick", MyListBox.Bind("DoubleClick"))
ogcButtonOK := myGui.Add("Button", "Default", "OK")
ogcButtonOK.OnEvent("Click", ButtonOK.Bind("Normal"))
Loop Files, "C:\*.*"  ; Change this folder and wildcard pattern to suit your preferences.
{
    ogcMyListBox.Add([A_LoopFilePath])
}
myGui.Show()
return

MyListBox(A_GuiEvent, GuiCtrlObj, Info, *)
{ ; V1toV2: Added bracket
if (A_GuiEvent != "DoubleClick")
    return
} ; V1toV2: Added Bracket before label
; Otherwise, the user double-clicked a list item, so treat that the same as pressing OK.
; So fall through to the next label.
ButtonOK(A_GuiEvent, GuiCtrlObj, Info, *)
{ ; V1toV2: Added bracket
MyListBox := ogcMyListBox.Text  ; Retrieve the ListBox's current selection.
msgResult := MsgBox("Would you like to launch the file or document below?`n`n" MyListBox, , 4)
if (msgResult = "No")
    return
; Otherwise, try to launch it:
{   ErrorLevel := "ERROR"
   Try ErrorLevel := Run(MyListBox, , "", )
}
if (ErrorLevel = "ERROR")
    msgResult := MsgBox("Could not launch the specified file. Perhaps it is not associated with anything.")
return
} ; V1toV2: Added bracket before function

GuiClose(*)
{ ; V1toV2: Added bracket
GuiEscape:
ExitApp

} ; Added bracket in the end

vmech
Posts: 343
Joined: 25 Aug 2019, 13:03

Re: Gui Onevent - is it possible to use the Goto function?

Post by vmech » 19 Sep 2021, 00:36

If you bind custom parameter values for calls functions then why you use A_GuiEvent as first functions parameter ?
Also, why you dont unite both functions into shared one ?
Please place your script code into [code][/code] block. Thank you.
AHK_user
Posts: 515
Joined: 04 Dec 2015, 14:52
Location: Belgium

Re: Gui Onevent - is it possible to use the Goto function?

Post by AHK_user » 19 Sep 2021, 10:16

vmech wrote:
19 Sep 2021, 00:36
If you bind custom parameter values for calls functions then why you use A_GuiEvent as first functions parameter ?
Also, why you dont unite both functions into shared one ?
A_GuiEvent is removed in V2, so it needs to be set in one way or another.
But I suppose that It would be better to set some variables like A_GuiEvent as global.

Feel free to propose a solution, but keep in mind, I want to convert this automatically and it should work preferably for the most scripts.

This is the github of the convertor:
https://github.com/mmikeww/AHK-v2-script-converter
safetycar
Posts: 435
Joined: 12 Aug 2017, 04:27

Re: Gui Onevent - is it possible to use the Goto function?

Post by safetycar » 19 Sep 2021, 14:35

I don't know exactly what you have thought so far.
But for the converter you are also going to find functions in the old shape lilke:

Code: Select all

CtrlEvent(CtrlHwnd, GuiEvent, EventInfo, ErrLevel:="")
(https://www.autohotkey.com/docs/commands/Gui.htm#Events)
I guess you don't want to adapt those functions differently from labels so it's probably better to make labels have that old structure too (even if sounds a bit bad thinking from outside of the converter).
Once you know the name of the function, some lines could be inserted as the first line of the function, containing declarations like A_GuiEvent := GuiEvent.

Code: Select all

ogcMyListBox := myGui.Add("ListBox", "vMyListBox  w640 r10")
_GuiCtrlOnEventTransitionHelper(ogcMyListBox, glabel_extracted_from_ogcMyListBox)

; Maybe at the end of the script:
_GuiCtrlOnEventTransitionHelper(v2ctrl, v1func) {
	SupportByType := {} ; Would have to be filled.
	for _,EventName in SupportByType[v2ctrl.Type]
		v2ctrl.OnEvent(EventName, ReroutePrimary(EventName, v1func))
	ReroutePrimary(Ev, Func) {
		GuiEvent := Ev
		OriginalFunc := Func
		return RerouteSecondary
		RerouteSecondary(GuiCtrlObj, Info, unused*) {
			CtrlHwnd := GuiCtrlObj.Hwnd
			EventInfo := Info
			OriginalFunc(CtrlHwnd, GuiEvent, EventInfo)
		}
	}
}
Then with gui window events would be quite similar. Maybe inserting some first lines like this...

Code: Select all

GuiSize(GuiHwnd, EventInfo, Width, Height) {
    WinGetPos(&A_GuiX, &A_GuiY, &A_GuiWidth, &A_GuiHeight, "ahk_id " GuiHwnd)
}
Etc... but you know, talking is a bit different than doing it. ;)
safetycar
Posts: 435
Joined: 12 Aug 2017, 04:27

Re: Gui Onevent - is it possible to use the Goto function?

Post by safetycar » 19 Sep 2021, 14:48

Although I'm also thinking now that A_GuiX and the like might be better converted into a function call (A_Gui(Hwnd)?) wrapping WinGetPos somehow.
But maybe it's a bit too much? I don't know.
AHK_user
Posts: 515
Joined: 04 Dec 2015, 14:52
Location: Belgium

Re: Gui Onevent - is it possible to use the Goto function?

Post by AHK_user » 20 Sep 2021, 05:31

Maybe it is the best to split the conversion, if it points to a function, we can do it one way, if it is a label, we try another way.
For the label conversion, I am getting the error "Label not found in current scope.". is this fixable?
The method is to create a function that sets global variables and uses a goto to go to the label.

AHK V2:

Code: Select all

myGui := Gui()
myGui.OnEvent("Close", GuiClose)
myGui.OnEvent("Escape", GuiClose)
myGui.Add("Text", , "Pick a file to launch from the list below.`nTo cancel, press ESCAPE or close this window.")
ogcMyListBox := myGui.Add("ListBox", "vMyListBox  w640 r10")
ogcMyListBox.OnEvent("DoubleClick", (*) => GoToV2('MyListBox','DoubleClick'))
ogcButtonOK := myGui.Add("Button", "Default", "OK")
ogcButtonOK.OnEvent("Click", ButtonOK.Bind("Normal"))
Loop Files, "C:\*.*"  ; Change this folder and wildcard pattern to suit your preferences.
{
    ogcMyListBox.Add([A_LoopFilePath])
}
myGui.Show()
return

MyListBox:
{ ; V1toV2: Added bracket
if (A_GuiEvent != "DoubleClick")
    return
} ; V1toV2: Added Bracket before label
; Otherwise, the user double-clicked a list item, so treat that the same as pressing OK.
; So fall through to the next label.
ButtonOK(A_GuiEvent, GuiCtrlObj, Info, *)
{ ; V1toV2: Added bracket
MyListBox := ogcMyListBox.Text  ; Retrieve the ListBox's current selection.
msgResult := MsgBox("Would you like to launch the file or document below?`n`n" MyListBox, , 4)
if (msgResult = "No")
    return
; Otherwise, try to launch it:
{   ErrorLevel := "ERROR"
   Try ErrorLevel := Run(MyListBox, , "", )
}
if (ErrorLevel = "ERROR")
    msgResult := MsgBox("Could not launch the specified file. Perhaps it is not associated with anything.")
return
} ; V1toV2: Added bracket before function

GuiClose(*)
{ ; V1toV2: Added bracket
GuiEscape:
ExitApp

} ; Added bracket in the end


GoToV2(label,GuiEvent){
   Global A_GuiEvent
   A_GuiEvent := GuiEvent
   GoTo(Label)
}
User avatar
kczx3
Posts: 1640
Joined: 06 Oct 2015, 21:39

Re: Gui Onevent - is it possible to use the Goto function?

Post by kczx3 » 20 Sep 2021, 08:42

I think the error you're seeing is pretty self-explanatory. You can't jump to a label in a different scope.
safetycar
Posts: 435
Joined: 12 Aug 2017, 04:27

Re: Gui Onevent - is it possible to use the Goto function?

Post by safetycar » 20 Sep 2021, 09:06

@AHK_user I don't know if the scope error is fixable in some other way but I think you can get what you want by using functions like.

Change this

Code: Select all

MyListBox:
{ ; V1toV2: Added bracket
; the rest
To this:

Code: Select all

MyListBox()
{ ; V1toV2: Added bracket
global
; the rest
(Notice the line with "global")

And where you have now the GoTo(Label) you call it like %label%() (well it wouldn't be a label anymore but you get it.)

Edit: Sorry I think I'm repeating on what @swagfag said
AHK_user
Posts: 515
Joined: 04 Dec 2015, 14:52
Location: Belgium

Re: Gui Onevent - is it possible to use the Goto function?

Post by AHK_user » 21 Sep 2021, 14:32

safetycar wrote:
20 Sep 2021, 09:06
@AHK_user I don't know if the scope error is fixable in some other way but I think you can get what you want by using functions like.

Change this

Code: Select all

MyListBox:
{ ; V1toV2: Added bracket
; the rest
To this:

Code: Select all

MyListBox()
{ ; V1toV2: Added bracket
global
; the rest
(Notice the line with "global")

And where you have now the GoTo(Label) you call it like %label%() (well it wouldn't be a label anymore but you get it.)

Edit: Sorry I think I'm repeating on what @swagfag said
This would indeed work, exept if there is a label inside another label... This is the reason why I was wondering if it would`t be possible to set some global variables and keep using labels to be as close to the original code.
safetycar
Posts: 435
Joined: 12 Aug 2017, 04:27

Re: Gui Onevent - is it possible to use the Goto function?

Post by safetycar » 21 Sep 2021, 14:40

AHK_user wrote:
21 Sep 2021, 14:32
This would indeed work, exept if there is a label inside another label... This is the reason why I was wondering if it would`t be possible to set some global variables and keep using labels to be as close to the original code.
Not sure about that situation. I've never tried it and I'm not sure how common is that type of case.
Post Reply

Return to “Ask for Help (v2)”