Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Super simple download with progress bar.


  • Please log in to reply
26 replies to this topic
Guest10
  • Members
  • 1216 posts
  • Last active: Oct 30 2015 05:12 PM
  • Joined: 27 Oct 2012

Any progress indicator that is like a pie chart as in circular with wedges (such as that for downloads in Chrome) to indicate progress rather than a progress "bar"?



Bruttosozialprodukt
  • Members
  • 457 posts
  • Last active: Oct 18 2015 08:47 AM
  • Joined: 20 Oct 2012

@Guest10

It would definitely be possible using gdip.

You could also use existing javascript libs and render it in an activeX shell.explorer. (this would likely not work under XP)

 

Here is a basic example of how I would implement this in HTML/JS, the code might also be useful to you if you want to build something like this with gdip:

<!DOCTYPE HTML>
<html>
  <body>
    <canvas id="myCanvas" width="200" height="200"></canvas>
    <script>
      var canvas = document.getElementById('myCanvas');
      var context = canvas.getContext('2d');
      var progress = 0;
      setInterval(function(){
          SetProgress(canvas,context,progress);
          progress = progress+1;
      }, 10);
      
      
      function SetProgress(canvas,context,percent) {
          context.clearRect (0, 0, canvas.width, canvas.height );
          context.beginPath();
                //arc(posX, posY, radius, startAngle, endAngle, counterClockwise)
          context.arc(100, 100, 50, Math.PI*1.5, Math.PI*1.5+Math.PI*2/100*percent, false);
          context.lineWidth = 10;
          context.strokeStyle = '#009933';
          context.stroke();
      }
    </script>
  </body>
</html>

For the gdip solution you might be interested in Gdip_DrawArc(pGraphics, pPen, x, y, w, h, StartAngle, SweepAngle)

For the activeX solution you might be interested in WB.document.parentWindow.SetProgress(...)

 

@jhabers

Just use the function of the first post in this thread (v1.1 to be specific). It works just fine for me.

	Url            = http://download.adlice.com/RogueKiller/RogueKiller.exe
	DownloadAs     = RogueKiller.exe
	Overwrite      := True 
	UseProgressBar := True
	DownloadFile(Url, DownloadAs, Overwrite, UseProgressBar)
	

;=================== Start Functions =====================================================================

DownloadFile(UrlToFile, SaveFileAs, Overwrite := True, UseProgressBar := True) {
    ;Check if the file already exists and if we must not overwrite it
      If (!Overwrite && FileExist(SaveFileAs))
          Return
    ;Check if the user wants a progressbar
      If (UseProgressBar) {
          ;Initialize the WinHttpRequest Object
            WebRequest := ComObjCreate("WinHttp.WinHttpRequest.5.1")
          ;Download the headers
            WebRequest.Open("HEAD", UrlToFile)
            WebRequest.Send()
          ;Store the header which holds the file size in a variable:
            FinalSize := WebRequest.GetResponseHeader("Content-Length")
          ;Create the progressbar and the timer
            Progress, H80, , Downloading..., %UrlToFile%
            SetTimer, __UpdateProgressBar, 100
      }
    ;Download the file
      UrlDownloadToFile, %UrlToFile%, %SaveFileAs%
    ;Remove the timer and the progressbar because the download has finished
      If (UseProgressBar) {
          Progress, Off
          SetTimer, __UpdateProgressBar, Off
      }
    Return
    
    ;The label that updates the progressbar
      __UpdateProgressBar:
          ;Get the current filesize and tick
            CurrentSize := FileOpen(SaveFileAs, "r").Length ;FileGetSize wouldn't return reliable results
            CurrentSizeTick := A_TickCount
          ;Calculate the downloadspeed
            Speed := Round((CurrentSize/1024-LastSize/1024)/((CurrentSizeTick-LastSizeTick)/1000)) . " Kb/s"
          ;Save the current filesize and tick for the next time
            LastSizeTick := CurrentSizeTick
            LastSize := FileOpen(SaveFileAs, "r").Length
          ;Calculate percent done
            PercentDone := Round(CurrentSize/FinalSize*100)
          ;Update the ProgressBar
            Progress, %PercentDone%, %PercentDone%`% Done, Downloading...  (%Speed%), Downloading %SaveFileAs% (%PercentDone%`%)
      Return
}


Guest10
  • Members
  • 1216 posts
  • Last active: Oct 30 2015 05:12 PM
  • Joined: 27 Oct 2012

Thanks, Bruttosozialprodukt, but how do I implement this in AHK?



Bruttosozialprodukt
  • Members
  • 457 posts
  • Last active: Oct 18 2015 08:47 AM
  • Joined: 20 Oct 2012

The gdip one or the activeX one?



Guest10
  • Members
  • 1216 posts
  • Last active: Oct 30 2015 05:12 PM
  • Joined: 27 Oct 2012

The Gdip solution; i.e., Gdip_DrawArc(pGraphics, pPen, x, y, w, h, StartAngle, SweepAngle) looks promising, any basic examples?



Bruttosozialprodukt
  • Members
  • 457 posts
  • Last active: Oct 18 2015 08:47 AM
  • Joined: 20 Oct 2012

Alright, this should get you started:

CreateCircleProgress(diameter:=50,thickness:=5,color:=0x99009933,xPos:="center",yPos:="center",guiId:=1) {
    width := height := diameter+thickness*2
    xPos := (xPos=="center" ? A_ScreenWidth/2-diameter/2-thickness : xPos)
    yPos := (yPos=="center" ? A_ScreenHeight/2-diameter/2-thickness : yPos)
    Gui, %guiId%: -Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs
    Gui, %guiId%: Show, NA
    
    hwnd := WinExist()
    hbm := CreateDIBSection(width, height)
    hdc := CreateCompatibleDC()
    obm := SelectObject(hdc, hbm)
    G := Gdip_GraphicsFromHDC(hdc)
    Gdip_SetSmoothingMode(G, 4)
    
    pen:=Gdip_CreatePen(color, thickness)
    Gdip_SetCompositingMode(G, 1)
    Return {hwnd:hwnd, hdc:hdc, obm:obm, hbm:hbm, pen:pen, G:G, diameter: diameter, thickness:thickness, xPos:xPos, yPos:yPos, width:width, height:height}
}
UpdateCircleProgress(circleObj,percent) {
    Gdip_Drawarc(circleObj.G, circleObj.pen, circleObj.thickness, circleObj.thickness, circleObj.diameter, circleObj.diameter, 270, 360/100*percent)
    UpdateLayeredWindow(circleObj.hwnd, circleObj.hdc, circleObj.xPos, circleObj.yPos, circleObj.width, circleObj.height)
}
DestroyCircleProgress(circleObj) {
    Gui % circleObj.hwnd ":Destroy"
    SelectObject(circleObj.hdc, circleObj.obm)
    DeleteObject(circleObj.hbm)
    DeleteDC(circleObj.hdc)
    Gdip_DeleteGraphics(circleObj.G)
}

edit: little bugfix

edit2: forgot some parameters

edit:3

here is how you could put it into the download function: http://pastebin.com/ZMR2eMhp

http://i.snag.gy/T3Lvz.jpg



Guest10
  • Members
  • 1216 posts
  • Last active: Oct 30 2015 05:12 PM
  • Joined: 27 Oct 2012

Thanks so much! Tested; works and looks great. I believe this is the first progress indicator of its kind on this forum. ;)



Guest10
  • Members
  • 1216 posts
  • Last active: Oct 30 2015 05:12 PM
  • Joined: 27 Oct 2012

I tried to incorporate this circle progress indicator into an existing timer (please see below), but for some reason, the Circle is missing?

; http://www.autohotkey.com/community/viewtopic.php?f=2&t=62008

#SingleInstance, Force
#NoEnv
SetBatchLines, -1
#Include Gdip.ahk

If (UseProgressBar) {
          ;Initialize the WinHttpRequest Object
            WebRequest := ComObjCreate("WinHttp.WinHttpRequest.5.1")
          ;Download the headers
            WebRequest.Open()
            WebRequest.Send()
          ;Store the header which holds the file size in a variable:
            FinalSize := WebRequest.GetResponseHeader()
          ;Create the progressbar and the timer
            Progress, H80, , Downloading...,
            circleObj := CreateCircleProgress(450,60)
            SetTimer, __UpdateProgressBar, 100
      }

      If (UseProgressBar) {
          Progress, Off
          SetTimer, __UpdateProgressBar, Off
          DestroyCircleProgress(circleObj)
      }

XI = %A_ScreenWidth%
YI = %A_ScreenHeight%

XPos := XI/2
YPOs := YI/2

XInput := XI-250
YInput := YI-150
; On-screen display (OSD)

CustomColor = 99AA55 ; C0C0C0 ; Can be any RGB color (it will be made transparent below):
Menu ,Tray, NoStandard
;Menu ,Tray, Add
Menu,Tray, Add,
Menu,Tray, Add, Exit, GuiClose
Gui +LastFound +AlwaysOnTop +Caption +ToolWindow +OwnDialogs
Gui, Color, %CustomColor%
Gui, Font, s10
;Gui Add , Text , x0 y10 w130 h15 vpercent +Center, Time Elapsed %perc%`%
Gui Add , Progress , x5 y30 w120 h10 cRed vmyprogress
Gui, Font, s16
Gui, Add, Text, x5 w120 vMyTime cRed +Center, -00:00:00
WinSet, TransColor, %CustomColor% 175 ; Make all pixels of this color transparent and make the text itself translucent (150):

Loop, 1 ; 3
{
    ; MsgBox, Iteration number is %A_Index%. ; A_Index will be 1, 2, then 3
    Sleep, 100 ; 1000

   SetTimer, UpdateOSD, 200 ; Causes a subroutine to be launched automatically and repeatedly at a specified time interval.
   Gui, Show, x%XPos% y%YPos% w130 NoActivate, Time-to-Go ; NoActivate avoids deactivating the currently active window.

   Gui +LastFound +AlwaysOnTop +Caption +ToolWindow +OwnDialogs
   WinGetPos ,XPos ,YPos,,,Time-to-Go,
   ;Period = 0000001 ; Specified a known static Period (1 minute for testing purposes)
   Period = 00000100 ; Specified a known static Period (1 minute for testing purposes)
   StringMid ,PeriodD, Period,1, 2
   StringMid ,PeriodH, Period,3, 2
   StringMid ,Periodm, Period,5, 2
   StringMid ,Periods, Period,7, 2
   Periodsec := (PeriodD*86400)+(PeriodH*3600)+(Periodm*60)+Periods
   StartTime = %A_Now%
   ;EndTime = %A_Now%
   ;EndTime = 20121021181050
   EnvAdd EndTime, Periodsec, seconds
   EnvSub StartTime, EndTime, seconds
   StartTime := Abs(StartTime)

   perc := 0 ; Resets percentage to 0, otherwise this loop never sees the counter reset
   Loop
   {
       if perc = 100
           break ; Terminate the loop
       else
           continue ; Skip the below and start a new iteration
   }
    Gui, Cancel
    ExitApp
}

UpdateOSD:
mysec := EndTime
EnvSub, mysec, %A_Now%, seconds
GuiControl,, MyTime, % FormatSeconds( mysec )
perc := ((StartTime-mysec)/StartTime)*100
perc := Floor(perc)
GuiControl ,,myprogress,%perc%
GuiControl ,,percent, Time Elapsed %perc%`%
If (perc=100){
    SetTimer, UpdateOSD, Off
    GuiControl ,,percent, Done %perc% `%

}

      __UpdateProgressBar:
            Progress, %Perc%, %Perc%`% Done, Downloading...  (%...%), Downloading %...% (%Perc%`%)
            UpdateCircleProgress(circleObj,Perc)
      Return

    Gui, Cancel
Return

GuiClose: ; writes the settings into a ini file to get the position and continue count from last point (for long periods, endtimes where you had to shutdown the computer)
ExitApp

FormatSeconds(NumberOfSeconds) ; Convert the specified number of seconds to hh:mm:ss format
{
    time = 19990101 ; *Midnight* of an arbitrary date.
    time += %NumberOfSeconds%, seconds
    FormatTime, mmss, %time%, mm:ss
    hours := NumberOfSeconds // 3600 ; This method is used to support more than 24 hours worth of sections
    hours := hours < 10 ? "0" . hours : hours
    return hours ":" mmss
}

CreateCircleProgress(diameter:=50,thickness:=5,color:=0x99009933,xPos:="center",yPos:="center",guiId:=1) {
    width := height := diameter+thickness*2
    xPos := (xPos=="center" ? A_ScreenWidth/2-diameter/2-thickness : xPos)
    yPos := (yPos=="center" ? A_ScreenHeight/2-diameter/2-thickness : yPos)
    Gui, %guiId%: -Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs
    Gui, %guiId%: Show, NA
   
    hwnd := WinExist()
    hbm := CreateDIBSection(width, height)
    hdc := CreateCompatibleDC()
    obm := SelectObject(hdc, hbm)
    G := Gdip_GraphicsFromHDC(hdc)
    Gdip_SetSmoothingMode(G, 4)
   
    pen:=Gdip_CreatePen(color, thickness)
    Gdip_SetCompositingMode(G, 1)
    Return {hwnd:hwnd, hdc:hdc, obm:obm, hbm:hbm, pen:pen, G:G, diameter: diameter, thickness:thickness, xPos:xPos, yPos:yPos, width:width, height:height}
}
UpdateCircleProgress(circleObj,percent) {
    Gdip_Drawarc(circleObj.G, circleObj.pen, circleObj.thickness, circleObj.thickness, circleObj.diameter, circleObj.diameter, 270, 360/100*percent)
    UpdateLayeredWindow(circleObj.hwnd, circleObj.hdc, circleObj.xPos, circleObj.yPos, circleObj.width, circleObj.height)
}
DestroyCircleProgress(circleObj) {
    Gui % circleObj.hwnd ":Destroy"
    SelectObject(circleObj.hdc, circleObj.obm)
    DeleteObject(circleObj.hbm)
    DeleteDC(circleObj.hdc)
    Gdip_DeleteGraphics(circleObj.G)
}


Bruttosozialprodukt
  • Members
  • 457 posts
  • Last active: Oct 18 2015 08:47 AM
  • Joined: 20 Oct 2012

Please explain what exactly the script is supposed to do. I created a new thread for the circle functions: http://ahkscript.org....php?f=6&t=6947
It would probably be better to continue the discussion over there.



Guest10
  • Members
  • 1216 posts
  • Last active: Oct 30 2015 05:12 PM
  • Joined: 27 Oct 2012

Thanks, I see some solutions on that thread with additional contributions by other forum members.



taghi_ar
  • Members
  • 23 posts
  • Last active: Dec 29 2016 05:37 PM
  • Joined: 04 Nov 2014

hi there

i have tested the command urldownloadtofile to do downloadin files one by one but i want a command or script to download full directory contents and i need that to be done through http not ftp can any one please help me



Bruttosozialprodukt
  • Members
  • 457 posts
  • Last active: Oct 18 2015 08:47 AM
  • Joined: 20 Oct 2012

This functions post in this thread have nothing to do with ftp. Downloading a directory is nothing that can be done with a single http request.

You would have to create the directory using FileCreateDir and call the download function for every single file you want to download to that folder.