Jump to content

Help! Button Variable issue


Recommended Posts

I have to first mention I am not a programmer by any means so I definitely need some help to get past this issue.

I am writing a script that will look at a certain directory that contains some .exe files and creates a GUI button for each .exe file it finds. It uses the FileFindNextFile command and goes through a loop once for each exe it finds and creates the button with the following code.

$GuiAppsButton=GUICtrlCreateButton ($GuiExe, $GuiAppsLeft,$GuiAppsTop,90,20)

This works great in that it creates seperate buttons named according to each exe file. The problem is that I want to be able to click on each button and have it run that specific exe file that it refers to. Notice that each time though the loop $GuiAppsButton value will be replaced. So if I later wait for a click of $GuiAppsButton it would only actually run anything on the last button since it was last assigned the value $GuiAppsButton.

This is very obvious why this is happening but I am just not having much luck thinking of a way around this problem. It's almost like each time through the loop it need to dynamically assign a different variable name so that multiple $GuiAppsButtons will exist to be able to call.

I hope this makes sense to someone. Let me know if you need more info.

Link to comment
Share on other sites

I have to first mention I am not a programmer by any means so I definitely need some help to get past this issue.

I am writing a script that will look at a certain directory that contains some .exe files and creates a GUI button for each .exe file it finds. It uses the FileFindNextFile command and goes through a loop once for each exe it finds and creates the button with the following code.

$GuiAppsButton=GUICtrlCreateButton ($GuiExe, $GuiAppsLeft,$GuiAppsTop,90,20)

This works great in that it creates seperate buttons named according to each exe file. The problem is that I want to be able to click on each button and have it run that specific exe file that it refers to. Notice that each time though the loop $GuiAppsButton value will be replaced. So if I later wait for a click of $GuiAppsButton it would only actually run anything on the last button since it was last assigned the value $GuiAppsButton.

This is very obvious why this is happening but I am just not having much luck thinking of a way around this problem. It's almost like each time through the loop it need to dynamically assign a different variable name so that multiple $GuiAppsButtons will exist to be able to call.

I hope this makes sense to someone. Let me know if you need more info.

i'll see if i can get something written up for you, sounds like a fun little project.
Link to comment
Share on other sites

Here you go....

#include <GuiConstants.au3>

; Use the button label to store the name of the exe.....

Global $MAX_EXE_COUNT = 500
Global $buttonWidth = 90, $buttonHeight = 30, $buttonGap = 5
Global $path = @SystemDir

Dim $Button[$MAX_EXE_COUNT+1]

GuiCreate("Example")

Dim $fileCount = 0
$search = FileFindFirstFile($path & "\*.exe")  
If $search <> -1 Then; Check if the search was successful
    While 1
        $file = FileFindNextFile($search) 
        If @error Then ExitLoop
        
        $Button[$filecount] = GuiCtrlCreateButton($file, 10, $fileCount * ($buttonHeight+$buttonGap), $buttonWidth, $buttonHeight)
        $fileCount = $fileCount + 1
    WEnd

    FileClose($search); Close the search handle
EndIf

Global $ACTUAL_EXE_COUNT = $fileCount - 1

GuiSetState()

While 1
    $msg = GuiGetMsg()
    
    If $msg = $GUI_EVENT_CLOSE Then Exit
    
    If $msg >= $Button[0] And $msg <= $Button[$ACTUAL_EXE_COUNT] Then
        MsgBox(4096,"Could run ...", $path & "\" & GuiCtrlRead($msg))
           ;;;Run($path & "\" & GuiCtrlRead($msg))
    EndIf       
WEnd
Edited by CyberSlug
Use Mozilla | Take a look at My Disorganized AutoIt stuff | Very very old: AutoBuilder 11 Jan 2005 prototype I need to update my sig!
Link to comment
Share on other sites

Here you go....

#include <GuiConstants.au3>

; Use the button label to store the name of the exe.....

Global $MAX_EXE_COUNT = 500
Global $buttonWidth = 90, $buttonHeight = 30, $buttonGap = 5
Global $path = @SystemDir

Dim $Button[$MAX_EXE_COUNT+1]

GuiCreate("Example")

Dim $fileCount = 0
$search = FileFindFirstFile($path & "\*.exe")  
If $search <> -1 Then; Check if the search was successful
    While 1
        $file = FileFindNextFile($search) 
        If @error Then ExitLoop
        
        $Button[$filecount] = GuiCtrlCreateButton($file, 10, $fileCount * ($buttonHeight+$buttonGap), $buttonWidth, $buttonHeight)
        $fileCount = $fileCount + 1
    WEnd

    FileClose($search); Close the search handle
EndIf

Global $ACTUAL_EXE_COUNT = $fileCount - 1

GuiSetState()

While 1
    $msg = GuiGetMsg()
    
    If $msg = $GUI_EVENT_CLOSE Then Exit
    
    If $msg >= $Button[0] And $msg <= $Button[$ACTUAL_EXE_COUNT] Then
        MsgBox(4096,"Could run ...", $path & "\" & GuiCtrlRead($msg))
         ;;;Run($path & "\" & GuiCtrlRead($msg))
    EndIf       
WEnd
nice. i was going about it kind of the same way, except using a 2 dimensional array, [$x][0] being the filename, and [$x][1] being the GUICtrlCreateButton(). i didn't get mine finished yet though...

***edit***

yes i decided it would be silly to continue doing mine, i've already explained the only real difference, and i think the OP could figure out how to add the small bit of code necessary to change CS's if they wanted to go that route.

Edited by cameronsdad
Link to comment
Share on other sites

  • Moderators

Geeze Cyber... a bit quick for me!!, I was sitting here trying to figure out damn widths of buttons!! This is close but could be a hell of alot better

#include <guiconstants.au3>
Local $Directory = FileSelectFolder('Select A Folder To Search...', @HomeDrive)
Local $SearchDirectory = FileFindFirstFile($Directory & "\*.exe")
Local $ExeFiles = ''
Local $aExeArray = ''
If $SearchDirectory = - 1 Then Exit

While 1
    $ExeFiles = FileFindNextFile($SearchDirectory) 
    If @error Then ExitLoop
    $aExeArray = $aExeArray & $ExeFiles & Chr(01)
    If UBound(StringSplit(StringTrimRight($aExeArray, 1), Chr(01))) > 300 Then ExitLoop
WEnd

Local $Bwidth = MsgLongestString($aExeArray)
$aExeArray = StringSplit(StringTrimRight($aExeArray, 1), Chr(01))
ArraySortByLen($aExeArray)

Local $ArrayTotal = UBound($aExeArray)
Local $Buttons[$ArrayTotal]
Local $Gheight = $ArrayTotal
Local $GWidth = $Bwidth
Local $BLeft = 10
Local $BTop = 10
Local $SubtractI = ''
If $ArrayTotal / 20 > 1 Then
    $GWidth = $Bwidth * ($ArrayTotal / 20) + (($ArrayTotal / 20) * 13)
EndIf

$MainGui = GUICreate('Test GUI', $Gwidth + 20, 810)

For $i = 1 To $ArrayTotal - 1
    If $i >= 21 And $i <= 40 Then 
        $TimesBLeft = (($BLeft + $Bwidth) + 10) * 1
        $SubtractI = ($i - 21) * 40
    ElseIf $i >= 41 And $i <= 60 Then 
        $TimesBLeft =  (($BLeft + $Bwidth) + 5) * 2
        $SubtractI = ($i - 41) * 40
    ElseIf $i >= 61 And $i <= 80 Then 
        $TimesBLeft =  (($BLeft + $Bwidth) + 5) * 3
        $SubtractI = ($i - 61) * 40
    ElseIf $i >= 81 And $i <= 100 Then 
        $TimesBLeft =  (($BLeft + $Bwidth) + 5) * 4
        $SubtractI = ($i - 81) * 40
    ElseIf $i >= 101 And $i <= 120 Then 
        $TimesBLeft =  (($BLeft + $Bwidth) + 5) * 5
        $SubtractI = ($i - 101) * 40
    ElseIf $i >= 121 And $i <= 140 Then 
        $TimesBLeft =  (($BLeft + $Bwidth) + 5) * 6
        $SubtractI = ($i - 121) * 40
    ElseIf $i >= 141 And $i <= 160 Then 
        $TimesBLeft =  (($BLeft + $Bwidth) + 5) * 7
        $SubtractI = ($i - 141) * 40
    ElseIf $i >= 161 And $i <= 180 Then 
        $TimesBLeft =  (($BLeft + $Bwidth) + 5) * 8
        $SubtractI = ($i - 161) * 40
    ElseIf $i >= 181 And $i <= 200 Then 
        $TimesBLeft =  (($BLeft + $Bwidth) + 5) * 9
        $SubtractI = ($i - 181) * 40
    ElseIf $i >= 201 And $i <= 220 Then 
        $TimesBLeft =  (($BLeft + $Bwidth) + 5) * 10
        $SubtractI = ($i - 201) * 40
    ElseIf $i >= 221 And $i <= 240 Then 
        $TimesBLeft =  (($BLeft + $Bwidth) + 5) * 11
        $SubtractI = ($i - 221) * 40
    ElseIf $i >= 241 And $i <= 260 Then 
        $TimesBLeft =  (($BLeft + $Bwidth) + 5) * 12
        $SubtractI = ($i - 241) * 40
    ElseIf $i >= 261 And $i <= 280 Then 
        $TimesBLeft =  (($BLeft + $Bwidth) + 5) * 13
        $SubtractI = ($i - 261) * 40
    ElseIf $i >= 281 And $i <= 300 Then 
        $TimesBLeft =  (($BLeft + $Bwidth) + 5) * 14
        $SubtractI = ($i - 281) * 40
    Else
        $TimesBLeft = $BLeft * 1
        $SubtractI = ($i - 1) * 40
    ;MsgBox(0, '', $SubtractI )
    EndIf
    $Buttons[$i] = GUICtrlCreateButton(StringTrimRight($aExeArray[$i], 4), $TimesBLeft, $BTop + $SubtractI, $Bwidth, 30)
Next

GUISetState()

While 1
    $msg = GUIGetMsg()
    If $msg = - 3 Then Exit
WEnd

Func MsgLongestString($sText)
    Local $sSplit = StringSplit(StringTrimRight($sText, 1), Chr(01))
    Local $Times = ''
    If IsArray($sSplit) Then
        ArraySortByLen($sSplit)
        $Times = StringLen($sSplit[1]) * .225
        Return Int(StringLen($sSplit[1])*$Times)
    Else
        $Times = StringLen($sText) * .225
        Return Int(StringLen($sText)*$Times)
    EndIf
EndFunc 

Func ArraySortByLen(ByRef $nArray, $Start = 1)
    For $i = $Start To UBound($nArray) - 2
        Local $SE = $i
        For $x = $i To UBound($nArray) - 1
            If StringLen($nArray[$SE]) < StringLen($nArray[$x]) Then $SE = $x
        Next
        Local $HLD = $nArray[$i]
        $nArray[$i] = $nArray[$SE]
        $nArray[$SE] = $HLD
    Next
EndFunc

Edit: Edited the MsgLongString(), actually works nicer this way.

Edit2: Somebody stop me!!!, I'm so bored ...

Edit3: Ok, I have to stop, something keep drawing me back to this thread!! Buttons should be spaced right and width should be adjusted accordingly. Still a rough rough idea, I have a better one (idea), but no desire to write it :o

Edited by SmOke_N

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

THANKS a bunch everyone!

I had also figured out that you could use the ASSIGN command to create the dynamically incremented variable(ie var0, var1, var2). But I was still stumped on how I was going to get each one to run from a single command. The GuiCtrlRead($msg) is what I needed to flick on that dim light in my head.

Thanks again.

Link to comment
Share on other sites

OK.......I am now thinking about taking this little project one step further and I am stumped yet once again. I would like to make it so that the label on the button could be changed by the user to something more meaningfull. Like maybe right clicking on it would give the option to change the button text. I was thinking of using an ini file to store this information and the ini file would be created the first time the program is opened. So by default the buttons would just be named according to the exe's and then the user could change them later if they wanted to. I was thinking the ini might look something like this.

[1]

exe=filemon.exe

alias=File Monitor

[2]

exe=diskmon.exe

alias=Disk Monitor

I can easily figure out how to use the ini commands to create the ini file, but when trying to figure out how to get the button to open the exe is my problem. Since the button title may now not equal the exe file name I'm not sure exactly how to match up the button with the exe.

Hope someone can help. Thanks

Link to comment
Share on other sites

VERY ULGY but it works.

First: If the ini doesn't exist, create it.

Second: Create the contextMenuItems....

When a context menu is clicked, you need to convert its Gui ID number to a flat index: $msg - $ContextMenuItem[0] + 1

For all I know, the $msg id could be 25. But if the zeroth contextMenuItem ID is 22, then we know the index of the click was 4 (25 - 22 + 1). So we want to update the text of $Button[4]. Just set the button text and upadte the alias value from section "4" of our ini file!

#include <GuiConstants.au3>

; Use the ini filel to store the name of the exe.....

Global $iniFile = @ScriptDir & "\myIniFile.ini"

Global $MAX_EXE_COUNT = 500
Global $buttonWidth = 90, $buttonHeight = 30, $buttonGap = 5
Global $path = @SystemDir

Dim $Button[$MAX_EXE_COUNT+1]
Dim $ContextMenuItem[$MAX_EXE_COUNT+1]

If Not FileExists($iniFile) Then SplashTextOn("Please wait...", @LF & "Creating ini file for first run")

GuiCreate("Example")

Dim $fileCount = 0
$search = FileFindFirstFile($path & "\*.exe")  
If $search <> -1 Then; Check if the search was successful
    While 1
        $file = FileFindNextFile($search)
        If @error Then ExitLoop
        
        $name = iniRead($iniFile, $filecount, "alias", "DEFAULT_ERROR")
        If $name = "DEFAULT_ERROR" Then
;Generate initial INI file:
            iniWrite($iniFile, $fileCount, "exe", $file)
            iniWrite($iniFile, $fileCount, "alias", StringUpper(StringTrimRight($file,4)) )
            $name = StringUpper(StringTrimRight($file,4))
        EndIf
        $Button[$filecount] = GuiCtrlCreateButton($name, 10, $fileCount * ($buttonHeight+$buttonGap), $buttonWidth, $buttonHeight)
        $fileCount = $fileCount + 1
        

        
    WEnd

    FileClose($search); Close the search handle
EndIf

Global $ACTUAL_EXE_COUNT = $fileCount - 1


; I want the control IDs of the Buttons and ContextMenuItems to be completely separate blocks of numbers
; instead of interleaved.  Actually, because GUICtrlCreateMenuitem contains a call to GuiCtrlCreateContextMenu,
; $ContextMenuItem will always have an odd-numbered index...
For $i = 0 to $ACTUAL_EXE_COUNT
    $ContextMenuItem[$i] = GUICtrlCreateMenuitem("Edit name", GuiCtrlCreateContextMenu($Button[$i]) )
Next

SplashOff()
GuiSetState()

While 1
    $msg = GuiGetMsg()
    
    If $msg = $GUI_EVENT_CLOSE Then Exit
    
    If $msg >= $Button[0] And $msg <= $Button[$ACTUAL_EXE_COUNT] Then
        $exe =  iniRead($iniFile, $msg - $Button[0] + 1, "exe", "")
        
        MsgBox(4096,"Could run ...", $path & "\" & $exe)
        ;;;Run($path & "\" & GuiCtrlRead($msg))
   EndIf

    If $msg >= $ContextMenuItem[0] And $msg <= $ContextMenuItem[$ACTUAL_EXE_COUNT] Then
        $index = $msg - $ContextMenuItem[0] + 1
        $index = ($index-1) / 2;convert from odd number to flat index
        $input = InputBox("Edit button caption", "Change the text for button #" & $index, GuiCtrlRead($Button[$index]))
        If @error <> 1 Then
            GuiCtrlSetData($Button[$index], $input);update label
            iniWrite($iniFile, $index, "alias", $input);update ini
        EndIf
    EndIf
WEnd
Edited by CyberSlug
Use Mozilla | Take a look at My Disorganized AutoIt stuff | Very very old: AutoBuilder 11 Jan 2005 prototype I need to update my sig!
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...