AHK v2 GUI parser

Get help with using AutoHotkey (v2 or newer) and its commands and hotkeys
MannyKSoSo
Posts: 440
Joined: 28 Apr 2018, 21:59

AHK v2 GUI parser

Post by MannyKSoSo » 24 Apr 2019, 08:57

Hello, I am currently following the development of the AHK v2 and I have been slowly working on a way to take an xml data and turn it into a GUI. I have the basics down, but I am running into some problems. The first thing is that functions that are created I can't really access what the current values are inside the controls (and it doesn't really work with some of the more advanced controls). This is what I have so far

Code: Select all

obj := new XMLGui("data.xml", "Hello")
obj.Create()
;Gui_Close()
Return

Gui_Close() {
	ExitApp
}

NewFunction(this) {
	MsgBox("Value Changed! " this.Text)
}

class XMLGui {
	__New(FileName, GuiName) {
		this.GuiName := GuiName
		this.data := FileRead(FileName)
		this.doc := this.LoadXML(this.data)
	}
	LoadXML(ByRef data) {
		o := ComObjCreate("MSXML2.DOMDocument.6.0"),o.setProperty("SelectionLanguage", "XPath")
		o.async := false
		o.loadXML(data)
		if (o.parseError.errorCode!=0) {
		  msgbox("can't load dom " o.parseError.reason " on line " o.parseError.line)
		}
		return o
	}
	Create() {
		Global
		this.GuiName := GuiCreate()
		Total := this.doc.selectNodes("//MainGui/Control").length
		Loop Total {
			If (this.doc.selectSingleNode("//MainGui/Control[" A_Index "]/Options").text ~= "v\w+") {
				Options := this.doc.selectSingleNode("//MainGui/Control[" A_Index "]/Options").text
				RegExMatch(this.doc.selectSingleNode("//MainGui/Control[" A_Index "]/Options").text, "v\K\w+", Match), Varaible := Match.0
				%Varaible% := this.GuiName.Add(this.doc.selectSingleNode("//MainGui/Control[" A_Index "]/Type").text, Options, this.doc.selectSingleNode("//MainGui/Control[" A_Index "]/Text").text)
			} Else {
				this.GuiName.Add(this.doc.selectSingleNode("//MainGui/Control[" A_Index "]/Type").text, this.doc.selectSingleNode("//MainGui/Control[" A_Index "]/Options").text, this.doc.selectSingleNode("//MainGui/Control[" A_Index "]/Text").text)
			}
			If (this.doc.selectSingleNode("//MainGui/Control[" A_Index "]/OnEvent").text != "") {
				Events := StrSplit(this.doc.selectSingleNode("//MainGui/Control[" A_Index "]/OnEvent").text, ",")
				%Varaible%.OnEvent(Events[1], Events[2])
			}
		}
		this.GuiName.Show()
	}
}
The above also contains the class that creates the gui since I figured a class would be the most efficient way of creating the gui.
Here is the structure of xml (This structure can change depending on what needs to be done with the class)

Code: Select all

<MainGui>
    <Control>
		<Type>Text</Type>
		<Options></Options>
		<Text>This is a test control</Text>
		<OnEvent></OnEvent>
	</Control>
	<Control>
		<Type>Text</Type>
		<Options></Options>
		<Text>This is another test control</Text>
		<OnEvent></OnEvent>
	</Control>
	<Control>
		<Type>Edit</Type>
		<Options>vNewText</Options>
		<Text>This is the original text that will be changed</Text>
		<OnEvent>Change,NewFunction</OnEvent>
	</Control>
</MainGui>
My hope is that with an xml (or json if people are so inclined) that you can contain all your gui information (maybe even multiple) to make it easier for larger gui's and clean up your main code so it only contains the functions. Any help/suggestions are welcome.

Edit-1: Fixed code so values would show. Current code below works, but still looking to expand functionality
Spoiler
Last edited by MannyKSoSo on 24 Apr 2019, 09:11, edited 1 time in total.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: AHK v2 GUI parser

Post by Helgef » 24 Apr 2019, 09:10

The v-option is not for creating variables, it is for naming controls, you can also assign to the name property. I do not know why this prefix was kept.

I do not think assuming global and doing %var% := ... is the way to go. Minor note, you (consistently) misspelled Variable as Varaible.

Cheers.
MannyKSoSo
Posts: 440
Joined: 28 Apr 2018, 21:59

Re: AHK v2 GUI parser

Post by MannyKSoSo » 24 Apr 2019, 09:23

I have taken most of your notes into consideration. I have fixed the spelling and removed the global from the class. It was originally in there from some older example. As for the v-option it is supposed to use that as similar to this FakeLink := Gui.Add("Text", "", "Click here to launch Google.") so you can use that as the control for getting and setting values, but since I was getting errors I moved to using the this statement instead.
MannyKSoSo
Posts: 440
Joined: 28 Apr 2018, 21:59

Re: AHK v2 GUI parser

Post by MannyKSoSo » 26 Apr 2019, 14:57

One problem I am getting is with line %Varaible% := this.GuiName.Add(this.doc.selectSingleNode("//MainGui/Control[" A_Index "]/Type").text, Options, this.doc.selectSingleNode("//MainGui/Control[" A_Index "]/Text").text) as even if it is global I cannot get the value if I call it. Says there is an object error.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: AHK v2 GUI parser

Post by Helgef » 27 Apr 2019, 09:40

I cannot get the value if I call it
What do you mean by calling it? Controls cannot be called.

Is the XMLGui instance supposed to have any function after you call Create()? If not, you could just call it in __new and return the GuiObject instead. Then, if the user wants to access one of the controls it can just do myControlObj := myGui.control['myControlName'].

Cheers.
MannyKSoSo
Posts: 440
Joined: 28 Apr 2018, 21:59

Re: AHK v2 GUI parser

Post by MannyKSoSo » 29 Apr 2019, 08:28

What I mean is when you use a statement like so FakeLink := Gui.Add("Text", "", "Click here to launch Google.") This allows you to have a variable set up so you can access everything about that control. This is why in the Create() method contains the %Variable% so it can be access in that way. At the current moment it doesn't (since I haven't needed more extension). As for returning the GuiObject I am confused on how to do this. When I use Return this.GuiName := this.Create() It does return the Gui Object, but when I try calling parts of the gui it doesn't very much like it.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: AHK v2 GUI parser

Post by Helgef » 29 Apr 2019, 12:51

you do:

Code: Select all

__new(){
	; all the stuff you do now
	; and then:
	this.create()
	return this.guiName ; which is a wired choice of "variable" name
}
then you do myGuiObj := new XMLGui("data.xml", "Hello"), or

Code: Select all

create(){
	; all the stuff
	; ...
	return this.guiName
}
in either case I do not think you should show the gui in create()

Cheers.
User avatar
tank
Posts: 3130
Joined: 28 Sep 2013, 22:15
Location: CarrolltonTX
Contact:

Re: AHK v2 GUI parser

Post by tank » 29 Apr 2019, 13:14

sounds like an ahk implementation of xforms there is in fact a w3c standard for it you might try model
We are troubled on every side‚ yet not distressed; we are perplexed‚
but not in despair; Persecuted‚ but not forsaken; cast down‚ but not destroyed;
Telegram is the best way to reach me
https://t.me/ttnnkkrr
If you have forum suggestions please submit a
Check Out WebWriter
MannyKSoSo
Posts: 440
Joined: 28 Apr 2018, 21:59

Re: AHK v2 GUI parser

Post by MannyKSoSo » 29 Apr 2019, 14:38

@Helgef Indeed that worked. I used global in front of myGuiObj so I could access it in all my functions (but that is just me)
@tank Interesting I will take a look at it. My main goal for the whole thing is to make it so all gui information could be contained within another file (and not clutter the main work space with all the gui calls).

Moving on to another question, I know this is possible

Code: Select all

myGuiObj.Destroy()
myGuiObj := ""
myGuiObj := myGuiObj.Create()
myGuiObj.Show()
This will remove the old gui and replace it with a new one, but would it be possible to add it as part of the class (maybe even set up a hotkey) so you can reload the gui if you made changes to your xml file. In this case specifically it would help to speed up the process of making a gui by hand or if the end user is editing the xml file per what the user is doing.
Post Reply

Return to “Ask for Help (v2)”