Jump to content

help with list


Recommended Posts

I am currently using ToolTips to display the contents of a 3 column array. This is messy as I cannot keep the data in a nice list - I am currently using @TAB to space each column but it is never in line as the names of the entries variy. My next thought is to start looking at GUI which I have never used before and would rather use for this script but I am getting trouble making a list which I can update easily with status etc ...

Example I want to create from an array

Array

Col1 Col2 Col3

App1 .exe Staus ???

app2 .cmd status ???

app3 .bat status ???

The above is the array I already have created. What I now want to do is create a nice ordered list as above on screen with the 3rd column easily updatable.

I have played around with Gui but I am struggling to get to a point where I can find the row I want to update and then change the 3rd colums only. I am now getting in a mess and am wondering there must be a better way of doing this.

My script is below

#include <Array.au3>
#include <GUIConstants.au3>


;PROCESS NETWORK ONLY INSTALLATIONS ARRAY
;----------------------------------------
    $ListofNetOnlyAppsFullPaths = "testPackage1:1.exe#testPackage2:2.exe#testPackage3:3.exe#testPackage4:4.exe#testPackage5:5.exe"

    If $ListofNetOnlyAppsFullPaths <> "" Then 
        $ArrayOfNetOnlyInstalls = StringSplit($ListofNetOnlyAppsFullPaths, "#")
        
        dim $yPlace = 1
        Dim $y = 0
        Global $3dNetworkInstallArray[$yPlace][4] 
        
        
    ;Create 3D array of Network only applications  
    ;-------------------------  ARRAY -------------------------------------------
    ;---- Friendly Name --- Full Exe Path --- Completion State --- GUI Control ID
    ;-------------------------  ARRAY -------------------------------------------
        
        For $Element in $ArrayOfNetOnlyInstalls 
            
            If $y <> 0 Then
                
                $yPlace = $yPlace + 1
                redim $3dNetworkInstallArray[$yPlace][4]
                
            EndIf
        
            $SplitUp = StringSplit($Element, ":")
            
            If IsArray($SplitUp) Then 
            
                $SizeOfArray =  Ubound($SplitUp)
                If $SizeOfArray <> 3 Then ContinueLoop
            
                $3dNetworkInstallArray[$y][0] = $SplitUp[1]
                $3dNetworkInstallArray[$y][1] = $SplitUp[2]
                $3dNetworkInstallArray[$y][2] = "???"
                
                $y = $y + 1
                
            EndIf
            
        Next
        
    EndIf

    _ArrayDisplay($3dNetworkInstallArray)


    Dim $NetOnlyList = "Name Of Application" & @TAB & ":" & @TAB & "Progress" & @CRLF
    Dim $MulticastList
    Dim $counter
    
    $NumOfRows = ubound($3dNetworkInstallArray)
    $y = 0
    $ControlID = 1
    Dim $Item
    
    GUICreate("listview items",220,250, 100,200,-1,$WS_EX_ACCEPTFILES )
    GUISetBkColor (0x00E0FFFF) ; will change background color
    $listview = GuiCtrlCreateListView ("ID | Application Name  | Progress ",10,10,200,150);,$LVS_SORTDESCENDING)
    $button = GuiCtrlCreateButton ("Value?",75,170,70,20)
    
    Do 
        GuiCtrlCreateListViewItem($ControlID & "|" & $3dNetworkInstallArray[$y][0] & "|" & $3dNetworkInstallArray[$y][2], $listview)
        $3dNetworkInstallArray[$y][3] = $ControlID;assigns the 4the column of the array a control ID so this can be found when changing status
        
        $y = $y + 1
        $counter = $counter + 1
        $ControlID = $ControlID + 1
        
    Until $counter = $NumOfRows
    
    
    GuiSetState()
    Sleep(5000)
Link to comment
Share on other sites

  • Moderators

bourny,

Add this to the top of your script:

#include <WindowsConstants.au3>
#Include <GuiListView.au3>

Change the GUICreate line to read (just to make the 3rd col of the LV more visible!):

GUICreate("listview items", 300,250, 100, 200, -1, $WS_EX_ACCEPTFILES )

Add this JUST BEFORE your Do...Until loop:

$StartID = GUICtrlCreateDummy()

And put this in place of your Sleep(5000):

$CurrentLVItem = ""

While 1 
    If GUIGetMsg() = -3 Then Exit
    
    If _GUICtrlListView_GetSelectedIndices($listview) <> $CurrentLVItem Then 
        ConsoleWrite(_GUICtrlListView_GetSelectedIndices($listview) & @CRLF)
        $CurrentLVItem = _GUICtrlListView_GetSelectedIndices($listview)
        GUICtrlSetData($StartID + $CurrentLVItem + 1, $ControlID & "|" & $3dNetworkInstallArray[$CurrentLVItem][0] & "|" & "Change")
    EndIf
WEnd

Now if you click on a LV line, the 3rd col text will alter. Over to you to decide what it alters to!

Before you ask, the Dummy control just acts as a marker so that you can calulate the ControlID of the selected ListViewItem. Ask if anything else is unclear.

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Thanks for that. I see how you are working this ... I staill have a gap of knowledge on the problem I have with getting my script to update this GUI when it has completed processing one of the files in the list. This loop appears to need a user to click on the control to change it. I dont want the user to interact with the gui - I simply want the script to update the Gui 3rd column when I have processed one of the list.

Example.

Build GUI from the array I have made.

Gui is simply the users way of seeing the progess of the list . The list in this case is an installation list. Applications 1 - 5 will get installed.

Once the application is installed it will update the 3rd column to state Complete.

My other lack of understanding is once the GUI is built it needs to go into loop to get the input but I dont want to stay in a loop but instead build the GUI then move to different functions to do other work - When I am ready I need to then go back to update the 3rd column with the outcome of the installation. I am guessing I may need to put the GUI into an adlib or I may be misunderstanding how GUI works.

Much appreciation for helping me with my lack of knowledge. I am keen to crack the GUI side for this project I have...

Thanks

bourny,

Add this to the top of your script:

#include <WindowsConstants.au3>
#Include <GuiListView.au3>

Change the GUICreate line to read (just to make the 3rd col of the LV more visible!):

GUICreate("listview items", 300,250, 100, 200, -1, $WS_EX_ACCEPTFILES )

Add this JUST BEFORE your Do...Until loop:

$StartID = GUICtrlCreateDummy()

And put this in place of your Sleep(5000):

$CurrentLVItem = ""

While 1 
    If GUIGetMsg() = -3 Then Exit
    
    If _GUICtrlListView_GetSelectedIndices($listview) <> $CurrentLVItem Then 
        ConsoleWrite(_GUICtrlListView_GetSelectedIndices($listview) & @CRLF)
        $CurrentLVItem = _GUICtrlListView_GetSelectedIndices($listview)
        GUICtrlSetData($StartID + $CurrentLVItem + 1, $ControlID & "|" & $3dNetworkInstallArray[$CurrentLVItem][0] & "|" & "Change")
    EndIf
WEnd

Now if you click on a LV line, the 3rd col text will alter. Over to you to decide what it alters to!

Before you ask, the Dummy control just acts as a marker so that you can calulate the ControlID of the selected ListViewItem. Ask if anything else is unclear.

M23

Link to comment
Share on other sites

I managed to do the following - The script I have changed is below the do until loop. I remmed out the while loop and added a GUICtrlSetData command. I guessed at the $StartID + # to change the column I want.

The problem is I dont understand why the ControlID needs the plus # otherwise it just updates the title row. The second thing is I dont know how to get the correct controlID number based on the application I am updating. Lets say I want to update the testpackage4 field - How do I get the GUICtrlSetData to do this . I tried putting the Gui in a for next loop to read out each column to detect the correct row but it does not work in for next loop that I would usually use to read down an array.

I am getting there but bumbling about

Do

GuiCtrlCreateListViewItem($StartID & "|" & $3dNetworkInstallArray[$y][0] & "|" & $3dNetworkInstallArray[$y][2], $listview)

$3dNetworkInstallArray[$y][3] = $StartID

$y = $y + 1

$counter = $counter + 1

$ControlID = $ControlID + 1

Until $counter = $NumOfRows

GuiSetState()

Sleep(3000)

GUICtrlSetData($StartID + 4, "||Change")

Sleep(5000)

;$CurrentLVItem = ""

;While 1

; If GUIGetMsg() = -3 Then Exit

;

; If _GUICtrlListView_GetSelectedIndices($listview) <> $CurrentLVItem Then

; ConsoleWrite(_GUICtrlListView_GetSelectedIndices($listview) & @CRLF)

; $CurrentLVItem = _GUICtrlListView_GetSelectedIndices($listview)

; GUICtrlSetData($StartID + $CurrentLVItem + 1, $ControlID & "|" & $3dNetworkInstallArray[$CurrentLVItem][0] & "|" & "Change")

; EndIf

;WEnd

Link to comment
Share on other sites

How are you going to be notified about the installation completion? If you don't want the user to interact with the GUI then you don't need a message loop.

For $i = 0 To 4
    _GUICtrlListView_SetItemText($hListView, $i, 'Installing...', 2)
    ; Install $ith application. 
    _GUICtrlListView_SetItemText($hListView, $i, 'Completed', 2)
Next

If you want the user to close the window whenever he/she wants to you can use a message loop and some mechanism like a counter for the current running installation application and check the existence of the installation process by using AdlibEnable() function or _Timer_SetTimer(). Then with this counter you'll add another item to the list and update it.

Link to comment
Share on other sites

The job of the script is to pull a list of entries from the registry left behind from another script. This list is a list of application names that need installing. I simply read this into an array and then work down the array installing the applications in the list. During the installs I simply need to put a box up on the screen that lists the applications and when completing them it updates the box to inform the user what is going on or the progress of the installations.

The script therefore will need to update the progress GUi and then close once it has completed its tasks. As I said on my first post I can easily do this all with ToolTips / TrayTips but it cannot align the colums very well and ends up all over the place depending on the size of the filenames I am installing. This is the reason I am trying to use GUI however I DO NOT want the user to update or do anything with the GUI.

Many Thanks

How are you going to be notified about the installation completion? If you don't want the user to interact with the GUI then you don't need a message loop.

For $i = 0 To 4
    _GUICtrlListView_SetItemText($hListView, $i, 'Installing...', 2)
    ; Install $ith application. 
    _GUICtrlListView_SetItemText($hListView, $i, 'Completed', 2)
Next

If you want the user to close the window whenever he/she wants to you can use a message loop and some mechanism like a counter for the current running installation application and check the existence of the installation process by using AdlibEnable() function or _Timer_SetTimer(). Then with this counter you'll add another item to the list and update it.

Link to comment
Share on other sites

OK Authenticity -

I managed to get your snippet to work by changing one of the variables to $listview (Below). This goes down the list and changes each one in order. This is nearly where I need to be. How do I do the sdame thing but not in an order of top to bottom Can I do the loop but inside the loop read the rows and if a string for the applicatrion name matches the row is detected I just update that one row. ... My script may not complete all the installs in oder hence the reason I want to update the fields in a random fashion.....

Many thanks for your help

For $i = 0 To 4

_GUICtrlListView_SetItemText($listview, $i, 'Installing...', 2)

; Install $ith application.

Sleep(1000)

_GUICtrlListView_SetItemText($listview, $i, 'Completed', 2)

Next

Link to comment
Share on other sites

  • Moderators

bourny,

Then Authenticy's code should be what you want. Just run through the list installing each app and use _GUICtrlListView_SetItemText to change the value when the install is complete.

The problem is I dont understand why the ControlID needs the plus # otherwise it just updates the title row.

You need to define the index of the row you want to change. In Authenticity's code he uses _GUICtrlListView_SetItemText - in this function he adresses the list rows directly via their index $i.

I was using another function (GUICtrlSetData) which reset the data for the whole row based on its ControlID. These ControlID values are set sequentially by AutoIt when it creates the LV (and other controls) and need to be calculated to get the correct value for the LV row in question. I got the row index by using _GUICtrlListView_GetSelectedIndices and then had to convert it to the ControlID - that is why I used the dummy control as a pointer.

Authenticity's code is tighter (as usual!) and I probably should have coded the original as:

While 1 
    If GUIGetMsg() = -3 Then Exit
    
    If _GUICtrlListView_GetSelectedIndices($listview) <> $CurrentLVItem Then 
        $CurrentLVItem = _GUICtrlListView_GetSelectedIndices($listview)
        _GUICtrlListView_SetItemText($listView, $CurrentLVItem, 'Change', 2)
    EndIf
WEnd

I can only offer the excuse that I cut and pasted from another script where I replace the whole row in one go. ;-)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

I appreciate all your help - I am nearly where I want ot be. I can see that Authenticity is not referencing pre indexed variables but I am not fussed which way I do it.

If I use preindexed variables assigned to each row then I can easily update the row when necessary by writing the index to the array I have then reading the array to obtain the index reference if you get my drift - This is what I originally set out to do buthave failed to pull it off. Authenticitys way of doing this is also workable but If i read down every row each time I want to update the Gui I need to beable to detect the row I want bt detecting the text in the row that matches the install I am doing .... This may be messy hence I would prefer to build the row and get the ControlID written to my array so I can reference it once I want to update that row.

I think both solutions are nearly there but not quite allowing me to do the above.

I am trying to play with both sets of scripts but without a good knowledge of GUI i am still just guessing

Thanks

Link to comment
Share on other sites

  • Moderators

bourny,

You can get the text by using _GUICtrlListView_GetItemText. So you might want to code something like this:

For $i = To however_many_apps_you_are_checking
    ; Get app name from first element of the row
    $app_name = _GUICtrlListView_GetItemText($listview, $i, 0)
    ; Do I need to install it?
    If some-kind-of-check_says_Yes Then
        ;Install app
        _GUICtrlListView_SetItemText($listView, $i, 'Installed', 2)
    EndIf
Next

Does that help?

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Thanks for the update... I will take a look at your script to see if it will assist but I have been using the help you have both provided to work out what I was doing wrong initially. I have gone with writing the index of the gui row to the array I am using to rereference and update - Have a look at my script and see what you think... All I need to do now is make the Gui a little prittier and write the install functions. I have just done a simulation of the installs using trayTips.

#include <Array.au3>
#include <GUIConstants.au3>
#include <WindowsConstants.au3>
#Include <GuiListView.au3>

;PROCESS NETWORK ONLY INSTALLATIONS ARRAY
;----------------------------------------
    $ListofNetOnlyAppsFullPaths = "testPackage1:1.exe#testPackage2:2.exe#testPackage3:3.exe#testPackage4:4.exe#testPackage5:5.exe"

    If $ListofNetOnlyAppsFullPaths <> "" Then 
        $ArrayOfNetOnlyInstalls = StringSplit($ListofNetOnlyAppsFullPaths, "#")
        
        dim $yPlace = 1
        Dim $y = 0
        Global $3dNetworkInstallArray[$yPlace][4] 
        
        
    ;Create 3D array of Network only applications  
    ;-------------------------  ARRAY -------------------------------------------
    ;---- Friendly Name --- Full Exe Path --- Completion State --- GUI Control ID
    ;-------------------------  ARRAY -------------------------------------------
        
        For $Element in $ArrayOfNetOnlyInstalls 
            
            If $y <> 0 Then
                
                $yPlace = $yPlace + 1
                redim $3dNetworkInstallArray[$yPlace][4]
                
            EndIf
        
            $SplitUp = StringSplit($Element, ":")
            
            If IsArray($SplitUp) Then 
            
                $SizeOfArray =  Ubound($SplitUp)
                If $SizeOfArray <> 3 Then ContinueLoop
            
                $3dNetworkInstallArray[$y][0] = $SplitUp[1]
                $3dNetworkInstallArray[$y][1] = $SplitUp[2]
                $3dNetworkInstallArray[$y][2] = "???"
                
                $y = $y + 1
                
            EndIf
            
        Next
        
    EndIf

;_ArrayDisplay($3dNetworkInstallArray)


    Dim $NetOnlyList = "Name Of Application" & @TAB & ":" & @TAB & "Progress" & @CRLF
    Dim $MulticastList
    Dim $counter
    
    $NumOfRows = ubound($3dNetworkInstallArray)
    $y = 0
    $ControlID = 1
    Dim $Item
    
    GUICreate("listview items", 500,500, 100, 200, -1, $WS_EX_ACCEPTFILES )
;GUICreate("listview items",220,250, 100,200,-1,$WS_EX_ACCEPTFILES)
    GUISetBkColor (0x00E0FFFF) ; will change background color
    Global $listview = GuiCtrlCreateListView ("ID | Application Name  | Progress ",10,10,400,300);,$LVS_SORTDESCENDING)
    $button = GuiCtrlCreateButton ("Value?",75,170,70,20)
    
    
    BuildGUI()
    InstallApps()
    
    MsgBox(0, "", "End of installs")
    
    
    
    
Func InstallApps()
    
;This function will simulate installing the applications in non orderly fashion
;This 
    
    
    TrayTip("Installing", "TestPackage1", 30, 1)
    Sleep(2000)
    UpdateGUI("TestPackage1", "Installed OK")
    
    Sleep(2000)
    
    TrayTip("Installing", "TestPackage5", 30, 1)
    Sleep(2000)
    UpdateGUI("TestPackage5", "Delaying until on network")
    
    Sleep(2000)
    
    TrayTip("Installing", "TestPackage2", 30, 1)
    Sleep(2000)
    UpdateGUI("TestPackage2", "Installed OK")
    
    Sleep(2000)
    
    TrayTip("Installing", "TestPackage3", 30, 1)
    Sleep(2000)
    UpdateGUI("TestPackage3", "Installed OK")
    
    
    Sleep(2000)
    
    TrayTip("Installing", "TestPackage4", 30, 1)
    Sleep(2000)
    UpdateGUI("TestPackage4", "Failed to find package")
    
    Sleep(2000)
    
    
EndFunc


    

Func BuildGUI()
    
;Build Gui and write ControlID to the 4th column of the control array
;--------------------------------------------------------------------
    Dim $StartID = 0
    
    Do 
        
        GuiCtrlCreateListViewItem($StartID & "|" & $3dNetworkInstallArray[$y][0] & "|" & $3dNetworkInstallArray[$y][2], $listview)
        $3dNetworkInstallArray[$y][3] = $StartID
        $StartID = $StartID + 1
        $y = $y + 1
        $counter = $counter + 1
        
        
    Until $counter = $NumOfRows
;-------------------------
    GuiSetState()
    
    Sleep(2000)
    
EndFunc

    
    
Func UpdateGUI($Package, $StatusOfPackage)
    
    $Result = _ArraySearch($3dNetworkInstallArray, $Package, 0, 0, 0, 1, 1)
    
     _GUICtrlListView_SetItemText($listView, $3dNetworkInstallArray[$Result][3], $StatusOfPackage, 2)
    
    sleep(2000)
    
EndFunc
Link to comment
Share on other sites

  • 3 weeks later...

I got a similar problem. I copied from help the code for making a listview and altered it to my needs. I just need to fill it with a changing list of clients extracted from an excel sheet.

I keep getting the same result as in the help file.

I know the line Dim $XLArrayName[5000][1] is what is causing one the problems. And perhaps I am not using _GUICtrlListView_AddArray correctly. I know the data is there because when I do an _ArrayDisplay ($XLArrayName, "Name") it shows me all the names.

CODE
#AutoIt3Wrapper_au3check_parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6

#include <GuiConstantsEx.au3>

#include <GuiListView.au3>

#include <ExcelCOM_UDF.au3>

Opt('MustDeclareVars', 1)

$Debug_LV = False ; Check ClassName being passed to ListView functions, set to True and use a handle to another control to see it work

Global $XLFilePath = @TempDir & "\uh_patsumnm_excel.xls"

Global $oExcel, $XLArrayName

$oExcel = _ExcelBookOpen($XLFilePath, @SW_HIDE)

;~ $oExcel = _ExcelBookOpen($XLFilePath)

$XLArrayName =_ExcelReadArray($oExcel, 1, 1, 500, 1); Get the client's name.

_ExcelBookClose ($oExcel)

_Main()

Func _Main()

Local $iI,$hListView

; Create GUI

GUICreate("ListView Add Array", 400, 300)

$hListView = GUICtrlCreateListView("", 2, 2, 394, 268)

_GUICtrlListView_SetUnicodeFormat($hListView, False)

GUISetState()

; Add columns

_GUICtrlListView_AddColumn($hListView, "Clients", 100)

_GUICtrlListView_SetItemCount($hListView, 5000)

; One column load

Dim $XLArrayName[5000][1]

For $iI = 0 To UBound($XLArrayName) - 1

$XLArrayName[$iI][0] = "Client " & $iI

Next

_GUICtrlListView_AddArray($hListView, $XLArrayName)

Do

Until GUIGetMsg() = $GUI_EVENT_CLOSE

GUIDelete()

Exit

EndFunc ;==>_Main

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