Page 1 of 1

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

Posted: 16 Sep 2021, 17:48
by AHK_user
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

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

Posted: 16 Sep 2021, 18:10
by swagfag
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

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

Posted: 17 Sep 2021, 15:07
by AHK_user
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


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

Posted: 19 Sep 2021, 00:36
by vmech
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 ?

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

Posted: 19 Sep 2021, 10:16
by AHK_user
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

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

Posted: 19 Sep 2021, 14:35
by safetycar
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. ;)

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

Posted: 19 Sep 2021, 14:48
by safetycar
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.

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

Posted: 20 Sep 2021, 05:31
by AHK_user
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)
}

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

Posted: 20 Sep 2021, 08:42
by kczx3
I think the error you're seeing is pretty self-explanatory. You can't jump to a label in a different scope.

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

Posted: 20 Sep 2021, 09:06
by safetycar
@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

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

Posted: 21 Sep 2021, 14:32
by AHK_user
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.

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

Posted: 21 Sep 2021, 14:40
by safetycar
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.