zoukankan      html  css  js  c++  java
  • 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 = nilor (@ACompleteEvent = nilor (@AFailEvent = nilthen 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), 
    00'程序: 花太香, 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 > 0then
      
    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. 

  • 相关阅读:
    SQL Server临时表的使用方案
    SqlServer 临时表
    SqlServer 数据表数据移动
    IQ/OQ/DQ/PQ
    (转)C# WebApi 跨域问题解决方案:CORS
    (转).Net高级进阶,在复杂的业务逻辑下,如何以最简练的代码,最直观的编写事务代码?
    (转)C#动态webservice调用接口
    (转)wsdl文件用SoapUI快速创建WebService,CXF生成客户端代码
    (转)C# Oracle数据库操作类
    (转)C#连接Oracle数据库(直接引用dll使用)
  • 原文地址:https://www.cnblogs.com/jxgxy/p/2043703.html
Copyright © 2011-2022 走看看