16,747
社区成员




Type
PCFPRData = ^TCFPRData;
TCFPRData = record
PB : TProgressBar;
Max : Integer; //之所以不直接用TProgressBar来比较,看一下TProgressBar.GetMax就知道了
Position : Integer; //同上
end;
var
bUserCancel : Boolean;
Function CopyFilePR(TotalFileSize,TotalBytesTransferred,StreamSize,StreamBytesTransferred:Int64;
dwStreamNumber , dwCallbackReason : Cardinal;
hSourceFile , hDestinationFile : THandle;
Data : PCFPRData):DWORD; stdcall;
var
iPosition : integer;
begin
//40M以下的文件就不用显示进度条了,这里假设了复制速度在40M/秒以上,龟速复制不适合本回调
if StreamSize<40*1024*1024 then begin
Result := PROGRESS_QUIET;
Exit;
end;
Result := PROGRESS_CONTINUE;
if Data.Max=0 then begin //只设置一次Max
Data.Max := StreamSize DIV (6*1024*1024); //48M/秒的复制速度,每秒跳动8次左右
Data.PB.Max := Data.Max;
end;
iPosition := StreamBytesTransferred DIV (6*1024*1024);
if iPosition<>Data.Position then begin //当需要同步进度条的时候才同步
Data.Position := iPosition;
Data.PB.Position := iPosition;
Application.ProcessMessages;
//这里响应取消复制的操作
if bUserCancel then Result := PROGRESS_CANCEL; //取消文件复制,并删除目标文件
end;
end;
procedure TForm1.CancelBtnClick(Sender: TObject);
begin
bUserCancel := True;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
CFPRData : TCFPRData;
begin
DeleteFile('F:\DD.MKV');
FillChar(CFPRData , SizeOf(CFPRData) , 0);
CFPRData.PB := ProgressBar1;
ProgressBar1.Tag := 0;
ProgressBar1.Position := 0;
bUserCancel := False;
CopyFileEx('F:\多媒体\电影收藏\黑衣人3\Men.in.Black.3.2012.720p.BluRay.x264.DTS-HDChina.mkv' ,
'F:\DD.MKV' , @CopyFilePR , @CFPRData , NIL , COPY_FILE_FAIL_IF_EXISTS);
end;
这个文件是6G,比直接CopyFile只慢一点点.if copyfileex(PChar(edt1.Text),PChar(edt2.text), //调用函数
@copyprogressroutine,
nil,
0,
COPY_FILE_FAIL_IF_EXISTS) then
begin
showmessage( 'COPY Success ');
pb1.position:=0;
end;
Function CopyProgressRoutine(
TotalFileSize : Int64;
TotalBytesTransferred : Int64;
StreamSize : Int64;
StreamBytesTransferred : Int64;
dwStreamNumber : Cardinal;
dwCallbackReason : DWord;
hSourceFile : THandle;
hDestinationFile : THandle;
lpData : Pointer):integer;
Begin
form1.ProgressBar1.Max:=StreamSize;
form1.ProgressBar1.Min :=0;
form1.ProgressBar1.Position := StreamBytesTransferred;
application.ProcessMessages ;
Result := PROGRESS_CONTINUE;
end;
{
if copyfileex(PChar(edt1.Text),PChar(edt2.text),
@copyprogressroutine,
nil,
0,
COPY_FILE_FAIL_IF_EXISTS) then
begin
showmessage( 'COPY Success ');
pb1.position:=0;
end;
}