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 = 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.
  • 相关阅读:
    Hadoop集群(三) Hbase搭建
    Hadoop集群(二) HDFS搭建
    Hadoop集群(一) Zookeeper搭建
    Redis Cluster 添加/删除 完整折腾步骤
    Redis Cluster在线迁移
    Hadoop分布式HA的安装部署
    Describe the difference between repeater, bridge and router.
    what is the “handover” and "soft handover" in mobile communication system?
    The main roles of LTE eNodeB.
    The architecture of LTE network.
  • 原文地址:https://www.cnblogs.com/china1/p/3395149.html
Copyright © 2011-2022 走看看