Jump to content
Karnalsyn

Dynamically resizing GUI

Recommended Posts

Hi all,

I'm in the process of generating a script that will allow our technicians to queue up and perform adhoc software installations after a PC reimage. I've got a barebones script at the moment using koda gui. See image

1385116966_adhocinstaller.png.c06fca48363084d4f2d382061363cece.png

 

It gives the technician a browse button that points to our software repo. Hitting start executes the file. I plan to further expand on this concept, adding custom entry for command line switches, logging of execution results to target system, as well as I'd like to incorporate a system where each line updates with a Red X or Green CHECK to visually represent the success or failure of the Runwait command triggered by the Start button. I'm not sure how I'm going to accomplish the X/CHECK feature yet...

Additionally, I'd like that 1 browse line to be many browse lines. I can easily go into the script and expand the box and add 4 more, 9 more, etc. But what I would prefer to do is have that GUI give the user a -/+ button. Clicking + adds another browse line, clicking - removes it. I'd like if the GUI could size up or down based on the number of lines being added or removed. Unfortunately as much as I know about AutoIT. I'm still new in certain areas...GUIs being one of them. Has anyone handled this type of thing before or have a better idea on the approach I should take? Thanks!

This is the current code:

#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#Region ### START Koda GUI section ### Form=
$Form1_1 = GUICreate("Technician Services Custom Package Installer", 463, 267, 192, 124)
$Button1 = GUICtrlCreateButton("Browse", 336, 16, 99, 25)
$Input1 = GUICtrlCreateInput("Browse for Application", 40, 16, 281, 21)
$Button2 = GUICtrlCreateButton("Start", 176, 168, 75, 25)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

While 1
 $nMsg = GUIGetMsg()
 Switch $nMsg
  Case $GUI_EVENT_CLOSE
   Exit
        Case $Button1
            $sPath = FileOpenDialog("Select an application for install", "\\servername\foldername\foldername\testfoldername\", "All file (*.*)")
            GUICtrlSetData($Input1, $sPath)
  Case $Button2
   RunWait($sPath)
   Exit
 EndSwitch
WEnd

Share this post


Link to post
Share on other sites

I know that it's not what you ask for.

It's an alternative solution on how to handle multiply selections.

A5XDEJA.png

Using a ListBox or perhaps a ListView, and allow the user to add the selection to that ListBox/View, and also supply a button (or an double click in the List*) to remove an item.

If you want to add/remove a ctrl you can use GUICtrlCreate and GUICtrlDelete, then use winmove to change the size of the GUI.

Using the While loop I belive that the ctrls should be created as arrays (Not sure on that, I normally uses on event mode for my GUI's)

 

Cheers
/Rex

Share this post


Link to post
Share on other sites
Posted (edited)

@Karnalsyn to expand on what Rex is saying, it is relatively easy, fundamentally, to do what you are after. For example, you could do something as basic as this to add another field.

#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

$Form1_1 = GUICreate("Technician Services Custom Package Installer", 463, 267, 192, 124)
$Button1 = GUICtrlCreateButton("Browse", 336, 16, 99, 25)
$Input1 = GUICtrlCreateInput("Browse for Application", 40, 16, 281, 21)
$Button2 = GUICtrlCreateButton("Start", 176, 168, 75, 25)
$btnAdd = GUICtrlCreateButton("Add", 10, 225, 100, 40)

GUISetState(@SW_SHOW)


While 1
 $nMsg = GUIGetMsg()
 Switch $nMsg
  Case $GUI_EVENT_CLOSE
   Exit
    Case $Button1
        $sPath = FileOpenDialog("Select an application for install", "\\servername\foldername\foldername\testfoldername\", "All file (*.*)")
        GUICtrlSetData($Input1, $sPath)
    Case $btnAdd
        $Input2 = GUICtrlCreateInput("Browse for another Application", 40, 50, 281, 21)
    Case $Button2
        RunWait($sPath)
        Exit
 EndSwitch
WEnd

But you need to think more about what you want in the longer term. Do you want them to be able to add 10 fields, or 20, or 100? How big is your GUI going to get? At some point you simply implement a "select another button, and keep all your paths in an array in the background, output to a listview, as Rex points out. Here is something similar I did a while back (modified):

#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

$Form1_1 = GUICreate("Technician Services Custom Package Installer", 463, 267, 192, 124)
$Button1 = GUICtrlCreateButton("Browse for Application", 10, 16, 140, 25)
$Button2 = GUICtrlCreateButton("Start", 10, 230, 75, 25)
$lstApps = GUICtrlCreateListView("Application|Parameters", 10, 50, 443, 100)

GUISetState(@SW_SHOW)

While 1
 $nMsg = GUIGetMsg()
 Switch $nMsg
  Case $GUI_EVENT_CLOSE
   Exit
    Case $Button1
        $sPath = FileOpenDialog("Select an application for install", "\\servername\foldername\foldername\testfoldername\", "All file (*.*)")
        $aSplit = StringSplit($sPath, "\")
        $sParams = InputBox("Enter parameters for " & $aSplit[$aSplit[0]], "Enter parameters")
        GUICtrlCreateListViewItem($sPath & "|" & $sParams, $lstApps)
    Case $Button2
        RunWait($sPath)
        Exit
 EndSwitch
WEnd

You then get a scrolling box; much easier for calculating the size of your GUI, for when you go to do your installs, and for when someone wants to select one application out of the list and delete it. Just a suggestion to think about :)

Edited by JLogan3o13

Share this post


Link to post
Share on other sites
Posted (edited)

Thanks you guys, I'm liking the options provided by both of you

Rex, any chance you have code you can link? I'm curious how the listbox allows for multiple, individually run entry options that I can call later. As an Array listing?

There are aspect of all 3 examples I could see myself attempting to leverage

Edited by Karnalsyn

Share this post


Link to post
Share on other sites

I think that I would do something like this

#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <GUIListBox.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <GuiListBox.au3>
#include <Array.au3>
Opt("GUIOnEventMode", 1)
#Region ### START Koda GUI section ### Form=
Global $Form1 = GUICreate("Form1", 349, 254, 886, 439)
GUISetOnEvent($GUI_EVENT_CLOSE, "Form1Close")
Global $idLbl_1 = GUICtrlCreateLabel("Browse for App:", 8, 8, 79, 17)
Global $idInp_1 = GUICtrlCreateInput("", 8, 24, 265, 21)
Global $idBtn_1 = GUICtrlCreateButton("&Browse", 280, 24, 59, 21)
GUICtrlSetOnEvent(-1, 'Browse')
Global $idBtn_2 = GUICtrlCreateButton("&Add to list", 8, 56, 75, 21)
GUICtrlSetOnEvent(-1, 'Add')
Global $idLbl_2 = GUICtrlCreateLabel("Apps to install:", 8, 88, 72, 17)
Global $idList_1 = GUICtrlCreateList("", 8, 104, 329, 110)
Global $idBtn_3 = GUICtrlCreateButton("&Start", 8, 224, 75, 21)
GUICtrlSetOnEvent(-1, 'Install')
Global $idBtn_4 = GUICtrlCreateButton("&Remove Selected", 240, 224, 100, 21)
GUICtrlSetOnEvent(-1, 'Remove')
GUISetState(@SW_SHOW)
; Set focus to the browse button
GUICtrlSetState($idBtn_1, $GUI_FOCUS)
#EndRegion ### END Koda GUI section ###

While 1
    Sleep(100)
WEnd

Func Form1Close()
    Exit
EndFunc   ;==>Form1Close

Func Browse()
    Local $sPath = FileOpenDialog("Select an application for install", "\\servername\foldername\foldername\testfoldername\", "All file (*.*)")
    GUICtrlSetData($idInp_1, $sPath)
    ; Set focus to the add button to allow the user to just hit enter to add the item
    GUICtrlSetState($idBtn_2, $GUI_FOCUS)
EndFunc   ;==>Browse

Func Add()
    ; Add selected item to ListBox
    GUICtrlSetData($idList_1, GUICtrlRead($idInp_1))
    ; Clear the Input
    GUICtrlSetData($idInp_1, '')
    ; Retur focus to the browse button
    GUICtrlSetState($idBtn_1, $GUI_FOCUS)
EndFunc   ;==>Add

Func Install()
    ; Reading items in the ListBox
    ; Method 1 just run the damn things
    For $i = 0 To _GUICtrlListBox_GetCount($idList_1) - 1
        RunWait(_GUICtrlListBox_GetText($idList_1, $i))
        ; Remove the executed item from the list, this gives the user a hint of where in the list we are
        _GUICtrlListBox_DeleteString($idList_1, $i)
    Next

    ; Method 2 create an array with the items from ListBox and the run the array
    ; We could create the read to array our self, but we'r lazy so we just use guinness from here
    ; https://www.autoitscript.com/forum/topic/145997-_guictrllistbox_createarray-create-an-array-from-a-listbox/
    Local $aItems = _GUICtrlListBox_CreateArray($idList_1)
    For $i = 1 To $aItems[0]
        RunWait($aItems[$i])
        ; Remove the executed item from the list, this gives the user a hint of where in the list we are
        _GUICtrlListBox_DeleteString($idList_1, $i - 1) ; We started at 1 not 0 so we have to substract 1 to get the correct index
    Next
EndFunc   ;==>Install

Func Remove()
    ; Remove selected item(s) from ListBox
    Local $aSelected = _GUICtrlListBox_GetSelItems($idList_1)
    ; Check that at least one item is selected, GetSelItems returns = 0 even it nothing is selected or exists in the ListBox
    If GUICtrlRead($idList_1) = "" Then Return
    For $i = 0 To $aSelected[0]
        _GUICtrlListBox_DeleteString($idList_1, $i)
    Next
EndFunc   ;==>Remove

; #FUNCTION# ====================================================================================================================
; Name ..........: _GUICtrlListBox_CreateArray
; Description ...: Creates a 1-dimensional array from a listbox.
; Syntax ........: _GUICtrlListBox_CreateArray($hListBox)
; Parameters ....: $hListBox            - Control ID/Handle to the control
; Return values .: Success - The array returned is one-dimensional and is made up of the following:
;                                $aArray[0] = Number of rows
;                                $aArray[1] = 1st row
;                                $aArray[2] = 2nd row
;                                $aArray[n] = nth row
; Author ........: guinness
; Remarks .......: GUICtrlListBox.au3 should be included.
; Example .......: Yes
; ===============================================================================================================================
Func _GUICtrlListBox_CreateArray($hListBox)
    Local $iItemCount = _GUICtrlListBox_GetCount($hListBox)
    Local $aReturn[$iItemCount + 1] = [$iItemCount]
    For $i = 0 To $iItemCount - 1
        $aReturn[$i + 1] = _GUICtrlListBox_GetText($hListBox, $i)
    Next
    Return SetError(Number($aReturn[0] = 0), 0, $aReturn)
EndFunc   ;==>_GUICtrlListBox_CreateArray

Ofc this is a fast and simple code, with not much error control.

But it should give you an idea of how it could be done

 

Cheers
/Rex

Share this post


Link to post
Share on other sites

I did a similar thing a few years back. I had a directory containing program folders. these folders contained setup files and an ini file with options to control the install and basic descriptions of the programs. 

The main installer scanned for ini files and added the installers to a listview. They could be manually checked\unchecked depending on PC\users or they could be automatically checked\unchecked depending on entries in the ini files

The software is setup to be installed automatically after 10 seconds unless you clicked the list view, then the timer stops and you can choose which programs to install. You can delete icons and and copy stuff after, it's been a while since I looked at it and forgot what else it can do. The coding is a bit all over the place and could do with a coat of looking at, got a bit more OCD since 😁

I have attached the files. There are sample inis but no installers. The program will go through the motions and prompt for reboot of windows. just abort that. Hopefully should give you some ideas.

Software Installer.7z

Share this post


Link to post
Share on other sites

Thanks everyone. Some good ideas and all quite varied in approach. This gives me a good place to start!

Really appreciate it

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

×
×
  • Create New...