Delphi编写下载程序:UrlDownloadToFile的进度提示

本文介绍如何在Delphi程序中利用UrlDownloadToFile函数进行文件下载,并实现下载进度的实时提示。通过监控下载过程,为用户提供更好的交互体验。
摘要由CSDN通过智能技术生成

urlmon.dll中有一个用于下载的API,MSDN中的定义如下:

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

Delphi的UrlMon.pas中有它的Pascal声明:

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

szURL是要下载的文件的URL地址,szFileName是另存文件名,dwReserved是保留参数,传递0。如果不需要进度提示的话,调用这个函数很简单。比如要下载http://218.95.47.224/page/jxzy/XSZB/web/fourteens/Music/qili.mp3 这首歌,并保存为D:/ Music/七里香.mp3,就可以这样调用:

   URLDownloadToFile(nil,'http://218.95.47.224/page/jxzy/XSZB/web/fourteens/Music/qili.mp3 ','D:/ Music/七里香.mp3',0,nil);

不过这样做的缺点是没有进度提示,而且会阻塞调用线程。如果要获得进度提示就要用到最后一个参数lpfnCB了,它是一个接口类型IBindStatusCallBack,定义如下:


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 ;


进度提示就靠这个接口的OnProgress方法了。我们可以定义一个实现 IBindStatusCallback 接口的类,只处理一下OnProgress方法就可以了,其它方法咱啥都不做,就返回S_OK。下面简要说一下OnProgress:

ulProgress :当前进度值
ulProgressMax :总进度
ulStatusCode: 状态值,是tagBINDSTATUS枚举。表明正在寻找资源啊,正在连接啊这些状态。具体请查看MSDN,我们这里不需要关心它
szStatusText:状态字符串,咱也不关心它

所以我们用百分比来表示进度的话就是FloatToStr(ulProgress*100/ulProgressMax)+'/%',简单吧。如果要在下载完成前取消任务,可以在OnProgress中返回E_ABORT。
我把UrlDownloadToFile及其进度提示功能都封装进了一个线程类中,这个类的源码如下:

{ Delphi  File  Download Thread  Class   ,  Copyright (c) Zhou Zuoji }

unit FileDownLoadThread;

interface

uses
    Classes
,
    SysUtils
,
    Windows
,
    ActiveX
,
    UrlMon;
在Visual Basic 6.0中,使用`URLDownloadToFile`函数可以实现文件的下载功能。这个函数是Windows API的一部分,用于从指定的URL下载文件并保存到本地磁盘。为了实现带有下载进度的文件下载,我们需要结合其他技术来获取下载进度信息。 `URLDownloadToFile`函数本身并不提供下载进度的回调,因此要获取进度信息,可以采用以下方法: 1. **定时轮询法**:通过定时检查临时文件的大小来估算下载进度。这种方法简单,但可能存在一定的延迟和误差。 2. **使用HTTP头信息**:对于HTTP协议的下载,可以通过解析HTTP响应头中的`Content-Length`字段来计算下载进度,这需要能够接收和解析HTTP响应头。 3. **第三方库或工具**:使用支持进度回调的第三方下载库或工具,例如AxWebBrowser控件的`Navigate2`方法,可以通过事件获取下载进度。 下面是一个使用定时轮询法的示例代码,这个方法适用于多种类型的URL,但需要注意的是,对于非HTTP协议的下载,可能无法获取进度信息。 ```vb Private Declare Function URLDownloadToFile Lib "urlmon" Alias "URLDownloadToFileA" ( _ ByVal pCaller As Long, _ ByVal szURL As String, _ ByVal szFileName As String, _ ByVal dwReserved As Long, _ ByVal lpfnCB As Long) As Long Private Sub DownloadFile(url As String, fileName As String) Dim hEvent As Long Dim result As Long Dim fileLength As Long Dim downloaded As Long Dim percent As Long Dim timeInterval As Long Dim timerID As Long ' 初始化下载进度 downloaded = 0 fileLength = 0 percent = 0 ' 设置定时器,例如每500毫秒触发一次检查 timeInterval = 500 timerID = SetTimer(0, 0, timeInterval, AddressOf UpdateProgress) ' 下载文件 result = URLDownloadToFile(0, url, fileName, 0, 0) ' 取消定时器 KillTimer 0, timerID End Sub Private Sub UpdateProgress(ByVal hwnd As Long, ByVal uMsg As Long, ByVal idEvent As Long, ByVal dwTime As Long) ' 更新下载进度的代码 ' 这里需要自己实现如何获取下载的当前字节和总字节数 ' 更新界面的进度条等组件 End Sub ``` 在上述代码中,`UpdateProgress`子程序需要根据实际情况实现,用于更新下载进度。由于VB6本身不具备直接获取下载进度的能力,需要用户根据具体情况,可能结合第三方库或API来实现此功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值