File Download With ProgressBar
Posted: Thu May 16, 2013 3:52 am
I was searching and came across a older thread to accomplish this. I felt like updating his code a bit to support the new and improved PB functions. I was able to strip a lot of messy code, and make it much more understandable. Plus now it will grab the file size regardless to header length.
Credits to V2 for writing the original source here http://www.purebasic.fr/english/viewtopic.php?t=8331.
Edit: Updated the code to thread the download, and you can stop the download process. Supports one simultaneous download without freezing up the form any.
Credits to V2 for writing the original source here http://www.purebasic.fr/english/viewtopic.php?t=8331.
Edit: Updated the code to thread the download, and you can stop the download process. Supports one simultaneous download without freezing up the form any.
Code: Select all
Global StopDownload.l = 0
Enumeration
#Window
#Start
#ProgressBar
#Frame
#Label
#Label2
#URL
EndEnumeration
Structure DownloadData
Folder.s
File.s
URL.s
EndStructure
Procedure DoEvents()
msg.MSG
If PeekMessage_(msg, 0, 0, 0, 1)
TranslateMessage_(msg)
DispatchMessage_(msg)
Else
Delay(1)
EndIf
EndProcedure
Procedure DownloadWithProgress(*Parameters.DownloadData)
Protected.l FileBytes = 0, Bytes = 0, INTERNET_FLAG_RELOAD = $80000000, Size, Buffer = 4096, LastSize, Timer, Timed
Protected.b isLoop = 1, OpenType = 1
Protected.s Header, Line
;Get Filesize
Header = GetHTTPHeader(*Parameters\URL)
Repeat
x + 1
Line = StringField(Header, x, Chr(10))
Until FindString(Line, "Content-Length:", 1, #PB_String_NoCase)
Size = Val(StringField(Line, 2, "Content-Length: "))
;Allocate Buffer For File Data
*Memory = AllocateMemory(Buffer)
;Create File To Dump Data To And Initialize WinINet
Result = CreateFile(1, *Parameters\Folder + *Parameters\File)
hInet = InternetOpen_("", OpenType, #Null, #Null, 0)
hURL = InternetOpenUrl_(hInet, *Parameters\URL, #Null, 0, INTERNET_FLAG_RELOAD, 0)
If Size > 1048576
SetGadgetText(#Label, "File Size: "+Str(Size/1048576)+" MB")
ElseIf Size > 1024
SetGadgetText(#Label, "File Size: "+Str(Size/1024)+" KB")
Else
SetGadgetText(#Label, "File Size: "+Str(Size)+" Bytes")
EndIf
SetGadgetAttribute(#ProgressBar, #PB_ProgressBar_Maximum, Size)
;Start Downloading
Timer = ElapsedMilliseconds()
Repeat
InternetReadFile_(hURL, *Memory, Buffer, @Bytes)
If Bytes = 0
isLoop = 0
Else
FileBytes = FileBytes + Bytes
Timed = ElapsedMilliseconds()-Timer
If Timed > 1000
SetGadgetText(#Label2, "Download Speed: "+Str((FileBytes - LastSize)/1024)+" KB/s")
Timer = ElapsedMilliseconds()
LastSize = FileBytes
EndIf
If Size >= FileBytes : SetGadgetState(#ProgressBar, FileBytes) : EndIf
If StopDownload = 1 : isLoop = 0 : StopDownload = 0 : EndIf
WriteData(1, *Memory, Bytes)
EndIf
DoEvents()
Until isLoop = 0
;Release Handles
InternetCloseHandle_(hURL)
InternetCloseHandle_(hInet)
CloseFile(1)
;Form Clean
SetGadgetState(#ProgressBar, 0)
SetGadgetText(#Label, "File Size: ")
SetGadgetText(#Label2, "Download Speed: ")
SetGadgetText(#Start, "Start")
;Clean Up
FreeMemory(*Memory)
ClearStructure(*Parameters, DownloadData)
FreeMemory(*Parameters)
EndProcedure
InitNetwork()
If OpenWindow(#Window, 0, 0, 400, 175, "Download With Progress", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
StringGadget(#URL, 10, 10, 380, 20, "http://ddj9plya1d2mr.cloudfront.net/ubuntu-13.04-desktop-amd64.iso")
ProgressBarGadget(#ProgressBar, 10, 40, 380, 30, 0, 100, #PB_ProgressBar_Smooth)
TextGadget(#Label, 10, 80, 300, 20, "File Size:")
TextGadget(#Label2, 10, 100, 300, 20, "Download Speed:")
Frame3DGadget(#Frame, -10, 120, 420, 110, "")
ButtonGadget(#Start, 280, 140, 110, 25, "Start", #PB_Button_Default)
Repeat
EventID = WaitWindowEvent()
Select EventID
Case #PB_Event_Gadget
Select EventGadget()
Case #Start
If IsThread(Thread)
StopDownload = 1
Else
URL.s = GetGadgetText(#URL)
;Get Filename
TrimURL.s = GetURLPart(URL, #PB_URL_Path)
Position = CountString(TrimURL, "/") + 1
File.s = StringField(TrimURL, Position, "/")
;Request Path
Folder.s = PathRequester("Where do you want to save '"+File+"'?", "C:\")
If Folder
*Parameters.DownloadData = AllocateMemory(SizeOf(DownloadData))
*Parameters\File = File
*Parameters\Folder = Folder
*Parameters\URL = URL
Thread = CreateThread(@DownloadWithProgress(), *Parameters)
SetGadgetText(#Start, "Cancel")
EndIf
EndIf
EndSelect
Case #PB_Event_CloseWindow
End
EndSelect
ForEver
EndIf