S
smlabc
Unregistered / Unconfirmed
GUEST, unregistred user!
最近感觉不管写什么代码,看起来都很别扭,不舒服,希望大家贴点看起来舒服的代码,以下抛砖引玉贴个垃圾单元://封装了URLDownloadToFile函数unit FileDownLoadThread;interfaceuses 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;implementationconstructor 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.Free; 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.