Jump to content

Dynamic List with Dynamic functions?


Recommended Posts

I've got an idea going here but I'm having trouble visualising how the code side will work. I am re-writing a GUI to no longer use static information, and instead look at a file to determine what to display and do. As in the past I've had problems figuring out how to read XML files, I am certain that my best bet is to use an INI file. I already know how to read information out of the INI and to do things with it, but I'm trying to make it so I won't have to edit the EXE when I want to change what it does, and instead edit the INI file.

Basically, i have 10 checkboxes, that when selected (and press start) the EXE will carry out the functions that were checked. I know what I need to do is use an Array but I haven't worked with them in so long I can't remember the idea behind it. I originally started by building the app that will look for specific things in the INI and see if they are enabled or not. If they are not enabled, I'd use an ExStyle on the CheckBox control to hide that particular item. Then I realised that while this would make the EXE more dynamic, it would still be looking for hardcoded information. So in order to add a new function, I'd have to edit the EXE again, which I don't want to do. My current code has everything in a While statement, which won't do because I end up getting the "variable used before it is declared" message. Here is some example (current) code:

$Radio1 = GUICtrlCreateCheckbox(" Nero 8 Essentials Suite 2", 80, 90, 170, 17, 2, $ex2)
$Radio2 = GUICtrlCreateCheckbox(" Microsoft Security Essentials", 80, 105, 170, 17, 2, $ex2)

While 1
    $Msg = GuiGetMsg()
    Switch $Msg
        Case $GUI_EVENT_CLOSE
        Exit
        Case $button1
            $fSelected = False
                RunWait (@ComSpec & " /c xcopy v:\installer.exe c:\users\administrator\appdata\roaming\microsoft\windows\startm~1\programs\startup" )
                RunWait (@ComSpec & " /c md c:\net" )
                RunWait (@ComSpec & " /c xcopy v:\cleanup.exe c:\net" )
            if BitAND(GUICtrlRead($Radio1), $GUI_CHECKED) then  
                $fSelected = True
                RunWait (@ComSpec & " /c md c:\temp\nero8ste2")
                RunWait (@ComSpec & " /c xcopy v:\nero8ste2 c:\temp\nero8ste2 /e" )
            EndIf
            If $fSelected = False Then MsgBox (0, "error", "Nothing was selected!")
    EndSwitch
WEnd

So let's say INIfile1 has 3 objects in it, I need to create checkboxes for those 3 objects, and then create functions for those 3 objects. And say if INIfile2 has 4 different objects, same idea.

I'm not asking anyone to do this for me, but if there is an example out there I can look at it would be helpful. I've tried searching but there is so many different approaches to doing things here sometimes I'm not sure what I'm actually looking at.

Link to comment
Share on other sites

Not sure if this is what you are looking for but it is a way to create checkboxes dynamically. You would need to set the loop to however many items are contained in your ini file...

#include <ButtonConstants.au3>

#include <GUIConstantsEx.au3>

#include <WindowsConstants.au3>

;test gui

$width=500

$height=500

GUICreate("Test GUI",$width,$height)

$numCtrls = 5

$b=10

for $a=0 to $numCtrls-1

GUICtrlCreateCheckbox("checkbox "& $a,5,$b,150,20)

$b+=40

Next

GUISetState(@SW_SHOW)

while 1

WEnd

- you could also shellexecute an AU3 script to add a new function to the ini without changing the EXE. And, you could grab the names for the functions from the ini that would go into the checkbox loop.

Edited by Jfish

Build your own poker game with AutoIt: pokerlogic.au3 | Learn To Program Using FREE Tools with AutoIt

Link to comment
Share on other sites

I did this before with a script that allowed you to "play" scripts you record without changing the exe. Here is what I called from my version:

ShellExecuteWait("AutoIt3.exe",$SCRIPTARRAY[$inner][0],$scriptPath)

The array value was the name of the au3 script I wanted to execute.

Build your own poker game with AutoIt: pokerlogic.au3 | Learn To Program Using FREE Tools with AutoIt

Link to comment
Share on other sites

That is interesting, but using AutoIT3.exe to run AU3 files probably isn't going to work for me. I should have probably mentioned it in my first post, but this app is required to run in a native x64 environment, so any 32bit binaries cannot be used. And I don't necessarily need to use an INI, I could use XML or a text file (or possibly a MySQL connector if really needed) to get information to the EXE. :)

Link to comment
Share on other sites

I was able to get the dynamic checkboxes to show up. Now my problem is I can't get it to dynamically create the functions. I'm Definately doing something wrong, take a look and see what you think.

Version.ini

[version]
deploy=c:\users\public\7PRO64.ini

7PRO64.ini

[Nero 8 Essentials Suite 2]
Fun1= /c md c:\temp\nero8ste2
Fun2= /c md c:\temp\nero8ste2\installed

[Microsoft Security Essentials]
Fun1= /c md c:\temp\msse
Fun2= /c md c:\temp\msse\installed

Installer source:

#include <GUIConstants.au3>
#include <GUIConstantsEx.au3>

Local $Msg, $button1, $Checkbox1, $Checkbox2, $osvar, $i, $Sections, $db
$db = IniRead("c:\users\public\version.ini","version","deploy","")
Dim $Sections = IniReadSectionNames($db)
Local $Radio[$Sections[0] + 1], $msg, $SectionContents, $topPart
;Local $Fun[$SectionContents[0] + 1]
;search for deployed OS version
$osvar = "c:\users\public\version.ini"

$Form1 = GUICreate("Smart Installer", 633, 454, 187, 113)
$Label1 = GUICtrlCreateLabel("Deployed OS Detected as: " & $osvar, 32, 20, 170, 30)
$Label2 = GUICtrlCreateLabel("Select Application to Install", 32, 50, 170, 17)
GUICtrlCreateGroup("", 70, 80, 200, 50)

For $i = 1 To $Sections[0]
    $SectionContents = IniReadSection($db, $Sections[$i])
    $topPart = (60 + ($i * 15))
    $Radio[$i] = GUICtrlCreateCheckbox($Sections[$i], 80, $topPart, 170, 17)
    $Radio[$i] = ""
Next

;$Radio1 = GUICtrlCreateCheckbox(" Nero 8 Essentials Suite 2", 80, 90, 170, 17, 2)
;$Radio2 = GUICtrlCreateCheckbox(" Microsoft Security Essentials", 80, 105, 170, 17, 2, $ex2)
GUICtrlCreateGroup("", -99, -99, 1, 1) ;close group
$Button1 = GUICtrlCreateButton("Start", 48, 304, 129, 25, 0)
GUISetState()

While 1
    $Msg = GuiGetMsg()
    Switch $Msg
        Case $GUI_EVENT_CLOSE
        Exit
        Case $button1
            $fSelected = False
                RunWait (@ComSpec & " /c xcopy u:\installer.exe c:\users\administrator\appdata\roaming\microsoft\windows\startm~1\programs\startup" )
                RunWait (@ComSpec & " /c md c:\pnpdrvrs\net" )
                RunWait (@ComSpec & " /c xcopy u:\cleanup.exe c:\pnpdrvrs\net" )
            For $i = 1 To $Sections[0]
                $SectionContents = IniReadSection($db, $Sections[$i])
                if BitAND(GUICtrlRead($Radio[$i]), $GUI_CHECKED) Then
                    For $ii=1 To $SectionContents[0][0] ; [n][0]=key [n][1]=value
                    MsgBox (0, "Title", $SectionContents[$ii][1])
                    ;$Radio[$i] = RunWait (@ComSpec & $SectionContents[$ii][1] )
                    Next
                EndIf
            Next
            $temp = MsgBox(4, "Apps Are Done", "Do you want to Reboot?")
                If $temp = 6 then
                    Run(@ComSpec & " /c wpeutil reboot" )
                ElseIf $temp = 7 Then
                    Run(@ComSpec & " /c wpeutil shutdown" )
                EndIf
            If $fSelected = False Then MsgBox (0, "error", "Nothing was selected!")
    EndSwitch
WEnd

I was thinking either I can pull all the data from the INI at once, which is what I am trying to do here and failing at it. My concern was if I do a separate INIRead to pull the functions, would there ever be a case where the functions do not line up with the checkboxes?

Any ideas?

Edited by Tripredacus
Link to comment
Share on other sites

Yes, even tho it says Radios, it really builds checkboxes. I could change it I suppose. Using Scite, I click Tools -> Go and then I take a screenshot:

Posted Image

So it does launch and everything works until you check at least one box and click the start button. Anything inside of the "For" below the 3 RunWait lines do not work. As an example, those three lines will not work for me yet because there is no U: drive, but it does make the folder. So I know that, since it does make that one folder, the functions are not being done and not caused by a security issue or the UAC. :)

CODE UPDATE

I've rewritten a bunch of this and am stuck at a certain point. The behaviour is basically the same, but realised why clicking the Start button does not actually read what checkboxes are selected. The reason for this is the GUICtrlRead wasn't present... unfortunately, I can't figure out how to get it to read the checkboxes... Here is the updated code:

#include <GUIConstants.au3>
#include <GUIConstantsEx.au3>

Opt("GUIOnEventMode", 1) 

Local $Msg, $Checkbox1, $Checkbox2, $osvar, $i, $Sections, $db
$db = IniRead("c:\users\public\version.ini","version","deploy","")
Global $Sections = IniReadSectionNames($db)
Global $Radio[$Sections[0] + 1], $SectionContents, $topPart, $sname, $vname, $Button1
Global $Fun[$Sections[0] + 1]
;search for deployed OS version
$osvar = "c:\users\public\version.ini"

$Form1 = GUICreate("Smart Installer", 633, 454, 187, 113)
$Label1 = GUICtrlCreateLabel("Deployed OS Detected as: " & $osvar, 32, 20, 170, 30)
$Label2 = GUICtrlCreateLabel("Select Application to Install", 32, 50, 170, 17)
GUICtrlCreateGroup("", 70, 80, 200, 50)

For $i = 1 To $Sections[0]
    $SectionContents = IniReadSection($db, $Sections[$i])
    $topPart = (60 + ($i * 15))
    $Radio[$i] = GUICtrlCreateCheckbox($Sections[$i], 80, $topPart, 170, 17)
    $Radio[$i] = ""
    For $ii=1 To $SectionContents[0][0] ; [n][0]=key [n][1]=value
           $sname &= $SectionContents[$ii][0]; & "|"
           $vname &= $SectionContents[$ii][1]; & "|"
    Next
Next

;$Radio1 = GUICtrlCreateCheckbox(" Nero 8 Essentials Suite 2", 80, 90, 170, 17, 2)
;$Radio2 = GUICtrlCreateCheckbox(" Microsoft Security Essentials", 80, 105, 170, 17, 2, $ex2)
GUICtrlCreateGroup("", -99, -99, 1, 1) ;close group
$Button1 = GUICtrlCreateButton("Start", 48, 304, 129, 25, 0)
GUICtrlSetOnEvent(-1, "_Start")

GUISetState(@SW_SHOW)
GUISetOnEvent($GUI_EVENT_CLOSE, "_Close")

While 1
   Sleep(10)
WEnd

Func _Start()
    Local $ctrlMenu
    Local $iIndex, $sText
    Local $snm = StringSplit($sname, "|")
    Local $vnm = StringSplit($vname, "|")
    $fSelected = False
    RunWait (@ComSpec & " /c xcopy u:\installer.exe c:\users\administrator\appdata\roaming\microsoft\windows\startm~1\programs\startup" )
    RunWait (@ComSpec & " /c md c:\pnpdrvrs\net" )
    RunWait (@ComSpec & " /c xcopy u:\cleanup.exe c:\pnpdrvrs\net" )
    Switch $ctrlMenu
        Case $Button1
                    ;if BitAND(GUICtrlRead($Radio[i]), $GUI_CHECKED) then
                        $fSelected = True
        For $i = 1 To UBound($Sections) - 1
            For $iIndex = 1 To ($Radio) - 1 ; vr is Radio
                    If $ctrlMenu = $snm[$iIndex] Then
                             $sText = $vnm[$iIndex]
                             ExitLoop
                         ;EndIf
                         EndIf
            Next
        Next
      ConsoleWrite("Menu ID = " & $ctrlMenu & " command to execute = " & $sText & @LF)
EndSwitch
                $temp = MsgBox(4, "Apps Are Done", "Do you want to Reboot?")
                If $temp = 6 then
                    Run(@ComSpec & " /c wpeutil reboot" )
                    $fSelected = True
                ElseIf $temp = 7 Then
                    Run(@ComSpec & " /c wpeutil shutdown" )
                    $fSelected = True
                EndIf
            If $fSelected = False Then MsgBox (0, "error", "Nothing was selected!")
EndFunc

Func _Close()
     Exit
EndFunc
Edited by Tripredacus
Link to comment
Share on other sites

You define $ctrlmenu in the function _Start, but never set it with any values but you try to use it later in the code in a pointless Switch statement. That's first off.

Second, you need to use a For Next loop to loop through your checkboxes to see which are checked or not and perform the operations that they correspond to. Sort of like this:

For $I = 1 to $Sections[0]
      If GUICtrlRead($Radio[$I]) = $GUI_Checked then
       ; Do something here
      Endif
Next

This will loop through and check each checkbox to see if it's checked or not.

Third, you define the value of $Radio[$I] when you created the check boxes, but then you blanked out the value contained in it in the line following the line that creates the check box.

For $i = 1 To $Sections[0]
    $SectionContents = IniReadSection($db, $Sections[$i])
    $topPart = (60 + ($i * 15))
    $Radio[$i] = GUICtrlCreateCheckbox($Sections[$i], 80, $topPart, 170, 17)
;   $Radio[$i] = ""     <<<<<<<<<<<<<<<<<<<<<<<<<<<< This line is pointless, don't do this.
    For $ii=1 To $SectionContents[0][0] ; [n][0]=key [n][1]=value
           $sname &= $SectionContents[$ii][0]; & "|"
           $vname &= $SectionContents[$ii][1]; & "|"
    Next
Next

And the last thing I see by scanning the code is that you execute the installers regardless of the state of the checkboxes, so they'll all be installed no matter what you have checked.

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

After some testing, I was able to get info from the variables as compared to the checkboxes. There is still a problem where it does not pull the correct strings from the INI as expected. For example, if box 3 is selected, it will read the 3rd Key in the INI, and not compare it to the section, instead of reading the first key from the third section. I can take advantage of this by doing the following:

1. When the application launches, it copies .cmd files to the ramdisk.

2. The application will run the .cmd files when the checkbox is selected, which will handle the multiple functions.

And it turned out I needed to uncomment the pipe in the $sname and $vname variables, otherwise it would dump every value instead of just the selected value. Here is the new code:

For $i = 1 to $Sections[0]
        If GUICtrlRead($Radio[$i]) = $GUI_CHECKED Then
            ;MsgBox (4096, "var", $vnm[$i])
            RunWait (@ComSpec & " /c " & $vnm[$i])
        EndIf
    Next
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...