API函数CopyFileEx使用详解(delphi)

来源:互联网 发布:linux运维之道 编辑:程序博客网 时间:2024/06/07 03:25

 


{ 函数原型 }
 
  function CopyFileEx(
    lpExistingFileName   : PChar;               // 来源文件
    lpNewFileName        : PChar;               // 目标文件
    lpProgressRoutine    : TFNProgressRoutine;  // 用于返回文件有关信息的回调函数
    lpData               : Pointer;             // 传递给回调函数的参数
    pbCancel             : PBool;               // 用于中途取消拷贝,函数会监视此值的状态,如果为真,则停止拷贝
    dwCopyFlags          : DWORD                // 选项标志,见定义
    ): BOOL; stdcall;                           // 返回拷贝成功还是失败
 
 
 
{ CopyFileEx 回调函数可能的返回值 }
 
  PROGRESS_CONTINUE = 0;                        // 让拷贝过程继续
  PROGRESS_CANCEL = 1;                          // 终止拷贝过程并删除目标文件
  PROGRESS_STOP = 2;                            // 停止拷贝,但以后可以继续开始
  PROGRESS_QUIET = 3;                           // 让拷贝过程继续,但从此不再进行回调
 
 
 
{ CopyFileEx 回调函数状态 }
 
  CALLBACK_STREAM_SWITCH = $00000001;           // 第一次回调的状态是 CALLBACK_STREAM_SWITCH
  CALLBACK_CHUNK_FINISHED = $00000000;          // 而后的状态都是 CALLBACK_CHUNK_FINISHED
 
 
 
{ CopyFileEx 选项标志 }
 
  COPY_FILE_FAIL_IF_EXISTS = $00000001;         //文件存在则取消拷贝
  COPY_FILE_RESTARTABLE = $00000002;            //拷贝失败可重新开始
 
 
 
{ 回调函数原型 }
 
  TFarProc = Pointer;
  TFNProgressRoutine = TFarProc;                //指针类型
 
  function CopyProgress(
    TotalFileSize         : LARGE_INTEGER;      // 文件总大小,字节
    TotalBytesTransferred : LARGE_INTEGER;      // 已复制的文件大小,字节
    StreamSize            : LARGE_INTEGER;      // 当前流的总字节数
    StreamBytesTransferred: LARGE_INTEGER;      // 当前流已拷贝的字节数
    dwStreamNumber        : DWORD;              // 当前流序号
    dwCallbackReason      : DWORD;              // 回调函数的状态,见定义
    hSourceFile           : THANDLE;            // 来源文件句柄
    hDestinationFile      : THANDLE;            // 目标文件句柄
    lpData                : Pointer             // CopyFileEx 函数传递过来的参数
    ) : DWORD; stdcall;                         // 回调函数的返回值,见定义
 
 
 
{ 说明 }
 
    该函数复制一个已存在的文件到一个新文件。该函数保留了文件的扩展属性,OLE存储格式和文件属性。文件的安全属性不复制到新文件中去。
    如果目标文件存在,且具有只读属性,则函数执行失败。
    该函数每复制 65536字节(即64KB) 的内容后就调用一次回调函数。
    第一次调用回调函数时 dwCallbackReason(回调函数的状态) 的值为 CALLBACK_STREAM_SWITCH,此时不复制任何数据,只是告诉回调函数,将要开始复制数据了。
    此函数是线程同步的,也就是说,在主窗口中调用此函数时,窗口将无法响应用户的操作,直到文件复制完毕为止。
    此函数无法复制锁定的文件,比如页面文件 PageFile.sys。就像在资源管理器中复制 PageFile.sys 一样,会提示文件正被另一个程序使用,无法复制。此函数不会提示错误,只会返回逻辑值否,表示复制失败。
 
 
 
{============================================================}
{  例子                                                      }
{============================================================}
 
unit Main;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;
 
type
  TForm2 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    Button2: TButton;
    procedure Button2Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form2             : TForm2;
  Cancel            : Boolean;
  iCount            : Integer;
 
implementation
 
{$R *.dfm}
 
function CopyProgress(
  TotalFileSize: LARGE_INTEGER;                   // 文件总大小,字节
  TotalBytesTransferred: LARGE_INTEGER;           // 已复制的文件大小,字节
  StreamSize: LARGE_INTEGER;                      // 当前流的总字节数
  StreamBytesTransferred: LARGE_INTEGER;          // 当前流已拷贝的字节数
  dwStreamNumber: DWORD;                          // 当前流序号
  dwCallbackReason: DWORD;                        // 回调函数的状态,见定义
  hSourceFile: THANDLE;                           // 来源文件句柄
  hDestinationFile: THANDLE;                      // 目标文件句柄
  lpData: Pointer                                 // CopyFileEx 函数传递过来的参数
  ): DWORD; stdcall;                              // 回调函数的返回值,见定义
begin
  // if iCount = 2 then begin
  //   Result := PROGRESS_STOP;
  //   Exit;
  // end;
  Application.ProcessMessages;
  Form2.Memo1.Clear;
  Form2.Memo1.Lines.Add(IntToStr(TotalFileSize.QuadPart));
  Form2.Memo1.Lines.Add(IntToStr(TotalBytesTransferred.QuadPart));
  Form2.Memo1.Lines.Add(IntToStr(StreamSize.QuadPart));
  Form2.Memo1.Lines.Add(IntToStr(StreamBytesTransferred.QuadPart));
  Form2.Memo1.Lines.Add(IntToStr(dwStreamNumber));
  Form2.Memo1.Lines.Add(IntToStr(Result));
  Inc(iCount);
end;
 
procedure TForm2.Button1Click(Sender: TObject);
var
  Src, Dest         : string;
begin
  iCount := 0;
  Cancel := False;
  Src := 'D:/Tools.rar';
  Dest := 'E:/Tools.rar';

  if not FileExists(Src) then begin
    Memo1.Text := '文件 ' + Src + ' 不存在!';
    Exit;
  end;
 
  CopyFileEx(
    PChar(Src),
    PChar(Dest),
    @CopyProgress,
    nil,
    @Cancel,
    COPY_FILE_RESTARTABLE);
end;
 
procedure TForm2.Button2Click(Sender: TObject);
begin
  Cancel := True;
end;
 
end.
 

 

 

 

文章来自:  http://blog.csdn.net/stevenldj/archive/2007/11/08/1872842.aspx

原创粉丝点击