//修改了一下.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ComCtrls, CommCtrl;
type
TCopyFileData = Record
Source: string;
Destination: string;
pCancel : Pointer;
hProgress : THandle;
end;
TCopyFile = Class
private
IsStop : BOOL;
FHandle : THandle;
ThreadId: LongWord;
CopyFileData : TCopyFileData;
public
constructor Create(const Source: string;
const Destination: string;
Progress : Thandle);
destructor Destroy;
override;
procedure Start;
procedure Cancel;
function WaitFor : DWORD;
end;
TForm1 = class(TForm)
ProgressBar1: TProgressBar;
Button2: TButton;
Animate1: TAnimate;
procedure FormCreate(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
CopyFile : TCopyFile;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
{ TCopyFile }
function CopyProgressRoutine(
TotalFileSize : LARGE_INTEGER;
TotalBytesTransferred : LARGE_INTEGER;
StreamSize : LARGE_INTEGER;
StreamBytesTransferred : LARGE_INTEGER;
dwStreamNumber : DWORD;
dwCallbackReason : DWORD;
hSourceFile : THandle;
hDestinationFile : THandle;
lpData : Pointer) : DWORD;
stdcall;
begin
with TCopyFileData(lpData^)do
begin
SendMessage(hProgress, PBM_SETRANGE32, 0, TotalFileSize.QuadPart);
SendMessage(hProgress, PBM_SETPOS, TotalBytesTransferred.QuadPart, 0);
if BOOL(pCancel^) then
Result := PROGRESS_STOP
else
Result := PROGRESS_CONTINUE;
end;
end;
function ThreadFunc(Parameter: Pointer): BOOL;
begin
with TCopyFileData(Parameter^)do
begin
Result := CopyFileEx(PChar(Source),PChar(Destination),
@CopyProgressRoutine, Parameter, nil, COPY_FILE_RESTARTABLE);
end;
end;
procedure TCopyFile.Start;
begin
if FHandle = 0 then
begin
IsStop := False;
FHandle := begin
Thread(nil,0,@ThreadFunc,@CopyFileData, CREATE_SUSPENDED,ThreadId);
ResumeThread(FHandle);
end;
end;
function TCopyFile.WaitFor : DWORD;
var
Msg: TMsg;
H: THandle;
begin
H := FHandle;
if GetCurrentThreadID = MainThreadID then
while MsgWaitForMultipleObjects(1, H, False, INFINITE,
QS_SENDMESSAGE) = WAIT_OBJECT_0 + 1do
PeekMessage(Msg, 0, 0, 0, PM_NOREMOVE)
else
WaitForSingleObject(H, INFINITE);
GetExitCodeThread(H, Result);
end;
constructor TCopyFile.Create(const Source, Destination: string;
Progress : Thandle);
begin
IsStop := False;
CopyFileData.Source := Source;
CopyFileData.Destination := Destination;
CopyFileData.pCancel := @IsStop;
CopyFileData.hProgress := Progress;
end;
destructor TCopyFile.Destroy;
begin
if not IsStop then
Cancel;
inherited Destroy;
end;
procedure TCopyFile.Cancel;
begin
IsStop := True;
//WaitFor;
CloseHandle(FHandle);
FHandle := 0;
end;
{TFrom1}
procedure TForm1.Button2Click(Sender: TObject);
begin
CopyFile.Destroy;
Close;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
CopyFile := TCopyFile.Create('E:/Vickwa/databak/20040230.bak',
'd:/20040230.bak',ProgressBar1.Handle);
CopyFile.Start;
end;
end.