Jump to content


Photo

Object based GUI creation and automatically saving values.


  • Please log in to reply
3 replies to this topic

#1 maestrith

maestrith
  • Members
  • 406 posts

Posted 19 June 2012 - 12:22 AM

This script only works with AHK_L.

I know it is not much but I am working on a way to make it so that not only can you design a GUI but all of the values that are either selected (radios, checkboxes...etc) or edit fields are kept track of easily. I have yet to work on Listviews or Treeviews but I figured I would share what I have.
#Singleinstance,Force
gui()
gui(){
 window({title:"Object GUI Test",position:"W300 h700",options:"+resize",number:5
 ,Gui:["Text,x0 y0,Text value","Edit,vFirst w300 -Multi r1,Change this value"
 ,"Edit,w300 -Multi r1 x0 vSecond,Change this value"
 ,"ListBox,vlistbox h200 choose2,First Entry Test|First Entry|Second Entry"
 ,"Radio,vradio,Radio button"
 ,"Radio,vradio1,Radio button 2"
 ,"Checkbox,vcheck,Checkbox"
 ,"DDL,vddl,First|Second|Third"
 ,"ComboBox,vcombo,First|Second"
 ,"Hotkey,vhotkey,F1"
 ,"Tab,vtab,One|Two|Three"
 ,"Button,,1"
 ,"Tab,2,1"
 ,"Button,,2"
 ,"Tab,3,1"
 ,"Button,,3"
 ,""  ;same as Gui,Tab
 ,"Button,gsaveall Default,Save Settings"]}) ;this can be all in one line if you like but I broke it up to make it easy to read
 window({title:"Second window",position:"AutoSize",options:"+owner5",number:4
 ,Gui:["Edit,vFirst,Change this as well"
 ,"Button,gsave Default,Save settings"]})
 window({number:5,add:1,position:"AutoSize"
 ,Gui:["Text,,Text value","Edit,vThird w300 -Multi r1,Change this value","Edit,vfourt w300 -Multi r1,Change this value"]}) ;how to add controls after creation
}
misc(){
 saveall:
 save:
 sw:=A_ThisLabel="save"?A_Gui:""
 win:=window(),value:=window({var:1})
 for a in win
 for b,c in win[a]{
  if sw && a!=sw
  continue
  ControlGet,list,list,,,% "ahk_id" c.hwnd
  v:=value[a,b],list:=RegExReplace(list,"`n","|"),list:=InStr(list,v)?list:list "|" v
  if c.var="ComboBox"{
   sort,list,D|
   xadd("Options","Gui" a "/" b,{list:list},v)
   GuiControl,%a%:,% c.hwnd,% "|" list
   ControlGet,choose,FindString,%v%,,% "ahk_id " c.hwnd
   GuiControl,%a%:Choose,% c.hwnd,%choose%
  }
  xadd("Options","Gui" a "/" b,"",v)
 }
 xsave()
 GuiControlGet,out,focusv
 if win[A_Gui,out].var="ComboBox"
 return
 for a in value
 for b,c in value[a]
 if sw && a!=sw
 continue
 else
 total.="Window number " a " Variable " b " = " c "`n"
 msgbox % total "`n`n and a single entery of " value[4,"First"] "`nthis will reload to show that they are saved."
 reload
 return
 5GuiEscape:
 5GuiClose:
 exitapp
 return
}
load_settings(number){
 Gui,%Number%:Default
 sleep,0
 xml("Options","Options","Options.xml"),settings:=xget("Options").selectnodes("//Gui" number "/*"),win:=window()
 while,control:=settings.item[A_Index-1].nodename,setting:=settings.item[A_Index-1].Text,hwnd:=win[number,control].hwnd{
  if regexmatch(con:=win[number,Control].var,"i)(ListBox|DDL|DropDownList|ComboBox|Tab|tab2)"){
   sleep,0 ;not sure why, but it is needed.
   if win[number,Control].var = "ComboBox"
   GuiControl,%number%:,%hwnd%,% "|" settings.item[a_index-1].selectsinglenode("@list").text
   ControlGet,choose,FindString,%setting%,,% "ahk_id" hwnd
   if choose
   GuiControl,%number%:Choose,%hwnd%,%choose%
   else
   GuiControl,%number%:Choose,%hwnd%,%setting%
  }
  else if setting
  GuiControl,%number%:,%hwnd%,%setting%
 }
}
window(win=""){
 static
 static window:=[],option:=""
 for a,b in win
 %a%:=b
 if !win
 return window
 if win.var{
  temp:=[]
  for a in window{
   Gui,%a%:Submit,NoHide
   for b,c in window[a]{
    temp[a,b]:=%b%
   }
  }
  return temp
 }
 if !win.add
 Gui,%number%:Destroy
 Gui,%Number%:Default
 if win.options
 Gui,%number%:%options%
 for a,b in Gui{
  RegExMatch(b,"(.*),(.*),(.*)",c),RegExMatch(c2,"U)\bv(.*)\b",var)
  if (c2+1&&(c1="Tab"||c1="Tab2")){
   Gui,%number%:Tab,%c2%,%c3%
   continue
  }
  if !c1
  Gui,%Number%:Tab
  else
  Gui,%number%:Add,%c1%,%c2% hwndout,%c3%
  if var1
  window[number,var1]:={var:c1,hwnd:out,text:c3}
  c2:=c3:=""
 }
 gui,%number%:show,%position%,%title% 
 load_settings(number)
}
f1::
for a in win:=window()
for b,c in win[a]
msgbox % b "   " c
return
xml(ref="",root="",file=""){
 static documents:=[]
 if !ref
 return documents
 file:=file?file:ref ".xml"
 if !documents[ref]{
  doc:=ComObjCreate("MSXML2.DOMDocument"),doc.setProperty("SelectionLanguage","XPath")
  ifexist %file%
  doc.load(file)
  else
  xml:=doc.createelement(root),doc.appendchild(xml)
  documents[ref]:={xml:doc,file:file,root:root}
 }
 return documents[ref]
}
xsave(){
 for a,b in xml()
 b.xml.transformNodeToObject(style(),b.xml),b.xml.save(b.file)
}
style(){
 xsl := ComObjCreate("MSXML2.DOMDocument")
 style =
 (
 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="xml" indent="yes" encoding="UTF-8"/>
 <xsl:template match="@*|node()">
 <xsl:copy>
 <xsl:apply-templates select="@*|node()"/>
 </xsl:copy>
 </xsl:template>
 </xsl:stylesheet>
 )
 xsl.loadXML(style), style:=null
 return xsl
}
xadd(ref,path,value,text="",duplicate=""){
 doc:=xml(ref).xml,batch:=[],currentpath:=xml(ref).root
 StringSplit,path,path,/
 edit:=doc.selectsinglenode("//" path)
 if (edit=""||duplicate){
  check:=doc.SelectSingleNode("//" path)?1:0
  Loop,Parse,path,/
  last:=currentpath,bool:=doc.SelectSingleNode(currentpath.="/" A_LoopField)?1:0,batch[A_Index]:={name:A_LoopField,exist:bool,last:last}
  for a,b in batch
  if !b.Exist
  edit:=doc.selectsinglenode(b.last),xml:=doc.createelement(b.name),edit.appendchild(xml)
  edit:=doc.SelectSingleNode(b.last "/" b.name)
 }
 if duplicate&&check=1
 dup:=doc.SelectSingleNode(batch[path0]last),xml:=doc.CreateElement(path%path0%),dup.AppendChild(xml),edit:=xml
 if IsObject(value)
 for a,b in value
 edit.setattribute(a,b)
 else
 edit.text:=value
 if Text
 edit.text:=Text
}
xget(doc,xpath="",attribute=""){
 xml:=xml(doc).xml
 if !xpath
 return xml
 data:=xml.selectsinglenode("//" xpath)
 if attribute
 return data.selectsinglenode("@" attribute).text
 return data.text
}
This is nowhere near complete but it has the basic layout for creating controls and windows and then by giving your controls variables it will keep track of them, and save whatever values they may have in them.

Please keep in mind that Listviews and Treeviews (along with others I am sure) are not yet supported. It will take some time to work out how to save the structures of a LV but I am really not looking forward to the TV. Let me know if anything is broken.

This is not intended, although you could use it for, single GUI programs with a few things to keep track of. It is more for complex multiple control/variables and settings.

Let me know what you think :)

Update:
Changed the way that the xml is saved to allow for the multiple windows and the ability to re-use variable names in separate windows.
Added the ability to add controls to a window after they are created and have those values saved as well.
Changing the g-label from save to saveall in a gui will change weather it saves just that gui where the button is, or all of them.

#2 dylan904

dylan904
  • Members
  • 706 posts

Posted 19 June 2012 - 03:57 AM

As a simple example, you may try something like this as well 8)
Gui, Add, Edit, vEdit
Gui, Add, CheckBox, vCheck, Choose
Gui, Add, Button, gSubmit, Submit
Gui, Show
return

OK:
Gui, 2: Submit
Return

submit:
DynamicCheck()
return

DynamicCheck()
{
    global outcomes
    Gui, 2: Destroy
    HWND := WinExist()
    Gui, 2: Add, ListView, vOutcomes, Control Name|Value|Hidden 
    Gui, 2: ListView, Outcomes
    Gui, 2: Add, Button, gOK, OK
    WinGet, 2Cons, ControlList, ahk_id %HWND%
    StringSplit, ConSplit, 2Cons, `n,`r
    Loop, %ConSplit0% {
        Gui, 1:Default
        GuiControlGet, Contents,, % ConSplit%A_Index%, ahk_id %HWND%
        If InStr(ConSplit%A_Index%, "Button")
        {
            If Contents is not number
            break
        }
        ControlGet, HidCon, Visible,, % ConSplit%A_Index%, ahk_id %HWND%
        HidCon := (HidCon) ? "No" : "Yes"
        Gui, 2:Default
        LV_Add("", ConSplit%A_Index%, Contents, HidCon)
        ConSplit%A_Index% := ""
    }
    LV_ModifyCol()
    Gui, 1:Default
    Gui, 2: Show,, Outcomes
    Return
}


#3 Guests

  • Guests

Posted 19 June 2012 - 11:17 AM

If it is only ahk_l please post it under custom scripts.

Can some moderator move it? Thank you

#4 maestrith

maestrith
  • Members
  • 406 posts

Posted 19 June 2012 - 03:30 PM

My mistake. Sorry guest. Hopefully they will move it for me.