Jump to content

Minimize/Close Gui During Progress Display


Recommended Posts

Hi there

Having trouble figuring out how to Minimize/Close Gui Window while ProgressBar Displays, is this possible?

Code below:

:: The Code will be used to create a software wrapper for Silent Application Installs via Corporate Network, however I'd like to give the end user a way of minimizing the install to the system tray, allowing the user to continue working. The code will read the required information for example "Display Name", "Version", "Command Line" etc.. from an .ini file inside the @scriptdir folder. For the sake of keeping the post small I've removed all the unnecessary code.

#include <Constants.au3>
#include <GUIConstantsEx.au3>
#include <ProgressConstants.au3>

Opt('GUIEventOptions',1)
Opt('TrayOnEventMode',1)
Opt('TrayMenuMode',1)   

TraySetOnEvent($TRAY_EVENT_PRIMARYUP, 'FNC_MAXIMISE')

$GUI_COMPANY = 'Company Name'
$GUI_DISPLAY = 'Software Name'
$GUI_VERSION = '1.0'
$RUN = 1
    $GUI_GUIWNDW = GUICreate($GUI_COMPANY, 365, 150, -1, -1, -1)

    $GUI_FNTNAME = 'Arial'
    GUISetBkColor(0xEEEEEE)
    GUISetFont(10, 800, 0, $GUI_FNTNAME)

    $GUI_LBLTITL = GUICtrlCreateLabel( $GUI_DISPLAY & ' '  & $GUI_VERSION, 10, 10, 345)
 
    GUISetFont(8.5, 800, 0, $GUI_FNTNAME)
    $GUI_LBLSUBT = GUICtrlCreateLabel('Installing ' & $GUI_DISPLAY & ', please wait...', 15, 45, 305)
    GUICtrlSetColor($GUI_LBLSUBT, 0X666666)

    GUISetFont(8, 400, 0, $GUI_FNTNAME)

    $GUI_LBLSTAT = GUICtrlCreateLabel('Status: Installing... - ', 25, 95, 109)
    GUICtrlSetColor($GUI_LBLSTAT, 0X666666)

    $GUI_GUIGRAPX = GUICtrlCreateGraphic(10, 35, 345, 1)
    GUICtrlSetBkColor(-1, 0x999999)
 
    $GUI_PROGBAR = GUICtrlCreateProgress (10, 70, 345, 15,$PBS_SMOOTH)

    $GUI_BTNMINIM = GUICtrlCreateButton('Minimise to System Tray»', 10, 125, 170, 20)
    $GUI_BTNCANCL = GUICtrlCreateButton('Cancel', 185, 125, 170, 20)

    GUISetState(@SW_SHOW)
    
    $PKG_RUNCMND = Run('notepad.exe')
    
    While 1
        $MSG = GUIGetMsg()
        Select 
            Case $RUN = 1
                For $i = 0 To 95 Step 1
                    Sleep(80)
                    GUICtrlSetData($GUI_PROGBAR, $i)
                Next
                $PID_RUNCMND = ProcessExists('notepad.exe')
                ProcessWaitClose($PID_RUNCMND)
                GUICtrlSetData($GUI_PROGBAR, 100)
                $PID_RUNCMND = ProcessExists('notepad.exe')
                If Not $PID_RUNCMND Then
                    Sleep(1250)
                    GUIDelete()
                    ExitLoop
                EndIf
            Case $MSG = $GUI_EVENT_MINIMIZE 
                FNC_MINIMISE()
            Case $MSG = $GUI_EVENT_CLOSE
                Exit
            Case $MSG = $GUI_BTNCANCL
                Exit
            Case $MSG = $GUI_BTNMINIM
                FNC_MINIMISE()
        EndSelect
    Wend

Func FNC_MINIMISE()
    GuiSetState(@SW_MINIMIZE)
    GuiSetState(@SW_HIDE)
    TraySetState(1)
    If @OSVersion = 'WIN_NT4' or @OSVersion = 'WIN_ME' or @OSVersion = 'WIN_98' or @OSVersion = 'WIN_95' then
        TraySetToolTip ($GUI_DISPLAY & 'Click here to Restore')
    Else
        Traytip ($GUI_DISPLAY, 'Click here to Restore', 5)
    EndIf
EndFunc

Func FNC_MAXIMISE()
    GuiSetState(@SW_RESTORE)
    GuiSetState(@SW_Show)
    TraySetState(2)
EndFunc

Any help with this would be greatly appreciated.

Cheers

Link to comment
Share on other sites

matrixnz

Example:

#include <Constants.au3>
#include <GUIConstantsEx.au3>
#include <ProgressConstants.au3>
#include <WindowsConstants.au3>

Opt('GUIEventOptions',1)
Opt('TrayOnEventMode',1)
Opt('TrayMenuMode',1)

Global $TimerProc_Handle, $EventId = 10001, $Elapse = 100, $ProgCount = 0

TraySetOnEvent($TRAY_EVENT_PRIMARYUP, 'FNC_MAXIMISE')

$GUI_COMPANY = 'Company Name'
$GUI_DISPLAY = 'Software Name'
$GUI_VERSION = '1.0'
$RUN = 1

$GUI_GUIWNDW = GUICreate($GUI_COMPANY, 365, 150, -1, -1, -1)

$GUI_FNTNAME = 'Arial'
GUISetBkColor(0xEEEEEE)
GUISetFont(10, 800, 0, $GUI_FNTNAME)

$GUI_LBLTITL = GUICtrlCreateLabel( $GUI_DISPLAY & ' '  & $GUI_VERSION, 10, 10, 345)
GUISetFont(8.5, 800, 0, $GUI_FNTNAME)
    
$GUI_LBLSUBT = GUICtrlCreateLabel('Installing ' & $GUI_DISPLAY & ', please wait...', 15, 45, 305)
GUICtrlSetColor($GUI_LBLSUBT, 0X666666)

GUISetFont(8, 400, 0, $GUI_FNTNAME)

$GUI_LBLSTAT = GUICtrlCreateLabel('Status: Installing... - ', 25, 95, 109)
GUICtrlSetColor($GUI_LBLSTAT, 0X666666)

$GUI_GUIGRAPX = GUICtrlCreateGraphic(10, 35, 345, 1)
GUICtrlSetBkColor(-1, 0x999999)

$GUI_PROGBAR = GUICtrlCreateProgress (10, 70, 345, 15,$PBS_SMOOTH)

$GUI_BTNMINIM = GUICtrlCreateButton('Minimise to System Tray»', 10, 125, 170, 20)
$GUI_BTNCANCL = GUICtrlCreateButton('Cancel', 185, 125, 170, 20)

GUISetState(@SW_SHOW)
    
$PKG_RUNCMND = Run('notepad.exe')
    
While 1
    $MSG = GUIGetMsg()
    Select 
        Case $RUN = 1
            $RUN = 0
            GUIRegisterMsg($WM_TIMER, "_Progress")
            DllCall("User32.dll", "int", "SetTimer", "hwnd", $GUI_GUIWNDW, "int", $EventId, "int", $Elapse, "int", 0)
        Case $MSG = $GUI_EVENT_MINIMIZE 
            FNC_MINIMISE()
        Case $MSG = $GUI_EVENT_CLOSE
            Exit
        Case $MSG = $GUI_BTNCANCL
            Exit
        Case $MSG = $GUI_BTNMINIM
            FNC_MINIMISE()
    EndSelect
Wend

GUIRegisterMsg($WM_TIMER, "")
DllCall("user32.dll", "int", "KillTimer", "hwnd", $GUI_GUIWNDW, "int", $EventId)

Func FNC_MINIMISE()
    GuiSetState(@SW_MINIMIZE)
    GuiSetState(@SW_HIDE)
    TraySetState(1)
    If @OSVersion = 'WIN_NT4' or @OSVersion = 'WIN_ME' or @OSVersion = 'WIN_98' or @OSVersion = 'WIN_95' then
        TraySetToolTip ($GUI_DISPLAY & 'Click here to Restore')
    Else
        Traytip ($GUI_DISPLAY, 'Click here to Restore', 5)
    EndIf
EndFunc

Func FNC_MAXIMISE()
    GuiSetState(@SW_RESTORE)
    GuiSetState(@SW_Show)
    TraySetState(2)
EndFunc

Func _Progress($hWnd, $Msg, $wParam, $lParam)
    If $ProgCount = 100 Then $ProgCount = 0
    $ProgCount += 1
    GUICtrlSetData($GUI_PROGBAR, $ProgCount)
EndFunc
Link to comment
Share on other sites

Thanks Rasim for your quick and brilliant response, the Gui Event messages and buttons work as they should which is great, however the progress bar just keeps looping even after killing the external process, which in the example above is Notepad.exe.

Now I tried appending the following to the _progress function:

Func _Progress($hWnd, $Msg, $wParam, $lParam)
    $ProgCount += 1
    GUICtrlSetData($GUI_PROGBAR, $ProgCount)
    If $ProgCount = 99 Then
        $PID_RUNCMND = ProcessExists('notepad.exe')
        ProcessWaitClose($PID_RUNCMND)
        GUICtrlSetData($GUI_PROGBAR, 100)
        $PID_RUNCMND = ProcessExists('notepad.exe')
        If Not $PID_RUNCMND Then
            Sleep(1250)
            GUIDelete()
        EndIf
    EndIf
EndFunc

To allow the program to wait until the process is closed, the Gui Events still work during the progress but not after reaching 99% or during the ProcessWaitClose stage.

Is there method to have it watch the process and if it no longer exists exit the function, but retain the Gui Events during the entire script?

Thanks again.

Cheers

Link to comment
Share on other sites

Don`t understand completely, you need to exit if process not exists?

#include <Constants.au3>
#include <GUIConstantsEx.au3>
#include <ProgressConstants.au3>
#include <WindowsConstants.au3>

Opt('GUIEventOptions',1)
Opt('TrayOnEventMode',1)
Opt('TrayMenuMode',1)

Global $TimerProc_Handle, $EventId = 10001, $Elapse = 100, $ProgCount = 0

TraySetOnEvent($TRAY_EVENT_PRIMARYUP, 'FNC_MAXIMISE')

$GUI_COMPANY = 'Company Name'
$GUI_DISPLAY = 'Software Name'
$GUI_VERSION = '1.0'
$RUN = 1

$GUI_GUIWNDW = GUICreate($GUI_COMPANY, 365, 150, -1, -1, -1)

$GUI_FNTNAME = 'Arial'
GUISetBkColor(0xEEEEEE)
GUISetFont(10, 800, 0, $GUI_FNTNAME)

$GUI_LBLTITL = GUICtrlCreateLabel( $GUI_DISPLAY & ' '  & $GUI_VERSION, 10, 10, 345)
GUISetFont(8.5, 800, 0, $GUI_FNTNAME)
    
$GUI_LBLSUBT = GUICtrlCreateLabel('Installing ' & $GUI_DISPLAY & ', please wait...', 15, 45, 305)
GUICtrlSetColor($GUI_LBLSUBT, 0X666666)

GUISetFont(8, 400, 0, $GUI_FNTNAME)

$GUI_LBLSTAT = GUICtrlCreateLabel('Status: Installing... - ', 25, 95, 109)
GUICtrlSetColor($GUI_LBLSTAT, 0X666666)

$GUI_GUIGRAPX = GUICtrlCreateGraphic(10, 35, 345, 1)
GUICtrlSetBkColor(-1, 0x999999)

$GUI_PROGBAR = GUICtrlCreateProgress (10, 70, 345, 15,$PBS_SMOOTH)

$GUI_BTNMINIM = GUICtrlCreateButton('Minimise to System Tray»', 10, 125, 170, 20)
$GUI_BTNCANCL = GUICtrlCreateButton('Cancel', 185, 125, 170, 20)

GUISetState(@SW_SHOW)
    
$PKG_RUNCMND = Run('notepad.exe')
    
While 1
    $MSG = GUIGetMsg()
    Select 
        Case $RUN = 1
            $RUN = 0
            GUIRegisterMsg($WM_TIMER, "_Progress")
            DllCall("User32.dll", "int", "SetTimer", "hwnd", $GUI_GUIWNDW, "int", $EventId, "int", $Elapse, "int", 0)
        Case $MSG = $GUI_EVENT_MINIMIZE 
            FNC_MINIMISE()
        Case $MSG = $GUI_EVENT_CLOSE
            Exit
        Case $MSG = $GUI_BTNCANCL
            Exit
        Case $MSG = $GUI_BTNMINIM
            FNC_MINIMISE()
    EndSelect
Wend

Func FNC_MINIMISE()
    GuiSetState(@SW_MINIMIZE)
    GuiSetState(@SW_HIDE)
    TraySetState(1)
    If @OSVersion = 'WIN_NT4' or @OSVersion = 'WIN_ME' or @OSVersion = 'WIN_98' or @OSVersion = 'WIN_95' then
        TraySetToolTip ($GUI_DISPLAY & 'Click here to Restore')
    Else
        Traytip ($GUI_DISPLAY, 'Click here to Restore', 5)
    EndIf
EndFunc

Func FNC_MAXIMISE()
    GuiSetState(@SW_RESTORE)
    GuiSetState(@SW_Show)
    TraySetState(2)
EndFunc

Func _Progress($hWnd, $Msg, $wParam, $lParam)
    If Not ProcessExists($PKG_RUNCMND) Then Exit
    If $ProgCount = 100 Then $ProgCount = 0
    $ProgCount += 1
    GUICtrlSetData($GUI_PROGBAR, $ProgCount)
EndFunc

Func OnAutoItExit()
    GUIRegisterMsg($WM_TIMER, "")
    DllCall("user32.dll", "int", "KillTimer", "hwnd", $GUI_GUIWNDW, "int", $EventId)
EndFunc
Link to comment
Share on other sites

Thanks again Rasim for your reply

Rather than Exit is it possible to end the function then exit the loop?

Here is what I'm trying to achieve, I have a large number of applications that I package for deployment across our company, rather than create and edit a AutoIT script for each application, which I have been doing, I thought I'd create a software template wrapper so that all our software installations have the same look and feel. To do this I created a simple INI file with a section called INSTALL, which the AutoIT Script Reads into an Array, then for each line within the Array I use StringSplit to create another Array.

example below

[iNSTALL]

INSTALL1=Install Shield Script Engine,7.0,isscript.msi /qn /norestart

INSTALL2=ArcGIS,9.2,ArcGIS.msi /qn SerialCode=123456 RegCode=1234567 /norestart

So the Array is broken into 3 Display Name, Version and Commandline

This is then written into the Gui once completed it reads the second line INSTALL2 and the splits this into another array etc.. which is the written into the Gui for the second install.

So in summary, I'm trying to run the Install1 command (read from the ini file) which the Gui displays it's progress and then once this process has completed exit the "function", reset the "Gui" and then run Install2.

Hope that made sense.

Cheers

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