UrlDownloadFile, 线程下载文件, 带进度条

unit FileDownLoadThread;
interface
uses
  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;
implementation

constructor 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.

//使用

复制代码
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls, UrlMon, FileDownLoadThread;

type
  TfrmDownloadFile = class(TForm)
    btn1: TButton;
    pb1: TProgressBar;
    lbl1: TLabel;
    lbl2: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure btn1Click(Sender: TObject);
  private
    aRunThread: TFileDownLoadThread;
  public
    SourceFile, DestFile: string;
    procedure DownLoadProcessEvent(Sender: TFileDownLoadThread; Progress, ProgressMax: Cardinal);
    procedure DownLoadCompleteEvent(Sender: TFileDownLoadThread);
    procedure DownLoadFailEvent(Sender: TFileDownLoadThread; Reason: LongInt);
  end;

var
  frmDownloadFile: TfrmDownloadFile;

implementation

{$R *.dfm}

procedure TfrmDownloadFile.FormCreate(Sender: TObject);
begin
  AppendMenu(GetSystemMenu(Handle, false), 0, 0, ‘程序: 花太香, QQ号: 2111971‘);
end;

procedure TfrmDownloadFile.btn1Click(Sender: TObject);
begin
  SourceFile := ‘http://toolbar.soso.com/T4/download/QQToolbarInstaller.exe‘;
  DestFile := ‘.\QQToolbarInstaller.exe‘;
  lbl1.Caption := ‘0/0‘;
  lbl2.Caption := ‘‘;
  pb1.Position := 0;
  lbl2.Caption := ‘正在下载:‘ + ExtractFileName(DestFile);
  aRunThread := TFileDownLoadThread.Create(SourceFile, DestFile, DownLoadProcessEvent, DownLoadCompleteEvent, DownLoadFailEvent, False);
end;

procedure TfrmDownloadFile.DownLoadProcessEvent(
  Sender: TFileDownLoadThread; Progress, ProgressMax: Cardinal);
var
  z, z1: Single;
  s, s1: string;
begin
  pb1.Position := Progress;
  pb1.Max := ProgressMax;
  if (pb1.Max > 0) then
  begin
    if pb1.Max > 1024 * 1024 then begin
      z := pb1.Max / (1024 * 1024);
      s := ‘MB‘;
    end else begin
      z := pb1.Max / (1024);
      s := ‘KB‘;
    end;

    if Progress > 1024 * 1024 then begin
      z1 := Progress / (1024 * 1024);
      s1 := ‘MB‘;
    end else begin
      z1 := Progress / (1024);
      s1 := ‘KB‘;
    end;
    lbl1.Caption := Format(‘%.2n‘ + s1 + ‘ / %.2n‘ + s, [z1, z]);
  end;
end;

procedure TfrmDownloadFile.DownLoadCompleteEvent(
  Sender: TFileDownLoadThread);
begin
  lbl2.Caption := ‘下载完成.‘;
  lbl1.Caption := ‘‘;
end;

procedure TfrmDownloadFile.DownLoadFailEvent(Sender: TFileDownLoadThread; Reason: Integer);
begin
  lbl2.Caption := ‘下载文件失败,请重试!‘;
end;
复制代码
end. 

http://www.cnblogs.com/jxgxy/archive/2011/05/11/2043703.html

时间: 2024-10-11 16:09:10

UrlDownloadFile, 线程下载文件, 带进度条的相关文章

webclient下载文件 带进度条

private void button1_Click(object sender, EventArgs e) { doDownload(textBox1.Text.Trim()); } private DateTime StartTime; private void doDownload(string url,string fileName="") { label1.Text = "正在下载:" + url;//label框提示下载文件 if (fileName.L

Asp.Net上传大文件带进度条swfupload

Asp.Net基于swfupload上传大文件带进度条百分比显示,漂亮大气上档次,大文件无压力,先看效果 一.上传效果图 1.上传前界面:图片不喜欢可以自己换 2.上传中界面:百分比显示 3.上传后返回文件地址,我测试呢所以乱写的 二.核心代码 upload.htm代码 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml

C# WPF 解压缩7zip文件 带进度条 sevenzipsharp

vs2013附件 :http://download.csdn.net/detail/u012663700/7427461 C# WPF 解压缩7zip文件 带进度条 sevenzipsharp WPF PNG实现的图形进度条 .NET 3.5 http://sevenzipsharp.codeplex.com/ MainWindow.xaml <Window x:Class="SevenZipTestWPF.MainWindow" xmlns="http://schem

VC下载文件显示进度条

VC下载文件显示进度条 逗比汪星人2009-09-18上传 by Koma http://blog.csd.net/wangningyu http://download.csdn.net/detail/wangningyu/1674247

安卓 下载多线程带进度条

当我们学完java中多线程的下载后,可以将它移植到我们的安卓中来,下面是具体实现源码: DownActivity.java [java] view plaincopy package com.example.downloads; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; import java.net.HttpURLConnection; import java.net.Ma

Extjs 使用fileupload插件上传文件 带进度条显示

一.首先我们看看官方给出的插件的解释: 一个文件上传表单项具有自定义的样式,并且可以控制按钮的文本和 像文本表单的空文本类似的其他特性. 它使用一个隐藏的文件输入元素,并在用户选择文件后 在form提交的同时执行实际的文件上传. 因为没有安全的跨浏览器以编程的方式对file表单项设值的方式, 所以标准表单项的 setValue 方法是无效的. getvalue方法的返回值取决于使用何种浏览器; 一些仅仅返回文件名, 一些返回一个完整的文件路径, 一些则返回文件的虚拟路径. 二.在我看来这个插件就

VC下载文件 + 显示进度条

在codeproject里找了许久,发现这样一个VC下载文件并显示进度条的源码,于是添加了些中文注释: 1.下载线程函数: [cpp] view plain copy print? UINT DownloadFile(LPVOID pParam) { CWnd*           pwnd = AfxGetMainWnd(); CProgressCtrl*  m_Prog = (CProgressCtrl*)pwnd->GetDlgItem(IDC_PROGRESS1); CButton*  

asp.net mvc 实现上传文件带进度条

思路:ajax异步上传文件,且开始上传文件的时候启动轮询来实时获取文件上传进度.保存进度我采用的是memcached缓存,因为项目其他地方也用了的,所以就直接用这个啦.注意:不能使用session来保存进度,因为session是线程安全的不能实时获取进度,可是试试httpcache或者memorycache,这两个我没有试过,请自行尝试. ps:使用websocket来实现也是不错的,不过我没有试过,有心的大神可以去试试. 下面贴一张效果图: 前端ajax上传文件,我使用了两种jq插件.一种是a

Python实现下载界面(带进度条,断点续传,多线程多任务下载等)

开发环境: Windows 7 64位,Python 3.6.2 实现功能: 进度条,下载速度和下载进度的显示,断点续传(暂停继续下载功能),取消下载等功能下载界面,如图所示点击'新建任务',弹出输入下载链接的窗口,如图所示点击'开始下载',可以自动获取下载文件名和选择存储路径,如图所示: 关键代码: 因为断点续传是在之前的文件继续追加,所以open(filename,'ab')这里打开文件的模式要为ab实现断点续传的代码如下: headers={'Range': 'bytes=%d-' %os