Jump to content

GUICtrlCreateProgress w/ Multiple GUIs


Recommended Posts

Like several people, I've come to wish that ProgressOn had a cancel/close button, but alas, it does not.  I have a rather complex Form w/ multiple objects/tabs/etc and having a GUICtrlCreateProgress in the same form isn't ideal, so I was attempting to bring up a second GUI window just to show the progress, and then have it close.

For this test I was attempting, I used guiness' >_InetGetGUI UDF with some obvious modifications attempting to get it to work with 2 seperate GUI's.

Here's what I have so far:

#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7

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

main()

Func main()
   
$Form = GUICreate("Download Test Using 2 GUIs", 372, 56, -1, 116)
$Button1 = GUICtrlCreateButton("Download", 40, 8, 299, 41)
GUICtrlSetFont(-1, 14, 400, 0, "MS Sans Serif")

GUISetState(@SW_SHOW)

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
         Case $Button1
            GUISetState(@SW_DISABLE, $Form)
            _progress()
            GUISetState(@SW_ENABLE, $Form)
    EndSwitch
WEnd
EndFunc

Func _progress()
    Local $sFilePathURL = "http://ftp.opera.com/pub/opera/win/1152/en/Opera_1152_en_Setup.exe"
    Local $hGUI, $iButton, $iLabel, $iProgressBar, $sFilePath

    $hGUI = GUICreate("_InetGetGUI()", 370, 90, -1, 0)
    $iLabel = GUICtrlCreateLabel("", 5, 5, 270, 40)
    $iButton = GUICtrlCreateButton("&Cancel", 275, 2.5, 90, 25)
    $iProgressBar = GUICtrlCreateProgress(5, 60, 360, 20)
    GUISetState(@SW_SHOW, $hGUI)
    $sDirectory = @ScriptDir
    $sFilePath = _InetGetGUI($sFilePathURL, $iLabel, $iProgressBar, $iButton, $sDirectory, $hGUI)
#cs
    While 1 <==================== don't think I need this section
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
               GUIDelete($hGUI)
             Case $iButton
                GUIDelete($hGUI)
        EndSwitch
    WEnd
#ce
EndFunc

Func _InetGetGUI($sURL, $iLabel, $iProgress, $iButton, $sDirectory, $hGUI)
    Local $hDownload, $iBytesRead = 0, $iFileSize, $iPercentage, $iSpeed = 0, $iTimer = 0, $sFilePath, $sProgressText, $sSpeed
    $sFilePath = StringRegExpReplace($sURL, "^.*/", "")
    $sDirectory = StringRegExpReplace($sDirectory, "[\\/]+\z", "") & "\" & $sFilePath
    $iFileSize = InetGetSize($sURL, 1)
    $hDownload = InetGet($sURL, $sDirectory, 0, 1)
    $sSpeed = "Current Speed: " & _ByteSuffix($iBytesRead - $iSpeed) & "/s"
    $iTimer = TimerInit()
    While InetGetInfo($hDownload, 2) = 0
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE, $iButton
                MsgBox(48,"","Download Cancelled")
                ExitLoop
        EndSwitch

        $iBytesRead = InetGetInfo($hDownload, 0)
        $iPercentage = $iBytesRead * 100 / $iFileSize
        $sProgressText = "Downloading " & _ByteSuffix($iBytesRead, 0) & " Of " & _ByteSuffix($iFileSize, 0) & @LF & $sSpeed
        GUICtrlSetData($iLabel, $sProgressText)
        GUICtrlSetData($iProgress, $iPercentage)

        If TimerDiff($iTimer) > 1000 Then
            $sSpeed = "Current Speed: " & _ByteSuffix($iBytesRead - $iSpeed) & "/s"
            $iSpeed = $iBytesRead
            $iTimer = TimerInit()
        EndIf
        Sleep(100)
    WEnd
    InetClose($hDownload)
    GUIDelete($hGUI)
    ;main() <======== closest to a solution that I've found, but it launches multiple instances of $Form which is not desirable
EndFunc

Func _ByteSuffix($iBytes, $iRound = 2)
    Local $A, $aArray[9] = [" B", " KB", " MB", " GB", " TB", " PB", " EB", " ZB", " YB"]
    While $iBytes > 1023
        $A += 1
        $iBytes /= 1024
    WEnd
    Return Round($iBytes, $iRound) & $aArray[$A]
EndFunc

It's semi-functional at best, the only way I can get it to stay open is using the commented out portion in _InetGetGUI - which launches multiple instances of $Form.  I have a feeling that I'm close to a solution, but after multiple attemps I still can't get it to work as intended.

Link to comment
Share on other sites

You need to know that you are trying to accomplish two things by canceling the download.

1. You need to actually stop the download. From the help file: "To abort a download call InetClose() and pass it the handle returned by InetGet()."

2. After using GuiDelete, you need to use ExitLoop to return back to the original gui.

#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7

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

main()

Func main()

$Form = GUICreate("Download Test Using 2 GUIs", 372, 56, -1, 116)
$Button1 = GUICtrlCreateButton("Download", 40, 8, 299, 41)
GUICtrlSetFont(-1, 14, 400, 0, "MS Sans Serif")

GUISetState(@SW_SHOW)

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
         Case $Button1
            GUISetState(@SW_DISABLE, $Form)
            _progress()
            GUISetState(@SW_ENABLE, $Form)
    EndSwitch
WEnd
EndFunc

Func _progress()
    Local $sFilePathURL = "http://ftp.opera.com/pub/opera/win/1152/en/Opera_1152_en_Setup.exe"
    Local $hGUI, $iButton, $iLabel, $iProgressBar, $sFilePath

    $hGUI = GUICreate("_InetGetGUI()", 370, 90, -1, 0)
    $iLabel = GUICtrlCreateLabel("", 5, 5, 270, 40)
    $iButton = GUICtrlCreateButton("&Cancel", 275, 2.5, 90, 25)
    $iProgressBar = GUICtrlCreateProgress(5, 60, 360, 20)
    GUISetState(@SW_SHOW, $hGUI)
    $sDirectory = @ScriptDir
    $sFilePath = _InetGetGUI($sFilePathURL, $iLabel, $iProgressBar, $iButton, $sDirectory, $hGUI)
;~ #cs
    While 1; <==================== don't think I need this section
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                InetClose($sFilePath)  ; Modified
               GUIDelete($hGUI)  
               ExitLoop  ; Modified
           Case $iButton
               InetClose($sFilePath)  ; Modified
                GUIDelete($hGUI)
                ExitLoop  ; Modified
        EndSwitch
    WEnd
;~ #ce
EndFunc

Func _InetGetGUI($sURL, $iLabel, $iProgress, $iButton, $sDirectory, $hGUI)
    Local $hDownload, $iBytesRead = 0, $iFileSize, $iPercentage, $iSpeed = 0, $iTimer = 0, $sFilePath, $sProgressText, $sSpeed
    $sFilePath = StringRegExpReplace($sURL, "^.*/", "")
    $sDirectory = StringRegExpReplace($sDirectory, "[\\/]+\z", "") & "\" & $sFilePath
    $iFileSize = InetGetSize($sURL, 1)
    $hDownload = InetGet($sURL, $sDirectory, 0, 1)
    $sSpeed = "Current Speed: " & _ByteSuffix($iBytesRead - $iSpeed) & "/s"
    $iTimer = TimerInit()
    While InetGetInfo($hDownload, 2) = 0
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                MsgBox(48,"","Download Cancelled")
                ExitLoop
            Case $iButton
                MsgBox(48,"","Download Cancelled")
                ExitLoop
        EndSwitch

        $iBytesRead = InetGetInfo($hDownload, 0)
        $iPercentage = $iBytesRead * 100 / $iFileSize
        $sProgressText = "Downloading " & _ByteSuffix($iBytesRead, 0) & " Of " & _ByteSuffix($iFileSize, 0) & @LF & $sSpeed
        GUICtrlSetData($iLabel, $sProgressText)
        GUICtrlSetData($iProgress, $iPercentage)

        If TimerDiff($iTimer) > 1000 Then
            $sSpeed = "Current Speed: " & _ByteSuffix($iBytesRead - $iSpeed) & "/s"
            $iSpeed = $iBytesRead
            $iTimer = TimerInit()
        EndIf
        Sleep(100)
    WEnd
    InetClose($hDownload)
    GUIDelete($hGUI)
    ;main() <======== closest to a solution that I've found, but it launches multiple instances of $Form which is not desirable
EndFunc

Func _ByteSuffix($iBytes, $iRound = 2)
    Local $A, $aArray[9] = [" B", " KB", " MB", " GB", " TB", " PB", " EB", " ZB", " YB"]
    While $iBytes > 1023
        $A += 1
        $iBytes /= 1024
    WEnd
    Return Round($iBytes, $iRound) & $aArray[$A]
EndFunc
Edited by abberration
Link to comment
Share on other sites

Do I need to be here? Or is the problem solved?

UDF List:

 
_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_ArrayFilter/_ArrayReduce_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 22/04/2018

Link to comment
Share on other sites

Hi,

Welcome to the autoit forum :)

You can't have multiple loops running at the same time, you will have to create an array and store the download informations inside, then check for the downloads status in the main loop.

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

Global $aDownloads[10][8] = [[0]] ;max 10 downloads here

main()

Func main()
    Local $Form = 0, $Button1 = 0, $aMsg = 0

    $Form = GUICreate("Download Test Using 2 GUIs", 372, 56, -1, 116)
    $Button1 = GUICtrlCreateButton("Download", 40, 8, 299, 41)
    GUICtrlSetFont($Button1, 14, 400, 0, "MS Sans Serif")
    GUISetState(@SW_SHOW, $Form)

    Local $iBytesRead = 0, $iPercentage = 0, $sProgressText = "", $sSpeed = ""

    While 1
        $aMsg = GUIGetMsg(1)

        Switch $aMsg[1]
            Case $Form
                Switch $aMsg[0]
                    Case $GUI_EVENT_CLOSE
                        Exit
                    Case $Button1
                        GUISetState(@SW_DISABLE, $Form)
                        _progress()
                        GUISetState(@SW_ENABLE, $Form)
                EndSwitch
            Case Else
                For $i = 1 To $aDownloads[0][0]
                    If $aMsg[1] <> $aDownloads[$i][0] Then ContinueLoop

                    Switch $aMsg[0]
                        Case $GUI_EVENT_CLOSE, $aDownloads[$i][2]
                            MsgBox(48, "", "Download Cancelled")
                            InetClose($aDownloads[$i][4])
                            GUIDelete($aDownloads[$i][0])
                    EndSwitch

                    ExitLoop
                Next
        EndSwitch

        For $i = 1 To $aDownloads[0][0]
            If $aDownloads[$i][4] = 0 Then ContinueLoop

            If InetGetInfo($aDownloads[$i][4], 2) Then
                InetClose($aDownloads[$i][4])
                GUIDelete($aDownloads[$i][0])

                $aDownloads[$i][4] = 0
                ContinueLoop
            EndIf

            $iBytesRead = InetGetInfo($aDownloads[$i][4], 0)
            $iPercentage = $iBytesRead * 100 / $aDownloads[$i][6]
            $sProgressText = "Downloading " & _ByteSuffix($iBytesRead, 0) & " Of " & _ByteSuffix($aDownloads[$i][6], 0) & @LF & $sSpeed
            GUICtrlSetData($aDownloads[$i][1], $sProgressText)
            GUICtrlSetData($aDownloads[$i][3], $iPercentage)

            If TimerDiff($aDownloads[$i][5]) > 1000 Then
                $sSpeed = "Current Speed: " & _ByteSuffix($iBytesRead - $aDownloads[$i][7]) & "/s"
                $aDownloads[$i][7] = $iBytesRead
                $aDownloads[$i][5] = TimerInit()
            EndIf
        Next
    WEnd
EndFunc   ;==>main

Func _progress()
    $aDownloads[0][0] += 1

    Local $sFilePathURL = "http://ftp.opera.com/pub/opera/win/1152/en/Opera_1152_en_Setup.exe"
    Local $sDirectory = ""

    $aDownloads[$aDownloads[0][0]][0] = GUICreate("_InetGetGUI()", 370, 90, -1, 0)
    $aDownloads[$aDownloads[0][0]][1] = GUICtrlCreateLabel("", 5, 5, 270, 40)
    $aDownloads[$aDownloads[0][0]][2] = GUICtrlCreateButton("&Cancel", 275, 2.5, 90, 25)
    $aDownloads[$aDownloads[0][0]][3] = GUICtrlCreateProgress(5, 60, 360, 20)

    $sDirectory = @ScriptDir
    _InetGetGUI($sFilePathURL, $sDirectory)

    GUISetState(@SW_SHOW, $aDownloads[$aDownloads[0][0]][0])
EndFunc   ;==>_progress

Func _InetGetGUI($sURL, $sDirectory)
    Local $sFilePath = StringRegExpReplace($sURL, "^.*/", "")
    $sDirectory = StringRegExpReplace($sDirectory, "[\\/]+\z", "") & "\" & $sFilePath
    $aDownloads[$aDownloads[0][0]][6] = InetGetSize($sURL, 1)
    $aDownloads[$aDownloads[0][0]][4] = InetGet($sURL, $sDirectory, 0, 1)
    $aDownloads[$aDownloads[0][0]][5] = TimerInit()
    $aDownloads[$aDownloads[0][0]][7] = 0
EndFunc   ;==>_InetGetGUI

Func _ByteSuffix($iBytes, $iRound = 2)
    Local $A, $aArray[9] = [" B", " KB", " MB", " GB", " TB", " PB", " EB", " ZB", " YB"]
    While $iBytes > 1023
        $A += 1
        $iBytes /= 1024
    WEnd
    Return Round($iBytes, $iRound) & $aArray[$A]
EndFunc   ;==>_ByteSuffix
Edit: Added indents.

Br, FireFox.

Edited by FireFox
Link to comment
Share on other sites

Thanks for the replies!

abberration's version: the cancellation works, but $Form is completely non-responsive after cancelling, and I either have to stop executing or kill it w/ taskmgr.

FireFox"s version: the cancellation works here as well, $Form is responsive after the fact, but if I hit download a 2nd time I notice some abnormalities with the speed and the reported download size [Downloading (x of y)], even though everything seems functional with both the download and multiple cancellations.

[edit] If it helps, my intended use for this is with an automated download script that I have - essentially a series of checkboxes with a download button but I wanted to try a simple example first.

Edited by Minotaur
Link to comment
Share on other sites

but if I hit download a 2nd time I notice some abnormalities with the speed and the reported download size [Downloading (x of y)]

I don't deny it, it's a fast made example and it can be improved/fixed.

Br, FireFox.

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