最好能举一小例!! 谢谢!!

解决方案 »

  1.   

    建议用Indy的组件进行下载
    IndyTCPClient如果一定要UrlDownloadToFile的话,把文件保存到流,用计时器获取流的大小,麻烦
      

  2.   

    type
      TDownloadStatusCallback = class(TObject, IUnknown, IBindStatusCallback)
      private
        FRefCount: Integer;
        function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
        function _AddRef: Integer; stdcall;
        function _Release: Integer; stdcall;
      public
        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;{ TDownloadStatusCallback }function TDownloadStatusCallback._AddRef: Integer;
    begin
      Inc(FRefCount);
      Result := FRefCount;
    end;function TDownloadStatusCallback._Release: Integer;
    begin
      Dec(FRefCount);
      Result := FRefCount;
    end;function TDownloadStatusCallback.GetBindInfo(out grfBINDF: DWORD;
      var bindinfo: TBindInfo): HResult;
    begin
      Result := E_NOTIMPL;
    end;function TDownloadStatusCallback.GetPriority(out nPriority): HResult;
    begin
      Result := E_NOTIMPL;
    end;function TDownloadStatusCallback.OnDataAvailable(grfBSCF, dwSize: DWORD;
      formatetc: PFormatEtc; stgmed: PStgMedium): HResult;
    begin
      Result := E_NOTIMPL;
    end;function TDownloadStatusCallback.OnLowResource(reserved: DWORD): HResult;
    begin
      Result := E_NOTIMPL;
    end;function TDownloadStatusCallback.OnObjectAvailable(const iid: TGUID;
      punk: IInterface): HResult;
    begin
       Result := E_NOTIMPL;
    end;function TDownloadStatusCallback.OnProgress(ulProgress, ulProgressMax,
      ulStatusCode: ULONG; szStatusText: LPCWSTR): HResult;
    begin
      Case ulStatusCode of
        BINDSTATUS_FINDINGRESOURCE:
        begin
          Form1.Label1.Caption := 'Finding resource...';
        end;
        BINDSTATUS_CONNECTING:
        begin
          Form1.Label1.Caption := 'Connecting...';
        end;
        BINDSTATUS_BEGINDOWNLOADDATA:
        begin
          Form1.Gauge1.Progress := 0;
          Form1.Label1.Caption := 'Begin download...';
        end;
        BINDSTATUS_DOWNLOADINGDATA:
        begin
          Form1.Gauge1.Progress := MulDiv(ulProgress,100,ulProgressMax);
          Form1.Label1.Caption := 'Download in progress...';
        end;
        BINDSTATUS_ENDDOWNLOADDATA:
        begin
          Form1.Label1.Caption := 'Download completed...';
        end;
      end;
      Application.ProcessMessages;
      if UserCancel then
         begin
           Result := E_ABORT;
           Exit;
         end;
      Result := S_OK;
    end;function TDownloadStatusCallback.OnStartBinding(dwReserved: DWORD;
      pib: IBinding): HResult;
    begin
      Result := E_NOTIMPL;
    end;function TDownloadStatusCallback.OnStopBinding(hresult: HResult;
      szError: LPCWSTR): HResult;
    begin
       Result := E_NOTIMPL;
    end;function TDownloadStatusCallback.QueryInterface(const IID: TGUID;
      out Obj): HResult;
    begin
      if GetInterface(IID,Obj)
         then Result := S_OK
         else Result := E_NOINTERFACE;
    end;procedure TForm1.BitBtn1Click(Sender: TObject);
    var DownStatus : TDownloadStatusCallback;
    begin
      UserCancel := false;
      DownStatus := TDownloadStatusCallBack.Create;
      try
        URLDownloadToFile(nil, PChar(edDLURL.Text), PChar(edTargetFile.Text), 0, DownStatus);
      finally
        DownStatus.Free;
      end;
    end;procedure TForm1.BitBtn2Click(Sender: TObject);
    begin
      UserCancel := true;
    end;end.因为这类API不具备更多的用户可控制性,所以远不如用Indy来的好