Jump to content

GuiCtrlSetOnEvent


Recommended Posts

Hi, I'm having a hard time with GuiCtrlSetOnEvent. Reading the help pages and searching a bit has not yielded anything for me, so I ask for a point in the right dir :D

Okay, I have some check boxes that can be set or not set and are read from an array. The checkboxes themselves then store their controlID into the array, etc, that's all fine and dandy. However, I want to set or unset a bit in the array if a box is checked or not.

However when I try this with GuiCtrlSetOnEvent, I always get the error: Unknown Function name in relation to negate. First of all, is there a better way to set the bit ? Eg, if the box is checked, I want the $choices[$i][$controlID] to be set to 1 and 0 if not checked. this should happen with an OnEvent . If there is not a better way (built in func), I need to know how to get this function to recognize my functionnames.

any help is appreciated.

Func gui()
Local $windowW = 700
Local $windowH = 400
Local $mainWindow, $okbutton
    
Opt("GUIOnEventMode",1)
$mainWindow = GUICreate("Preventive Maintenance System", $windowW, $windowH)
GUISetOnEvent($GUI_EVENT_CLOSE, "CLOSEClicked")
GUICtrlCreateLabel("Check your choices, then click 'Do Selected'.", 5, 10)
$okbutton = GUICtrlCreateButton("Do Selected",($windowW-75),($windowH-30),70)
GUICtrlSetOnEvent($okbutton,"OKButton")
for $i = 1 to $arrayend ; Go from 1 because we don't want to display a checkbox for "gui"
    ; capture the ControlID into the same array for later use.
    $choices[$i][2]= GUICtrlCreateCheckbox($choices[$i][0], 5, ($i*25)+5)
    if $choices[$i][1]=1 Then
        GUICtrlSetState(-1,$GUI_CHECKED)
    EndIf
    ; create state chage calls...
    GUICtrlSetOnEvent($choices[$i][2], "negate($i)") ; <--- RIGHT HERE IS THE PROBLEM>>>
Next
Global $guiText = GUICtrlCreateEdit("",$windowW/2,5,$windowW/2-7,$windowH-40, BitOr($ES_MULTILINE,$ES_READONLY))
GUISetState(@SW_SHOW)

logThis("Gui Initialized")
;_ArrayDisplay($choices)
while 1
 Sleep(1000)
WEnd
    
EndFunc

Func negate($i) ; Rotten error checking... look this over better later.
    if $choices[$i][1] Then
        $choices[$i][1] = 0
    Else
        $choices[$i][1] = 1
    EndIf
EndFunc
Link to comment
Share on other sites

I've never seen a parameter passed to a function with guictrlsetonevent. I'm not sure it's possible. I can't get a correct syntax. Maybe someone else knows if that is possible. Other than that, you could use a global variable to get around it.

Link to comment
Share on other sites

I've never seen a parameter passed to a function with guictrlsetonevent. I'm not sure it's possible. I can't get a correct syntax. Maybe someone else knows if that is possible. Other than that, you could use a global variable to get around it.

I've sorted it out I think - using @GUI_CTRLID, I should be able to solve this. Will post solution shortly.

Link to comment
Share on other sites

You can't pass parameters to the functions, but there are some macros like @GUI_CTRLID available to know where the event was triggered from (see the help file):

#include <GuiConstants.au3>

Opt("GUIOnEventMode", 1)

Global $windowW = 700, $windowH = 400
Global $mainWindow, $okbutton, $choices[4][3], $guiText

gui()

While 1
    Sleep(20)
WEnd

Func gui()
    $mainWindow = GUICreate("Preventive Maintenance System", $windowW, $windowH)
    GUISetOnEvent($GUI_EVENT_CLOSE, "CLOSEClicked")
    GUICtrlCreateLabel("Check your choices, then click 'Do Selected'.", 5, 10)
    $okbutton = GUICtrlCreateButton("Do Selected", ($windowW - 75), ($windowH - 30), 70)
    GUICtrlSetOnEvent($okbutton, "OKButton")
    For $i = 1 To UBound($choices) - 1
        $choices[$i][0] = $i
        $choices[$i][1] = Random(0, 1, True) ; Random checking
        $choices[$i][2] = GUICtrlCreateCheckbox($choices[$i][0], 5, ($i * 25) + 5)
        If $choices[$i][1] = 1 Then
            GUICtrlSetState(-1, $GUI_CHECKED)
        EndIf
        GUICtrlSetOnEvent($choices[$i][2], "negate")
    Next
    Global $guiText = GUICtrlCreateEdit("", $windowW / 2, 5, $windowW / 2 - 7, $windowH - 40, BitOR($ES_MULTILINE, $ES_READONLY))
    GUISetState(@SW_SHOW)
EndFunc   ;==>gui

Func negate()
    For $i = 1 To UBound($choices) - 1
        If $choices[$i][2] = @GUI_CtrlId Then
            GUICtrlSetData($guiText, GUICtrlRead($guiText) & @CRLF & "Somebody cliked checkbox " & $i)
            Return
        EndIf
    Next
EndFunc   ;==>negate

Func CLOSEClicked()
    MsgBox(64, "CLOSEClicked", "User closed GUI")
    Exit
EndFunc   ;==>CLOSEClicked

Func OKButton()
    GUICtrlSetData($guiText, GUICtrlRead($guiText) & @CRLF & "Somebody cliked the OK button.")
EndFunc   ;==>OKButton

:D

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

Okay, I have it working as expected.

Here is my script SO FAR - as you can tell be reading it - this is just the decision making part of it - very little of it actually does anything - other than make decisions of what to do.

Please review this and let me know where I ought to make it better. By the way, I know about UBound, I just used $arrayend because it's easier to set early on, and it's faster to type.

#cs **********

Preventative Maintenance System



16 Jan 2008

Call this program from command line as such:  <path>\pms.exe <choice>
the content you put after the command line is optional, if you put nothing, the system will bring up a GUI and run interactively.
If, however, you give it a number 0 to 16, it will perform various functions.

In Binary:      Decimal:
0 0 0 0 0 0     =0                  Leftmost column is Bit1 and rightmost column is Bit5, the others follow accordingly.
0 0 0 0 0 1     =1                  A "1" in a column is a "Yes" or "Affirmative".  A "0" in a column is a "No" or Negative
0 0 0 0 1 0     =2                  bit0 is for GUI
0 0 0 0 1 1     =3                  bit1 is for Defrag
0 0 0 1 0 0     =4                  bit2 is for DiskClean
0 0 0 1 0 1     =5                  bit3 is for UserClean
0 0 0 1 1 0     =6                  bit4 is for WindowsUpdates
0 0 0 1 1 1     =7                  bit5 is for PageFile
0 0 1 0 0 0     =8                  
0 0 1 0 0 1     =9
0 0 1 0 1 0     =10
0 0 1 0 1 1     =11

and so on... please determine the right combo on your own.
0 1 1 1 1 1     =95; No GUI, do everything else (basically silent operation)
1 1 1 1 1 1     =127 ; don't exceed 127, it'll just drop to 127. This means run the GUI and preselect everything.
1 0 0 0 0 0     =    ; you might as well just double click the exe, as it's the same result - run the GUI, select nothing.
#ce **********

#cs **********
INCLUDES, OPTIONS & VARIABLES 
#ce **********
#include <GUIConstants.au3>


Opt("TrayIconHide", 1)
Opt("RunErrorsFatal", 0) ; Don't really need this script quitting because Run or RunWait freaked out.
Opt("TrayIconDebug", 0) 
Opt('MustDeclareVars', 1)

Global $version="PMS v0.2", $scrollText[20], $scrollPos=0, $needReboot=0
Global $svr="\\autoit", $share="\PMS", $user="username", $pass="password"
Global $localLog=@TempDir ; For the case that the machine this script runs on is not able to log to the autoit server.
Global $REG_pageFileLoc="HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management", $REG_pageFileName="PagingFiles" ; page file key information
Global $localDriveLetter="T:" ; T: is one we don't use much in KRMC... so why not ;)
Global $choice[6], $drivemapped=0
; IF YOU MODIFIY THIS ARRAY, YOU NEED TO MODIFY THE SELECT STATEMENT BELOW AND CREATE CORRESPONDING FUNCTIONS...
Global $choices[6][3] = [["Gui",0,0],["Clean Temp Files, Recycle Bin",0,0],["Set Virtual Memory Correctly",0,0],["Clean User Profiles",0,0],["Perform Windows Updates",0,0],["Run Defrag (generally takes a long time)",0,0]]
Global Const $arrayend = 5 ; the array starts at 0 always.  Make sure you change this to 1 less than your max size if you change the amount of options.
Global $count ; needed this for the handles and setting GUICtrlSetOnEvent for the checkboxes
Global $test = 1  ; set to 0 to have script actually do anything besides mount/umount drives and some logging.

Local $hdd="", $mem="", $pagefilesize=0, $i=0, $buffer=0

if $cmdline[0] > 0 Then
    $buffer = $cmdline[1]
    if StringRegExp($buffer,"^\d+$") then ; this tests for positive integers
        if ( $buffer > 127) Then 
            $buffer = 127 
        EndIf
        $choice = bin($buffer)
        for $i=0 to $arrayend
            $choices[$i][1]=$choice[$i]
        Next
    Else
        logthis("Use a number between 1 and 127", $localLog)
        exit
    endif
EndIf
; Maybe later check for more than one $cmdline argument, and use those for something else handy.
    
; However, if it's just clicked on from the icon, start the gui, but just wait for the user.
if $cmdline[0]=0 Then
    $choices[0][1]=1
    for $i=1 to $arrayend
        $choices[$i][1]=0
    Next
EndIf

; map the drives - so we can log and do windows updates
mapAutoIT($localDriveLetter)


if $choices[0][1] Then
    gui()
    unMapAutoIT($localDriveLetter)
Else ; there is probably a better way to do this, but running low on time.
    for $i=1 to $arrayend ; the first 
        if $choices[$i][1] Then
            Select
                case $choices[$i][0] = $choices[1][0] ; Variable name in position 1,0 of $choices, this case: "Clean Temp Files, Recycle Bin".  Done this way to keep you from 
                    cleantempfiles()                  ; needing to change select choices when you change the names in the $choices array.
                case $choices[$i][0] = $choices[2][0]
                    ; Get size of available memory.  Do formula:
                    ; The recommended size is 2.5 times your RAM size, and my choice is to set the Initial Size and Maximum Size values equal, to get a fixed size swap file
                    ; We'll follow this till 4G in size for a swap file... past that's it a pain for windows to address the file size.
                    $mem = MemGetStats()
                    $pagefilesize = int(($mem[1] * 2.5) / 1000)
                    setupPageFile($hdd, $pagefilesize)
                case $choices[$i][0] = $choices[3][0]
                    cleanuserprofiles()
                case $choices[$i][0] = $choices[4][0]
                    doupdates()
                case $choices[$i][0] = $choices[5][0]
                    defrag()
                case Else
                    MsgBox (0, "Whoops", "Next time try to fix the select statement...")
            EndSelect
        EndIf
    Next
endif

; close drives.. no need to leave these on the user's PC.
unMapAutoIT($localDriveLetter)



#cs **********
Functions
#ce **********


Func gui()
Local $windowW = 700
Local $windowH = 400
Local $mainWindow, $okbutton
    
Opt("GUIOnEventMode",1)
$mainWindow = GUICreate("Preventive Maintenance System", $windowW, $windowH)
GUISetOnEvent($GUI_EVENT_CLOSE, "CLOSEClicked")
GUICtrlCreateLabel("Check your choices, then click 'Do Selected'.", 5, 10)
$okbutton = GUICtrlCreateButton("Do Selected",($windowW-75),($windowH-30),70)
GUICtrlSetOnEvent($okbutton,"OKButton")
for $count = 1 to $arrayend ; Go from 1 because we don't want to display a checkbox for "gui" & use Global $count because of limitation of GUICtrlSetOnEvent
    ; capture the ControlID into the same array for later use.
    $choices[$count][2]= GUICtrlCreateCheckbox($choices[$count][0], 5, ($count*25)+5)
    GUICtrlSetOnEvent(-1, "changestate")
    if $choices[$count][1]=1 Then
        GUICtrlSetState(-1,$GUI_CHECKED)
        
    EndIf
    ; create state chage calls...
     
Next
Global $guiText = GUICtrlCreateEdit("",$windowW/2,5,$windowW/2-7,$windowH-40, BitOr($ES_MULTILINE,$ES_READONLY))
GUISetState(@SW_SHOW)

logThis("Gui Initialized")

while 1
 Sleep(1000)
 
WEnd
    
EndFunc

Func changestate() ; Rotten error checking... look this over better later.
    Local $i=0
    ; ControlID is @GUI_CTRLID
    for $i=1 to $arrayend
        if $choices[$i][2] = @GUI_CTRLID Then
            if $choices[$i][1] Then
                $choices[$i][1] = 0
            Else
                $choices[$i][1] = 1
            EndIf
        EndIf
    Next
EndFunc


Func logThis($text)
    local $log,$loc,$success=0,$error=0 ; location of logfile.
    if $choices[0][1] Then ; see if the GUI is initialized.
        updateGUI($text)
    EndIf
    if $drivemapped Then
        $loc = $localDriveLetter&"\logs\"
        $log = FileOpen ( $loc & @ComputerName & ".log", 1 )
        $success=FileWrite($log, $text& " | " & @HOUR & ":" & @MIN & @CRLF)
        if $success <> 1 Then
            $error=1
        EndIf
        FileClose($log)
    EndIf
    if $drivemapped=0 OR $error<>0 then
        $loc = $localLog&"\"
        $log = FileOpen ( $loc & @ComputerName & ".log", 1 )
        $success=FileWrite($log, $text &" "& @HOUR & ":" & @MIN & @CRLF)
        if $success <> 1 Then
            MsgBox(0,"","Cannot log remotely or locally... something is really screwed up here.")
        EndIf
        FileClose($log)
    EndIf   
EndFunc

Func updateGUI($text)
    local $updatetxt = ""
    if $scrollpos < 19 AND $scrollpos > 0 then
        $scrollpos = $scrollpos + 1
        $scrolltext[$scrollpos] = $text
    elseif $scrollpos = 0 Then
        $scrolltext[$scrollpos] = $text
        $scrollpos = $scrollpos + 1
    Elseif $scrollpos >= 19 then
        _ArrayPush ($scrolltext, $text ,0 )
    endif
    for $i = 0 to $scrollpos 
        $updatetxt = $updatetxt&$scrolltext[$i]&@CRLF
    Next
    GUICtrlSetData($guiText,$updatetxt)
EndFunc

Func mapAutoIT($driveLetter)
    Local $success=0,$error=0
    $success = DriveMapAdd($driveletter,$svr&$share,0,$user,$pass)
    $error = @error
    Select
     case $success=1 AND $error=0
        $drivemapped=1
     case $error=1
        $success = DriveMapAdd($driveletter,$svr&$share,0); sometimes it gets screwy if you try to hand it credentials all the time.
        $error=@error
        if $success=1 AND $error=0 then
            $drivemapped=1
        else
            MsgBox(0,"","Cannot map drive: Undefined / Other error. @extended set with Windows API return", 5)
        EndIf
     case $error=2
        MsgBox(0,"","Cannot map drive: Access to the remote share was denied", 5)
     case $error=3
        MsgBox(0,"","Cannot map drive: The device is already assigned", 5)
     case $error=4
        MsgBox(0,"","Cannot map drive: Invalid device name", 5)
     case $error=5
        MsgBox(0,"","Cannot map drive: Invalid remote share", 5)
     case $error=6
        MsgBox(0,"","Cannot map drive: Invalid password", 5)
    EndSelect
EndFunc

Func unMapAutoIT($driveLetter)
    local $val=0
    $val = DriveMapDel($driveletter)
    $drivemapped=0
EndFunc

Func bin($decimal)
    local $retVal[6], $startVal=String($decimal), $work, $work2
    ; very limited - only goes to decimal(127) - 6 "columns"
    ; good enough for this run though..
    for $i = 5 to 0 step -1
        $retVal[$i] = Int(Mod($decimal,2))
        $decimal = $decimal / 2
    next
    return $retVal
EndFunc

Func OKButton()
    ;MsgBox(0,"GUI Event","OK Clicked...")
    ; read thru the $choices array and find out which ones are checked and run those functions...
    
    for $i = 1 to $arrayend
        ;MsgBox(0,"Stuff",$choices[$i][0])
        if $choices[$i][1] Then
            Select
                case $choices[$i][0] = $choices[1][0] ; Variable name in position 1,0 of $choices, this case: "Clean Temp Files, Recycle Bin".  Done this way to keep you from 
                    ;cleantempfiles()                 ; needing to change select choices when you change the names in the $choices array.
                    if $test Then
                        MsgBox(0,"Would do:","cleantempfiles()")
                    Else
                        cleantempfiles()
                    endif
                case $choices[$i][0] = $choices[2][0]
                    if $test Then
                        MsgBox(0,"Would do:","setupPageFile()")
                    Else
                        ; Get size of available memory.  Do formula:
                        ; The recommended size is 2.5 times your RAM size, and my choice is to set the Initial Size and Maximum Size values equal, to get a fixed size swap file
                        ; We'll follow this till 4G in size for a swap file... past that's it a pain for windows to address the file size.
                        $mem = MemGetStats()
                        $pagefilesize = int(($mem[1] * 2.5) / 1000)
                        setupPageFile($hdd, $pagefilesize)
                    EndIf
                case $choices[$i][0] = $choices[3][0]
                    if $test Then
                        MsgBox(0,"Would do:","cleanUserProfiles()")
                    Else
                        cleanuserprofiles()
                    EndIf
                case $choices[$i][0] = $choices[4][0]
                    if $test Then
                        MsgBox(0,"Would do:","doUpdates()")
                    Else
                        doupdates()
                    EndIf
                case $choices[$i][0] = $choices[5][0]
                    if $test Then
                        MsgBox(0,"Would do:","defrag()")
                    Else
                        defrag()
                    endif
                case Else
                    MsgBox (0, "Whoops", "Next time try to fix the select statement...")
            EndSelect
        EndIf
    next    
EndFunc

Func CLOSEClicked()
    unMapAutoIT($localDriveLetter)
    Exit
EndFunc
Link to comment
Share on other sites

  • 4 weeks later...

Sorry for the delay. I just came across this while searching for something else.

I ran into this problem before. What I did is create a dummy function that is called by the event. Then that function calls the real function and passes the info.

For example, here is some sample code I use:

$UpdateButton = GuiCtrlCreateButton("Update", $Left  + 200, 110, 60, 20)
GUICtrlSetOnEvent($UpdateButton, "Update")

Func Update ()
    UpdateProxy ($publicIP, $IP_Location)
EndFunc

Func UpdateProxy (ByRef $publicIP, ByRef $IP_Location)
    ;This finds the public IP and country location.
    
    ;Code goes here.

    Return $publicIP & $IP_Location
EndFunc

I can then call UpdateProxy() directly from another part of the code to pass variables. But I have to call Update() from an event, which then calls Update2Proxy.

Clutsy, but works great, and is easy to do.

Dick

I've never seen a parameter passed to a function with guictrlsetonevent. I'm not sure it's possible. I can't get a correct syntax. Maybe someone else knows if that is possible. Other than that, you could use a global variable to get around it.

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...