Jump to content
Sign in to follow this  
storme

Displaying an array of interactive controls on a grid

Recommended Posts

storme

G'day all

I originally proposed this script here but wonder if there is an easier way of doing this.

A lot of my programs require this kind of display (ie rows of data that may or may not require interaction.

This is the "proof of concept" and before I do a lot of work and find out 2 days latter it could have been done in one line. I thought I'd throw it out there once more to see if anyone had an easier way of doing it.

To scroll the "array" I've crated a seperate window and used "GUIScroll.au3" but I'm not sure how or if this can be used within a window, which is what I originaly wanted to do. Any help would be apreciated.

Interaction (button clicking) is handled by a great little script "onEventFunc.au3" which made life a lot easier for this script.

To run the script you'll have to get

GUIScroll.au3

and

onEventFunc.au3

; ================================================================
; Name...........: GUI_Control_Grid
; Description ...: Creates an interactive array of controls
; Syntax.........: Only "proof of concept" look in code
; Parameters ....: N/A
; Return values .: N/A
; Author ........: John Morrison
; Modified.......: 01Jan09
; Remarks .......:
; Related .......:
; Link ..........: http://www.autoitscript.com/forum/index.php?showtopic=87870
; Example .......: Yes this file "proof of concept"
; ================================================================
Opt("GUIOnEventMode", 1)

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Compression=4
#AutoIt3Wrapper_Res_Fileversion=0.0.3.0
#AutoIt3Wrapper_Res_FileVersion_AutoIncrement=p
#AutoIt3Wrapper_Run_Tidy=y
#AutoIt3Wrapper_Run_Obfuscator=y
#Obfuscator_Parameters=/Striponly
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include "GUIScroll.au3"    ; http://www.autoitscript.com/forum/index.php?showtopic=79684
#include "onEventFunc.au3" ;http://www.autoitscript.com/forum/index.php?showtopic=71811
#include <Array.au3>

Global $numPrograms = 10
Global $numControls = 6 ; Number of buttons + Checkbox

; declare variables
Local $programNames[$numPrograms] = ["Spybot", "Norton", "AVG", "Defrag", "prog1", "prog2", "prog3", "prog4", "prog5", "prog6"]
Local $controlText[$numControls] = ["", "Download", "Install", "Update", "Run", "Uninstall"] ; First element will be replaced by program name
Local $controlTypes[$numControls] = ["Checkbox", "Button", "Button", "Button", "Button", "Button"]
Local $functionNames[$numControls] = ["", "FuncDownload", "FuncInstall", "FuncUpdate", "FuncRun", "FuncUninstall"] ; blank "" entries mean no function to call
Local $controlWidth[$numControls] = [60, 80, 80, 80, 80, 80]
Local $controlHeight = 20
Local $guiControlArray[$numPrograms][$numControls]

Local $groupLeft = 10 ; left most position for group
Local $groupTop = 20 ; Top most position for group
Local $groupHeightSpacing = 5 ; space between rows
Local $groupWidthSpacing = 10 ; Space between collumns

; actually create and display the GUIarray
Local $Form1 = GUICreate("Select function to perform", 560, 200, 192, 124)
_controlArrayCreate($programNames, $controlText, $controlTypes, $controlWidth, $controlHeight, $guiControlArray)
_controlArrayDisplay($groupLeft, $groupTop, $groupHeightSpacing, $groupWidthSpacing, $guiControlArray)

SetOnEventA($GUI_EVENT_CLOSE, "ExitProgram")
GUISetState(@SW_SHOW)

;add scroll bars (Needs GUIScroll.au3 UDF)
Scrollbar_Step(20, $Form1, $SB_VERT); Scrolls per 20 pixels. If not set the default is 1 (smooth scrolling)
Scrollbar_Create($Form1, $SB_VERT, $groupTop + (($groupHeightSpacing + $controlHeight) * $numPrograms))

;Change button states
_controlArraySetState("Spybot", $programNames, "Download", $controlText, $guiControlArray, $GUI_DISABLE)
_controlArraySetState("Spybot", $programNames, "Install", $controlText, $guiControlArray, $GUI_DISABLE)
_controlArraySetState("Norton", $programNames, "Install", $controlText, $guiControlArray, $GUI_DISABLE)
_controlArraySetState("Norton", $programNames, "Update", $controlText, $guiControlArray, $GUI_DISABLE)
_controlArraySetState("Norton", $programNames, "Run", $controlText, $guiControlArray, $GUI_DISABLE)
_controlArraySetState("Norton", $programNames, "Uninstall", $controlText, $guiControlArray, $GUI_DISABLE)
_controlArraySetState("AVG", $programNames, "Install", $controlText, $guiControlArray, $GUI_DISABLE)
_controlArraySetState("AVG", $programNames, "Update", $controlText, $guiControlArray, $GUI_DISABLE)
_controlArraySetState("AVG", $programNames, "Run", $controlText, $guiControlArray, $GUI_DISABLE)
_controlArraySetState("AVG", $programNames, "Uninstall", $controlText, $guiControlArray, $GUI_DISABLE)
_controlArraySetState("Defrag", $programNames, "Download", $controlText, $guiControlArray, $GUI_HIDE)
_controlArraySetState("Defrag", $programNames, "Install", $controlText, $guiControlArray, $GUI_HIDE)
_controlArraySetState("Defrag", $programNames, "Update", $controlText, $guiControlArray, $GUI_HIDE)
_controlArraySetState("Defrag", $programNames, "Uninstall", $controlText, $guiControlArray, $GUI_HIDE)


main()

Exit

;--------------------------------------------------------------------------------------------------

Func main()
    ;Just wait around for the events to do something
    While 1
        Sleep(60000)
        #cs
            Local $nMsg = GUIGetMsg()
            If $nMsg Then
            Switch $nMsg
            Case $GUI_EVENT_CLOSE
            Exit
            EndSwitch
            ;If $nMsg = $guiControlArray[0][1] Then
            ;   MsgBox(0, "Found", "Button0-1")
            ;EndIf
            EndIf
        #ce
    WEnd
EndFunc   ;==>main

;--------------------------------------------------------------------------------------------------
Func ExitProgram()
    Exit
EndFunc   ;==>ExitProgram

Func FuncDownload($program, $Control)
    ConsoleWrite("Pressed " & $Control & " button for program " & $program & @CR)
EndFunc   ;==>FuncDownload

Func FuncInstall($program, $Control)
    ConsoleWrite("Pressed " & $Control & " button for program " & $program & @CR)
EndFunc   ;==>FuncInstall

Func FuncUpdate($program, $Control)
    ConsoleWrite("Pressed " & $Control & " button for program " & $program & @CR)
EndFunc   ;==>FuncUpdate

Func FuncRun($program, $Control)
    ConsoleWrite("Pressed " & $Control & " button for program " & $program & @CR)
EndFunc   ;==>FuncRun

Func FuncUninstall($program, $Control)
    ConsoleWrite("Pressed " & $Control & " button for program " & $program & @CR)
EndFunc   ;==>FuncUninstall



;--------------------------------------------------------------------------------------------------
; GUI Control Routines
Func _controlArrayCreate($programNames, $controlText, $controlTypes, $controlWidth, $controlHeight, ByRef $guiControlArray)
    Local $tempText = ""
    ;Create controls
    For $p = 0 To $numPrograms - 1
        For $c = 0 To $numControls - 1
            ; First element is always program name
            If $c = 0 Then
                $tempText = $programNames[$p]
            Else
                $tempText = $controlText[$c]
            EndIf
            
            Select
                Case $controlTypes[$c] = "Checkbox"
                    $guiControlArray[$p][$c] = GUICtrlCreateCheckbox($tempText, 0, 0, $controlWidth[$c], $controlHeight)
                    If $functionNames[$c] Then
                        SetOnEventA(-1, $functionNames[$c], $paramByVal, $programNames[$p], $paramByVal, $controlText[$c])
                        ConsoleWrite("SetOnEventA(-1, " & $functionNames[$c] & ", $paramByVal, " & $programNames[$p] & " " & $controlText[$c] & @CR)
                    EndIf
                Case $controlTypes[$c] = "Button"
                    $guiControlArray[$p][$c] = GUICtrlCreateButton($tempText, 0, 0, $controlWidth[$c], $controlHeight, $BS_FLAT)
                    If $functionNames[$c] Then
                        SetOnEventA(-1, $functionNames[$c], $paramByVal, $programNames[$p], $paramByVal, $controlText[$c])
                        ConsoleWrite("SetOnEventA(-1, " & $functionNames[$c] & ", $paramByVal, " & $programNames[$p] & " " & $controlText[$c] & @CR)
                    EndIf
                Case $controlTypes[$c] = "Label"
                    $guiControlArray[$p][$c] = GUICtrlCreateLabel($tempText, 0, 0, $controlWidth[$c], $controlHeight, $BS_FLAT)
            EndSelect
        Next
    Next
EndFunc   ;==>_controlArrayCreate

Func _controlArrayDisplay($groupLeft, $groupTop, $groupHeightSpacing, $groupWidthSpacing, $guiControlArray)
    
    ; calc left position of each control
    Local $tempLeft = $groupLeft
    Local $controlLeft[$numControls]
    For $c = 0 To $numControls - 1
        $controlLeft[$c] = $tempLeft
        $tempLeft += $controlWidth[$c] + $groupWidthSpacing
    Next

    ;Move controls
    For $p = 0 To $numPrograms - 1
        For $c = 0 To $numControls - 1
            GUICtrlSetPos($guiControlArray[$p][$c], $controlLeft[$c], $groupTop + (($controlHeight + $groupHeightSpacing) * $p))
        Next
    Next
EndFunc   ;==>_controlArrayDisplay

Func _controlArraySetState($program, $programNames, $Control, $controlText, $guiControlArray, $state)
    Local $programIndex = _ArraySearch($programNames, $program, 0, 0, 0, 1)
    Local $controlIndex = _ArraySearch($controlText, $Control, 0, 0, 0, 1)
    
    If ($programIndex <> -1) And ($controlIndex <> -1) Then
        GUICtrlSetState($guiControlArray[$programIndex][$controlIndex], $state)
    Else
        ; Can't find program and/or control
        Return -1
    EndIf
EndFunc   ;==>_controlArraySetState

Thanks for any/all feedback

John Morrison

Edited by storme

Share this post


Link to post
Share on other sites
martin

I would recommend using the built-in guiscroll bars. They are a bit more difficult to use than Kip's but they are also more flexible. If you add the style $WS_SIZEBOX to your gui, which is desirable in a lot of applications, and fix the positions of the controls with

Local $Form1 = GUICreate("Select function to perform", 560, 200, 192, 124, BitOR($GUI_SS_DEFAULT_GUI, $WS_SIZEBOX))
Opt("GUIResizeMode", BitOR($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKWIDTH, $GUI_DOCKHEIGHT))

then you will see that the scroll bar does not change correctly. It's not obvious to me how you fix that with Kip's udf.

I posted a similar sort of applicatiopn here which used the AutoIt scrollbars. The scrollbars need extra work but for simply resizing the window and scrolling around they are fine.

Using the OnEvent udf is of coarse a truly excellent move ^_^


Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
Share on other sites
storme

Hi Martin

I've never had much luck with GUI development, I waste too much time trying to get it perfect and end up with a mess. Which is why I've been working on this code, plug some data in, run the program and hay presto. I'm surprised that no one has made anything like it before. Well I haven't found any. There are so many situations where you want a list of items that can be "ticked" off and run.

What I'd like to to be able to set up scrollable box containing the controls but I have no idea how to do that. Which is why I'm using Kip's UDF as it made it easy to add scrolling to the whole thing.

Thanks for the "style $WS_SIZEBOX" I've added it to the code so it is now resizable and as you said the scroll bars aren't working properly....sigh

I saw your "String grid" and it looks great! So should only take a few more lines and you have Excel...right...^_^ only joking!

The On event UDF was a god send I had the code hacked together but nothing to handle the actual button presses then up pops the UDF...HMMM nice ;)

BTW if you're interested here is the latest version of the script now with a RUNALL system. Tick/untick the "runall" and all the programs get ticked or unticked. Click a button on "runall" and that function will be run for all ticked programs (that have that function available). Seems to work well.

Good Luck with your program

John Morrison

; ================================================================
; Name...........: GUI_Control_Grid
; Description ...: Creates an interactive array of controls
; Syntax.........: Only "proof of concept" look in code
; Parameters ....: N/A
; Return values .: N/A
; Author ........: John Morrison
; Modified.......: 05May09
; Remarks .......:
; Related .......:
; Link ..........: http://www.autoitscript.com/forum/index.php?showtopic=87870
; Example .......: Yes this file "proof of concept"
; ================================================================
Opt("GUIOnEventMode", 1)

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Compression=4
#AutoIt3Wrapper_Res_Fileversion=0.0.3.0
#AutoIt3Wrapper_Res_FileVersion_AutoIncrement=p
#AutoIt3Wrapper_Run_Tidy=y
#AutoIt3Wrapper_Run_Obfuscator=y
#Obfuscator_Parameters=/Striponly
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include "GUIScroll.au3"    ; http://www.autoitscript.com/forum/index.php?showtopic=79684
#include "onEventFunc.au3" ;http://www.autoitscript.com/forum/index.php?showtopic=71811
#include <Array.au3>

Global $numPrograms = 8
Global $numControls = 6 ; Number of buttons + Checkbox

; declare variables
Global $programNames[$numPrograms] = ["RUNALL", "Spybot", "Norton", "AVG", "Defrag", "prog1", "prog2", "prog3"]
Global $controlText[$numControls] = ["", "Download", "Install", "Update", "Run", "Uninstall"] ; First element will be replaced by program name
Global $controlTypes[$numControls] = ["Checkbox", "Button", "Button", "Button", "Button", "Button"]
;Local $functionNames[$numControls] = ["", "FuncDownload", "FuncInstall", "FuncUpdate", "FuncRun", "FuncUninstall"] ; blank "" entries mean no function to call
Global $functionNames[$numControls] = ["GUIDOIT", "GUIDOIT", "GUIDOIT", "GUIDOIT", "GUIDOIT", "GUIDOIT"] ; blank "" entries mean no function to call
Local $controlWidth[$numControls] = [60, 80, 80, 80, 80, 80]
Local $controlHeight = 20
Global $guiControlArray[$numPrograms][$numControls]

Local $groupLeft = 10 ; left most position for group
Local $groupTop = 20 ; Top most position for group
Local $groupHeightSpacing = 5 ; space between rows
Local $groupWidthSpacing = 10 ; Space between collumns

; actually create and display the GUIarray
;Local $Form1 = GUICreate("Select function to perform", 560, 200, 192, 124)
Local $Form1 = GUICreate("Select function to perform", 560, 200, 192, 124, BitOR($GUI_SS_DEFAULT_GUI, $WS_SIZEBOX))
Opt("GUIResizeMode", BitOR($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKWIDTH, $GUI_DOCKHEIGHT))
_controlArrayCreate($programNames, $controlText, $controlTypes, $controlWidth, $controlHeight, $guiControlArray)
_controlArrayDisplay($groupLeft, $groupTop, $groupHeightSpacing, $groupWidthSpacing, $guiControlArray)

SetOnEventA($GUI_EVENT_CLOSE, "ExitProgram")
GUISetState(@SW_SHOW)

;add scroll bars (Needs GUIScroll.au3 UDF)
Scrollbar_Step(20, $Form1, $SB_VERT); Scrolls per 20 pixels. If not set the default is 1 (smooth scrolling)
Scrollbar_Create($Form1, $SB_VERT, $groupTop + (($groupHeightSpacing + $controlHeight) * $numPrograms))

;Change button states
_controlArraySetState("Spybot", $programNames, "Download", $controlText, $guiControlArray, $GUI_DISABLE)
_controlArraySetState("Spybot", $programNames, "Install", $controlText, $guiControlArray, $GUI_DISABLE)
_controlArraySetState("Norton", $programNames, "Install", $controlText, $guiControlArray, $GUI_DISABLE)
_controlArraySetState("Norton", $programNames, "Update", $controlText, $guiControlArray, $GUI_DISABLE)
_controlArraySetState("Norton", $programNames, "Run", $controlText, $guiControlArray, $GUI_DISABLE)
_controlArraySetState("Norton", $programNames, "Uninstall", $controlText, $guiControlArray, $GUI_DISABLE)
_controlArraySetState("AVG", $programNames, "Install", $controlText, $guiControlArray, $GUI_DISABLE)
_controlArraySetState("AVG", $programNames, "Update", $controlText, $guiControlArray, $GUI_DISABLE)
_controlArraySetState("AVG", $programNames, "Run", $controlText, $guiControlArray, $GUI_DISABLE)
_controlArraySetState("AVG", $programNames, "Uninstall", $controlText, $guiControlArray, $GUI_DISABLE)
_controlArraySetState("Defrag", $programNames, "Download", $controlText, $guiControlArray, $GUI_HIDE)
_controlArraySetState("Defrag", $programNames, "Install", $controlText, $guiControlArray, $GUI_HIDE)
_controlArraySetState("Defrag", $programNames, "Update", $controlText, $guiControlArray, $GUI_HIDE)
_controlArraySetState("Defrag", $programNames, "Uninstall", $controlText, $guiControlArray, $GUI_HIDE)


main()

Exit

;--------------------------------------------------------------------------------------------------

Func main()
    ;Just wait around for the events to do something
    While 1
        Sleep(60000)
        #cs
            Local $nMsg = GUIGetMsg()
            If $nMsg Then
            Switch $nMsg
            Case $GUI_EVENT_CLOSE
            Exit
            EndSwitch
            ;If $nMsg = $guiControlArray[0][1] Then
            ;   MsgBox(0, "Found", "Button0-1")
            ;EndIf
            EndIf
        #ce
    WEnd
EndFunc   ;==>main

;--------------------------------------------------------------------------------------------------
Func ExitProgram()
    Exit
EndFunc   ;==>ExitProgram

Func GUIDOIT($program, $Control)
    Local $tempState
    If $program <> "RUNALL" Then
        ; Single Control
        If $Control <> "" Then
            ConsoleWrite($Control & " STARTED for " & $program & @CR)
        EndIf
    Else
        ; RUNALL Control Pressed - Run selected function for all 'checked' programs
        
        ;Check if it's the check box that has been clicked
        If $Control = "" Then
            ;Echo RUNALL checkbox to all checkboxes
            $tempState = GUICtrlRead($guiControlArray[0][0])
            For $p = 1 To $numPrograms - 1
                GUICtrlSetState($guiControlArray[$p][0], $tempState)
            Next
        Else
            Local $controlIndex = _ArraySearch($controlText, $Control, 0, 0, 0, 1)
            For $p = 1 To $numPrograms - 1
                ;Check Checkbox
                If GUICtrlRead($guiControlArray[$p][0]) = $GUI_CHECKED Then
                    ;Check Button Enabled and not hidden
                    $tempState = GUICtrlGetState($guiControlArray[$p][$controlIndex])
                    If BitAND($tempState, $GUI_ENABLE) And (Not (BitAND($tempState, $GUI_HIDE))) Then
                        ConsoleWrite($Control & " STARTED for " & $programNames[$p] & @CR)
                    EndIf
                EndIf
            Next
        EndIf
    EndIf
    ConsoleWrite(@CR)
EndFunc   ;==>GUIDOIT

;--------------------------------------------------------------------------------------------------
; GUI Control Routines
Func _controlArrayCreate($programNames, $controlText, $controlTypes, $controlWidth, $controlHeight, ByRef $guiControlArray)
    Local $tempText = ""
    ;Create controls
    For $p = 0 To $numPrograms - 1
        For $c = 0 To $numControls - 1
            ; First element is always program name
            If $c = 0 Then
                $tempText = $programNames[$p]
            Else
                $tempText = $controlText[$c]
            EndIf
            
            Select
                Case $controlTypes[$c] = "Checkbox"
                    $guiControlArray[$p][$c] = GUICtrlCreateCheckbox($tempText, 0, 0, $controlWidth[$c], $controlHeight)
                    If $functionNames[$c] Then
                        SetOnEventA(-1, $functionNames[$c], $paramByVal, $programNames[$p], $paramByVal, $controlText[$c])
                        ;ConsoleWrite("SetOnEventA(-1, " & $functionNames[$c] & ", $paramByVal, " & $programNames[$p] & " " & $controlText[$c] & @CR)
                    EndIf
                Case $controlTypes[$c] = "Button"
                    $guiControlArray[$p][$c] = GUICtrlCreateButton($tempText, 0, 0, $controlWidth[$c], $controlHeight, $BS_FLAT)
                    If $functionNames[$c] Then
                        SetOnEventA(-1, $functionNames[$c], $paramByVal, $programNames[$p], $paramByVal, $controlText[$c])
                        ;ConsoleWrite("SetOnEventA(-1, " & $functionNames[$c] & ", $paramByVal, " & $programNames[$p] & " " & $controlText[$c] & @CR)
                    EndIf
                Case $controlTypes[$c] = "Label"
                    $guiControlArray[$p][$c] = GUICtrlCreateLabel($tempText, 0, 0, $controlWidth[$c], $controlHeight, $BS_FLAT)
            EndSelect
        Next
    Next
EndFunc   ;==>_controlArrayCreate

Func _controlArrayDisplay($groupLeft, $groupTop, $groupHeightSpacing, $groupWidthSpacing, $guiControlArray)
    
    ; calc left position of each control
    Local $tempLeft = $groupLeft
    Local $controlLeft[$numControls]
    For $c = 0 To $numControls - 1
        $controlLeft[$c] = $tempLeft
        $tempLeft += $controlWidth[$c] + $groupWidthSpacing
    Next

    ;Move controls
    For $p = 0 To $numPrograms - 1
        For $c = 0 To $numControls - 1
            GUICtrlSetPos($guiControlArray[$p][$c], $controlLeft[$c], $groupTop + (($controlHeight + $groupHeightSpacing) * $p))
        Next
    Next
EndFunc   ;==>_controlArrayDisplay

Func _controlArraySetState($program, $programNames, $Control, $controlText, $guiControlArray, $state)
    Local $programIndex = _ArraySearch($programNames, $program, 0, 0, 0, 1)
    Local $controlIndex = _ArraySearch($controlText, $Control, 0, 0, 0, 1)
    
    If ($programIndex <> -1) And ($controlIndex <> -1) Then
        GUICtrlSetState($guiControlArray[$programIndex][$controlIndex], $state)
    Else
        ; Can't find program and/or control
        Return -1
    EndIf
EndFunc   ;==>_controlArraySetState

Share this post


Link to post
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
Sign in to follow this  

×