goaman
asked on
Please can anyone Fix this code... (Downloading a file from the Net)
Hi There!
I need help.. pls help me out to solve this problem... I want a "TProgressbar to indicates the download, TLabel gets the time left to finish the download file and the current downloading speed in KB/s?"...
[code]
function DownloadMyFile(SourceFile, DestFile: string): Boolean;
begin
Form1.ProgressBar1.Positio n:=0;
Form1.ProgressBar1.Max:=
try
Result := UrlDownloadToFile(nil, PChar(SourceFile), PChar(DestFile), 0, nil) = 0;
Form1.ProgressBar1.Positio n:=
Form1.kbps.Caption:=
Form1.TimeLeft.Caption:=
except
Result := False;
end;
end;
procedure TForm1.Button1Click(Sender : TObject);
begin
if DownloadFile(edit1.text ,edit2.text) then
begin
MessageDlg('Download Successful!',mtInformation , [mbOK], 0);
ShellExecute(Application.H andle, PChar('open'), PChar(Edit2.Text), PChar(''), nil, SW_NORMAL);
end
else
MessageDlg('Error downloading the file!', mtError, [mbOK], 0)
end;
end.
[/code]
Please complete this unfinished code.. Thanks in advance!
I need help.. pls help me out to solve this problem... I want a "TProgressbar to indicates the download, TLabel gets the time left to finish the download file and the current downloading speed in KB/s?"...
[code]
function DownloadMyFile(SourceFile,
begin
Form1.ProgressBar1.Positio
Form1.ProgressBar1.Max:=
try
Result := UrlDownloadToFile(nil, PChar(SourceFile), PChar(DestFile), 0, nil) = 0;
Form1.ProgressBar1.Positio
Form1.kbps.Caption:=
Form1.TimeLeft.Caption:=
except
Result := False;
end;
end;
procedure TForm1.Button1Click(Sender
begin
if DownloadFile(edit1.text ,edit2.text) then
begin
MessageDlg('Download Successful!',mtInformation
ShellExecute(Application.H
end
else
MessageDlg('Error downloading the file!', mtError, [mbOK], 0)
end;
end.
[/code]
Please complete this unfinished code.. Thanks in advance!
this is exactly what you need - IBindStatusCallBack
you can look how to do it from here:
https://www.experts-exchange.com/questions/20349921/UrlDownloadToFile-IBindStatusCallback.html
you can look how to do it from here:
https://www.experts-exchange.com/questions/20349921/UrlDownloadToFile-IBindStatusCallback.html
isn't it easier to use the Indy Component IdHttp? less code writing?
ASKER
Hi Darth_helge,
The link is Not Found on the server...
The requested URL /Programming/Programming_L anguages/D elphi/Q_20 887936.htm was not found on this server.
Hi Ivanov_G,
This article seems a little mess, no progressbar, no speed showing or anything.. only form1 caption shows the downloading bytes.. pls Help me... Could you pls fix the code that I've posted up there... the way I wanted... or is there any better example which shows progressbar, time left and kb/s while downloading?
If anyone need I can increase the points... just let me know...pls, I really need this...
Thanx in advance!
The link is Not Found on the server...
The requested URL /Programming/Programming_L
Hi Ivanov_G,
This article seems a little mess, no progressbar, no speed showing or anything.. only form1 caption shows the downloading bytes.. pls Help me... Could you pls fix the code that I've posted up there... the way I wanted... or is there any better example which shows progressbar, time left and kb/s while downloading?
If anyone need I can increase the points... just let me know...pls, I really need this...
Thanx in advance!
I forgot the last letter....
I think that by doing this way it's a lot more easier.
https://www.experts-exchange.com/questions/20887936/show-that-program-is-downloading-using-progressbar.html
I think that by doing this way it's a lot more easier.
https://www.experts-exchange.com/questions/20887936/show-that-program-is-downloading-using-progressbar.html
ASKER
Darth_helge,
I saw that code b4... and yes it's easy way but I wanna know how to do without IdHTTP component + This example doesn't have everything I need.. :(
I saw that code b4... and yes it's easy way but I wanna know how to do without IdHTTP component + This example doesn't have everything I need.. :(
the question I gave you doesn't use TidHTTP...
ASKER
Ivanov_G yes, it doesn't use IdHTTP component... but the example is not advanced... could you please edit that example and place there progressbar to show the downloading and the problem is I don't know how to show Downloading Speed and Tlabel which shows the time how long will it take to download the file.. could you give me a hand in this?
<<I saw that code b4... and yes it's easy way but I wanna know how to do without IdHTTP component + This example doesn't have everything I need.. :(
ok, I can't see why you don't wanna use that component, but in that case, Ivanov_G has a great answer for you.
Maybe you can fill me in Ivanov? Why is the interface you are suggesting better than TIdHTTP?
ok, I can't see why you don't wanna use that component, but in that case, Ivanov_G has a great answer for you.
Maybe you can fill me in Ivanov? Why is the interface you are suggesting better than TIdHTTP?
Darth_helge, did I said it is better ?! If so, pleaso quote my word where I claim this...
Ivanov, I was not intending to be rude. By all means, I respect your answer, and I am sure that you are a much better programmer than me.
I was simply curious about your solution, and what is good about it.
As I could see from mine and your solutions, I saw that mine was less complex and did the same thing (I think...).
But maybe e.g your solution i faster or more secure or more flexible... ..I don't know. That was the thing I asked you about.
Sorry if I made you upset
I was simply curious about your solution, and what is good about it.
As I could see from mine and your solutions, I saw that mine was less complex and did the same thing (I think...).
But maybe e.g your solution i faster or more secure or more flexible... ..I don't know. That was the thing I asked you about.
Sorry if I made you upset
I just gave a suggestion, the author if the one who choose the solution. I also think you solution is more simple and easier to implement.
Try this modification of using IBindStatusCallBack to see how it works. Also, you are going
to need to get the file size BEFORE downloading so you can set the Progressbar's Max property.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, UrlMon, ComCtrls, StdCtrls, ActiveX;
type
TBindStatusCallback = class(TObject, IBindStatusCallback)
protected
FRefCount: Integer;
// IUnknown
function QueryInterface(const IID: TGUID; out Obj): Integer; stdcall;
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;
public
// IBindStatusCallback
function OnStartBinding(dwReserved: DWORD; pib: IBinding): HResult; stdcall;
function GetPriority(out nPriority): HResult; stdcall;
function OnLowResource(reserved: DWORD): HResult; stdcall;
function OnProgress(ulProgress, ulProgressMax, ulStatusCode: ULONG;
szStatusText: LPCWSTR): HResult; stdcall;
function OnStopBinding(hresult: HResult; szError: LPCWSTR):
HResult; stdcall;
function GetBindInfo(out grfBINDF: DWORD; var bindinfo: TBindInfo):
HResult; stdcall;
function OnDataAvailable(grfBSCF: DWORD; dwSize: DWORD; formatetc: PFormatEtc;
stgmed: PStgMedium): HResult; stdcall;
function OnObjectAvailable(const iid: TGUID; punk: IUnknown): HResult; stdcall;
end;
TForm1 = class(TForm)
Button1: TButton;
ProgressBar1: TProgressBar;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
bsc: TBindStatusCallback;
implementation
{$R *.dfm}
function GetEstimatedCompletion(ATt lFileSize, ACompletedBytes: Integer; ABgTime: TDateTime): String;
var
LeftTime: TDateTime;
begin
Result := '';
LeftTime := (Now - ABgTime) / ACompletedBytes* (ATtlFileSize- ACompletedBytes);
Result := FormatDateTime('hh:nn:ss', LeftTime);
end;
function TBindStatusCallback.QueryI nterface(c onst IID: TGUID;
out Obj): Integer;
begin
if GetInterface(IID, Obj) then Result := S_OK
else Result := E_NOINTERFACE; end;
function TBindStatusCallback._AddRe f: Integer;
begin
Inc(FRefCount);
Result := FRefCount;
end;
function TBindStatusCallback._Relea se: Integer;
begin
Dec(FRefCount);
Result := FRefCount;
end;
function TBindStatusCallback.GetBin dInfo(out grfBINDF: DWORD;
var bindinfo: TBindInfo): HResult;
begin
Result := E_NOTIMPL;
end;
function TBindStatusCallback.GetPri ority(out nPriority): HResult;
begin
Result := E_NOTIMPL;
end;
function TBindStatusCallback.OnData Available( grfBSCF, dwSize: DWORD;
formatetc: PFormatEtc; stgmed: PStgMedium): HResult;
begin
Result := E_NOTIMPL;
end;
function TBindStatusCallback.OnLowR esource(re served: DWORD): HResult;
begin
Result := E_NOTIMPL;
end;
function TBindStatusCallback.OnObje ctAvailabl e(const iid: TGUID;
punk: IUnknown): HResult;
begin
Result := E_NOTIMPL;
end;
function TBindStatusCallback.OnStar tBinding(d wReserved: DWORD;
pib: IBinding): HResult;
begin
Result := E_NOTIMPL;
end;
function TBindStatusCallback.OnStop Binding(hr esult: HResult;
szError: LPCWSTR): HResult;
begin
Result := E_NOTIMPL;
end;
function TBindStatusCallback.OnProg ress(ulPro gress, ulProgressMax,
ulStatusCode: ULONG; szStatusText: LPCWSTR): HResult;
begin
// Do something, for example, show progress:
Form1.Caption:='Downloaded : '+IntToStr(ulProgress) +' bytes';
Form1.ProgressBar1.Positio n := ulProgress;
// To PREVENT Divide By Zero Errors!!
if ulProgress > 0 then
begin
Form1.StatusBar1.Panels[0] .Text := 'Estimated Completion time: ' +
GetEstimatedCompletion(giF ileSize, ulProgress, gdtBegtime);
end;
Result := S_OK;
// Place some abort flag here. For demo purpose here, cancel when
// CancelButton.Tag is set to 1:
if Form1.CancelButton.Tag = 1 then
begin
Result := E_ABORT;
Form1.Caption:='Download aborted!'
// Reset the CancelButton's tag
Form1.CancelButton.Tag := 0;
end;
end;
procedure TForm1.Button1Click(Sender : TObject);
begin
// you need to get the file size and set the Progressbar's Max property
// here.
case
URLDownloadToFile(nil,
'https://www.experts-exchange.com/questions/21087833/Please-can-anyone-Fix-this-code-Downloading-a-file-from-the-Net.html,
'c:\ee-question.html', 0 , bsc);
end;
procedure TForm1.CancelButtonClick(S ender: TObject);
begin
case TButton(Sender).Tag of
0: TButton(Sender).Tag := 1;
1: TButton(Sender.Tag := 0; // should never go here because it is reset in OnProgress.
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
bsc:=TBindStatusCallback.C reate;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
bsc.Free;
end;
end.
to need to get the file size BEFORE downloading so you can set the Progressbar's Max property.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, UrlMon, ComCtrls, StdCtrls, ActiveX;
type
TBindStatusCallback = class(TObject, IBindStatusCallback)
protected
FRefCount: Integer;
// IUnknown
function QueryInterface(const IID: TGUID; out Obj): Integer; stdcall;
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;
public
// IBindStatusCallback
function OnStartBinding(dwReserved:
function GetPriority(out nPriority): HResult; stdcall;
function OnLowResource(reserved: DWORD): HResult; stdcall;
function OnProgress(ulProgress, ulProgressMax, ulStatusCode: ULONG;
szStatusText: LPCWSTR): HResult; stdcall;
function OnStopBinding(hresult: HResult; szError: LPCWSTR):
HResult; stdcall;
function GetBindInfo(out grfBINDF: DWORD; var bindinfo: TBindInfo):
HResult; stdcall;
function OnDataAvailable(grfBSCF: DWORD; dwSize: DWORD; formatetc: PFormatEtc;
stgmed: PStgMedium): HResult; stdcall;
function OnObjectAvailable(const iid: TGUID; punk: IUnknown): HResult; stdcall;
end;
TForm1 = class(TForm)
Button1: TButton;
ProgressBar1: TProgressBar;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
bsc: TBindStatusCallback;
implementation
{$R *.dfm}
function GetEstimatedCompletion(ATt
var
LeftTime: TDateTime;
begin
Result := '';
LeftTime := (Now - ABgTime) / ACompletedBytes* (ATtlFileSize- ACompletedBytes);
Result := FormatDateTime('hh:nn:ss',
end;
function TBindStatusCallback.QueryI
out Obj): Integer;
begin
if GetInterface(IID, Obj) then Result := S_OK
else Result := E_NOINTERFACE; end;
function TBindStatusCallback._AddRe
begin
Inc(FRefCount);
Result := FRefCount;
end;
function TBindStatusCallback._Relea
begin
Dec(FRefCount);
Result := FRefCount;
end;
function TBindStatusCallback.GetBin
var bindinfo: TBindInfo): HResult;
begin
Result := E_NOTIMPL;
end;
function TBindStatusCallback.GetPri
begin
Result := E_NOTIMPL;
end;
function TBindStatusCallback.OnData
formatetc: PFormatEtc; stgmed: PStgMedium): HResult;
begin
Result := E_NOTIMPL;
end;
function TBindStatusCallback.OnLowR
begin
Result := E_NOTIMPL;
end;
function TBindStatusCallback.OnObje
punk: IUnknown): HResult;
begin
Result := E_NOTIMPL;
end;
function TBindStatusCallback.OnStar
pib: IBinding): HResult;
begin
Result := E_NOTIMPL;
end;
function TBindStatusCallback.OnStop
szError: LPCWSTR): HResult;
begin
Result := E_NOTIMPL;
end;
function TBindStatusCallback.OnProg
ulStatusCode: ULONG; szStatusText: LPCWSTR): HResult;
begin
// Do something, for example, show progress:
Form1.Caption:='Downloaded
Form1.ProgressBar1.Positio
// To PREVENT Divide By Zero Errors!!
if ulProgress > 0 then
begin
Form1.StatusBar1.Panels[0]
GetEstimatedCompletion(giF
end;
Result := S_OK;
// Place some abort flag here. For demo purpose here, cancel when
// CancelButton.Tag is set to 1:
if Form1.CancelButton.Tag = 1 then
begin
Result := E_ABORT;
Form1.Caption:='Download aborted!'
// Reset the CancelButton's tag
Form1.CancelButton.Tag := 0;
end;
end;
procedure TForm1.Button1Click(Sender
begin
// you need to get the file size and set the Progressbar's Max property
// here.
case
URLDownloadToFile(nil,
'https://www.experts-exchange.com/questions/21087833/Please-can-anyone-Fix-this-code-Downloading-a-file-from-the-Net.html,
'c:\ee-question.html', 0 , bsc);
end;
procedure TForm1.CancelButtonClick(S
begin
case TButton(Sender).Tag of
0: TButton(Sender).Tag := 1;
1: TButton(Sender.Tag := 0; // should never go here because it is reset in OnProgress.
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
bsc:=TBindStatusCallback.C
end;
procedure TForm1.FormDestroy(Sender:
begin
bsc.Free;
end;
end.
ASKER
hi EddieShipman,
I'm getting List index out of bounds(0)..
I'm getting List index out of bounds(0)..
You must have more than one panel in your statusbar. I think that is where it is coming from.
You can also change this line:
Form1.StatusBar1.Panels[0] .Text := 'Estimated Completion time: ' +
GetEstimatedCompletion(giF ileSize, ulProgress, gdtBegtime);
to this if SimpleText is True:
Form1.StatusBar1.SimpleTex t := 'Estimated Completion time: ' +
GetEstimatedCompletion(giF ileSize, ulProgress, gdtBegtime);
Form1.StatusBar1.Panels[0]
GetEstimatedCompletion(giF
to this if SimpleText is True:
Form1.StatusBar1.SimpleTex
GetEstimatedCompletion(giF
ASKER
It's working only when I set it to form1.caption:= 'Estimated Completion time: ' +
GetEstimatedCompletion(giF ileSize, ulProgress, gdtBegtime);
because form1 freezing while downloading except the form1.caption and progressbar
I think there is something wron with this function:
function GetEstimatedCompletion(ATt lFileSize, ACompletedBytes: Integer; ABgTime: TDateTime): String;
var
LeftTime: TDateTime;
begin
Result := '';
LeftTime := (Now - ABgTime) / ACompletedBytes* (ATtlFileSize- ACompletedBytes);
Result := FormatDateTime('hh:nn:ss', LeftTime);
end;
because it's showing the system's current time..
GetEstimatedCompletion(giF
because form1 freezing while downloading except the form1.caption and progressbar
I think there is something wron with this function:
function GetEstimatedCompletion(ATt
var
LeftTime: TDateTime;
begin
Result := '';
LeftTime := (Now - ABgTime) / ACompletedBytes* (ATtlFileSize- ACompletedBytes);
Result := FormatDateTime('hh:nn:ss',
end;
because it's showing the system's current time..
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Ok, I see what is wrong, now. We are not setting the gdtBegTime and giFileSize.
You need to do that when the GoButton is clicked.
procedure TForm1.GoButtonClick(Sende r: TObject);
begin
// you need to get the file size and set the Progressbar's Max property
// here.
gdtBegtime := Now;
giFileSize := 76738; // Get the file size and set here, this is value only for demo purposes.
ProgressBar1.Max:=giFileSi ze;
URLDownloadToFile(nil,
'https://www.experts-exchange.com/questions/21087833/Please-can-anyone-Fix-this-code-Downloading-a-file-from-the-Net.html,
'c:\ee-question.html', 0 , bsc);
end;
You need to do that when the GoButton is clicked.
procedure TForm1.GoButtonClick(Sende
begin
// you need to get the file size and set the Progressbar's Max property
// here.
gdtBegtime := Now;
giFileSize := 76738; // Get the file size and set here, this is value only for demo purposes.
ProgressBar1.Max:=giFileSi
URLDownloadToFile(nil,
'https://www.experts-exchange.com/questions/21087833/Please-can-anyone-Fix-this-code-Downloading-a-file-from-the-Net.html,
'c:\ee-question.html', 0 , bsc);
end;
I have modified this to get the filesize using idHTTP.Head, however, this site sometimes does not return
complete headers, I don't know why. It doesn't send Content-Length all the time like the RFC specifies that
it should, but of course, EE isn't very good at following standards, especially Web UI standards. You will
have to test with your URLs.
If you don't want to use TidHTTP to get the file size, you will have to use other WinInet means.
procedure TForm1.GoButtonClick(Sende r: TObject);
var
sURL: String;
sFileSize: String;
begin
sURL := 'https://www.experts-exchange.com/questions/21087833/Please-can-anyone-Fix-this-code-Downloading-a-file-from-the-Net.html;
// you need to get the file size and set the Progressbar's Max property
// here.
idHTTP1.Head(sURL);
idHTTP1.Head(sURL);
sFileSize := idHTTP1.Response.RawHeader s.Values[' Content-Le ngth'];
if sFileSize <> '' then
giFileSize := StrToInt(sFileSize)
else
giFileSize := 0;
gdtBegtime := Now;
ProgressBar1.Max:=giFileSi ze;
URLDownloadToFile(nil, PChar(sURL), 'c:\ee-question.html', 0 , bsc);
end;
complete headers, I don't know why. It doesn't send Content-Length all the time like the RFC specifies that
it should, but of course, EE isn't very good at following standards, especially Web UI standards. You will
have to test with your URLs.
If you don't want to use TidHTTP to get the file size, you will have to use other WinInet means.
procedure TForm1.GoButtonClick(Sende
var
sURL: String;
sFileSize: String;
begin
sURL := 'https://www.experts-exchange.com/questions/21087833/Please-can-anyone-Fix-this-code-Downloading-a-file-from-the-Net.html;
// you need to get the file size and set the Progressbar's Max property
// here.
idHTTP1.Head(sURL);
idHTTP1.Head(sURL);
sFileSize := idHTTP1.Response.RawHeader
if sFileSize <> '' then
giFileSize := StrToInt(sFileSize)
else
giFileSize := 0;
gdtBegtime := Now;
ProgressBar1.Max:=giFileSi
URLDownloadToFile(nil, PChar(sURL), 'c:\ee-question.html', 0 , bsc);
end;
https://www.experts-exchange.com/questions/20887936/show-that-program-is-downloading-using-progressbar.html
They're using the IdHttp component.....