Urldownloadtofile progress prompt

Source: Internet
Author: User

Urlmon. dll has an API for download. The definition in msdn is as follows:

HRESULT URLDownloadToFile(             LPUNKNOWN pCaller,       LPCTSTR szURL,       LPCTSTR szFileName,       DWORD dwReserved,       LPBINDSTATUSCALLBACK lpfnCB);

Delphi's urlmon. PAS has its Pascal statement:

function URLDownloadToFile(        pCaller: IUnKnown,  szURL: PAnsiChar,  szFileName: PAnsiChar,  dwReserved: DWORD,  lpfnCB: IBindStatusCallBack;);HRESULT;stdcall;

Szurl is the URL of the file to be downloaded, szfilename is another file name, dwreserved is the reserved parameter, and 0 is passed. If you do not need a progress prompt, it is easy to call this function. For example, to download the song "http: // 218.95.47.htm/page/jxzy/xszb/web/fourteens/music/qilique" and save it as "D: \ music \ qilixiang", you can call it like this:

Urldownloadtofile (nil, 'HTTP: // 218.95.47.htm/page/jxzy/xszb/web/fourteens/music/qiliqing', 'd: \ music \ qilixiangjie ', 0, nil );

However, the disadvantage is that there is no progress prompt and the call thread will be blocked. The last parameter lpfncb is required to obtain the progress prompt. It is an interface type ibindstatuscallback, which is defined as follows:

IBindStatusCallback = interface     ['{79eac9c1-baf9-11ce-8c82-00aa004ba90b}']    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;

The progress prompt depends on the onprogress method of this interface. We can define a class that implements the ibindstatuscallback interface. Only the onprogress method can be processed. if you do nothing about other methods, s_ OK is returned. Here is a brief description of onprogress:

Ulprogress: current progress Value
Ulprogressmax: total progress
Ulstatuscode: status value, which is the tagbindstatus enumeration. It indicates you are looking for resources, and you are connecting to these statuses. For details, refer to msdn. We do not need to care about it here.
Szstatustext: Status string, and we don't care about it either.

So if we use percentage to indicate the progress, it is floattostr (ulprogress * 100/ulprogressmax) + '/%', which is simple. To cancel the task before the download is complete, you can return e_abort in onprogress.
I encapsulated urldownloadtofile and its progress prompt function into a Thread class. The source code of this class is as follows:

 

{ Delphi File Download Thread Class , Copyright (c) Zhou Zuoji }unit FileDownLoadThread;interfaceuses
Classes, SysUtils, Windows, ActiveX, UrlMon;const S_ABORT = HRESULT($80004004); type TFileDownLoadThread = class; TDownLoadProcessEvent = procedure(Sender:TFileDownLoadThread;Progress, ProgressMax:Cardinal) of object; TDownLoadCompleteEvent = procedure(Sender:TFileDownLoadThread) of object ; TDownLoadFailEvent = procedure(Sender:TFileDownLoadThread;Reason:LongInt) of object ; TDownLoadMonitor = class( TInterfacedObject, IBindStatusCallback ) private FShouldAbort: Boolean; FThread:TFileDownLoadThread; protected 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; public constructor Create(AThread:TFileDownLoadThread); property ShouldAbort: Boolean read FShouldAbort write FShouldAbort; end; TFileDownLoadThread = class( TThread ) private FSourceURL: string; FSaveFileName: string; FProgress,FProgressMax:Cardinal; FOnProcess: TDownLoadProcessEvent; FOnComplete: TDownLoadCompleteEvent; FOnFail: TDownLoadFailEvent; FMonitor: TDownLoadMonitor; protected procedure Execute; override; procedure UpdateProgress(Progress, ProgressMax, StatusCode: Cardinal; StatusText:string); procedure DoUpdateUI; public constructor Create( ASrcURL, ASaveFileName: string; AProgressEvent:TDownLoadProcessEvent = nil; ACompleteEvent:TDownLoadCompleteEvent = nil;AFailEvent:TDownLoadFailEvent=nil;CreateSuspended: Boolean=False ); property SourceURL: string read FSourceURL; property SaveFileName: string read FSaveFileName; property OnProcess: TDownLoadProcessEvent read FOnProcess write FOnProcess; property OnComplete: TDownLoadCompleteEvent read FOnComplete write FOnComplete; property OnFail: TDownLoadFailEvent read FOnFail write FOnFail; end;implementationconstructor TDownLoadMonitor.Create(AThread: TFileDownLoadThread);begin inherited Create; FThread:=AThread; FShouldAbort:=False;end;function TDownLoadMonitor.GetBindInfo( out grfBINDF: DWORD; var bindinfo: TBindInfo ): HResult;begin result := S_OK;end;function TDownLoadMonitor.GetPriority( out nPriority ): HResult;begin Result := S_OK;end;function TDownLoadMonitor.OnDataAvailable( grfBSCF, dwSize: DWORD; formatetc: PFormatEtc; stgmed: PStgMedium ): HResult;begin Result := S_OK;end;function TDownLoadMonitor.OnLowResource( reserved: DWORD ): HResult;begin Result := S_OK;end;function TDownLoadMonitor.OnObjectAvailable( const iid: TGUID; punk: IInterface ): HResult;begin Result := S_OK;end;function TDownLoadMonitor.OnProgress( ulProgress, ulProgressMax, ulStatusCode: ULONG; szStatusText: LPCWSTR ): HResult;begin if FThread<>nil then FThread.UpdateProgress(ulProgress,ulProgressMax,ulStatusCode,''); if FShouldAbort then Result := E_ABORT else Result := S_OK;end;function TDownLoadMonitor.OnStartBinding( dwReserved: DWORD; pib: IBinding ): HResult;begin Result := S_OK;end;function TDownLoadMonitor.OnStopBinding( hresult: HResult; szError: LPCWSTR ): HResult;begin Result := S_OK;end;{ TFileDownLoadThread }constructor TFileDownLoadThread.Create( ASrcURL, ASaveFileName: string;AProgressEvent:TDownLoadProcessEvent ; ACompleteEvent:TDownLoadCompleteEvent;AFailEvent:TDownLoadFailEvent; CreateSuspended: Boolean );begin if (@AProgressEvent=nil) or (@ACompleteEvent=nil) or (@AFailEvent=nil) then CreateSuspended:=True; inherited Create( CreateSuspended ); FSourceURL:=ASrcURL; FSaveFileName:=ASaveFileName; FOnProcess:=AProgressEvent; FOnComplete:=ACompleteEvent; FOnFail:=AFailEvent;end;procedure TFileDownLoadThread.DoUpdateUI;begin if Assigned(FOnProcess) then FOnProcess(Self,FProgress,FProgressMax);end;procedure TFileDownLoadThread.Execute;var DownRet:HRESULT;begin inherited; FMonitor:=TDownLoadMonitor.Create(Self); DownRet:= URLDownloadToFile( nil, PAnsiChar( FSourceURL ), PAnsiChar( FSaveFileName ), 0,FMonitor as IBindStatusCallback); if DownRet=S_OK then begin if Assigned(FOnComplete) then FOnComplete(Self); end else begin if Assigned(FOnFail) then FOnFail(Self,DownRet); end; FMonitor:=nil;end;procedure TFileDownLoadThread.UpdateProgress(Progress, ProgressMax, StatusCode: Cardinal; StatusText: string);begin FProgress:=Progress; FProgressMax:=ProgressMax; Synchronize(DoUpdateUI); if Terminated then FMonitor.ShouldAbort:=True;end;end.


Use deleteurlcacheentry to clear the cache and then use urldownloadtofile to download the file.

/*************************************** *****************/
Cstring szurl = "http://www.dtapp.cn ";

Deleteurlcacheentry (szurl); // clear the cache
Cstring szfilename = "C :\\ dtapp.txt ";

If (s_ OK = urldownloadtofile (null, szurl, szfilename, null, null ))
{
// Download successful
}
Else
{
// Download failed
}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.