我的情况是这样:  程序有好几个窗口,每个窗口都有用到复制功能,因为需要在复制时显示复制进度,所以我放了progressbar,但这样导致程序中每个form都要有下面的复制函数,重复了好几个,有没有办法解决这种情况呢?另外,复制时的剩余时间怎么计算?如果能获取复制速度的话,能不能让复制进度通过剩余时间来确定!复制进度的显示方面有没有更好的办法了?function TMainForm.StreamCopy(FromFile, ToFile: String): Boolean;
var
  FromStr, ToStr: TFileStream;
  PerSize, CurrentSize: Integer;
  Create, LastAccess, LastWrite: TFileTime;
begin
  PerSize := 4096;//这里这样定义对不对??
  FromStr := TFileStream.Create(FromFile, fmOpenRead or fmShareDenyNone);
  ProgressBar1.Max := FromStr.Size div PerSize;
  try
    try
      ToStr := TFileStream.Create(ToFile, fmCreate);
    except
      FreeAndNil(FromStr);
      Result:= False;
      Exit;
    end;
    try
      CurrentSize := 0;
      repeat
        if Copying then
        begin
          if FromStr.Size - CurrentSize <= PerSize then
            PerSize := FromStr.Size - CurrentSize;
          ToStr.CopyFrom(FromStr, PerSize);
          Inc(CurrentSize, PerSize);
          ProgressBar1.Position:= ProgressBar1.Position + 1;
        end else
        begin
          FreeAndNil(ToStr);
          FreeAndNil(FromStr);
          DeleteFile(ToFile);
          Result:= False;
          Exit;
        end;
        Application.ProcessMessages;
      until CurrentSize >= FromStr.Size;
      GetFileTime(FromStr.Handle, @Create, @LastAccess, @LastWrite);
      SetFileTime(ToStr.Handle, @Create, @LastAccess, @LastWrite);
      Result := True;
    finally
      FreeAndNil(ToStr);
    end;
  finally
    FreeAndNil(FromStr);
  end;
  ProgressBar1.Position := 0;
end;

解决方案 »

  1.   

    form上加上一个ProgressBar1控件
    procedure TfrmMain.mycopyfile(sourcef, targetf: string);
    var
      FromF, ToF: file;
      NumRead, NumWritten: Integer;
      Buf: array[1..2048] of Char;
      n: integer;
    begin
      AssignFile(FromF, sourcef);
      Reset(FromF, 1); { Record size = 1 }
      AssignFile(ToF, targetf); { Open output file }
      Rewrite(ToF, 1); { Record size = 1 }
      n := 0;
      sb1.Panels[3].Text := '备份数据进度';
      repeat
        BlockRead(FromF, Buf, SizeOf(Buf), NumRead);
        ProgressBar1.Position := (sizeof(buf) * n * 100 div FileSize(FromF));
        application.ProcessMessages;
        //显示进度
        BlockWrite(ToF, Buf, NumRead, NumWritten);
        inc(n);
      until (NumRead = 0) or (NumWritten= NumRead);
      sb1.Panels[3].text := '进度';
      ProgressBar1.Position := 0;
      CloseFile(FromF);
      CloseFile(ToF);
    end;
      

  2.   

    楼上的大哥可能没了解我的意思,我的意思是程序里有多个窗口(form),每个窗口中都要用到复制功能,而且都需要有progressbar,按照我现在的代码,只能在没个form中加如上面的复制函数,这样这个函数就会有很多重复!!而且函数都一样!我试过把其他窗口中的函数去掉,只剩主窗口留了复制函数,但这样在其他窗口中复制时进度条无法显示,正确的来说进度显示在主窗口的progressbar中!
      

  3.   

    http://vcl.vclxx.org/DELPHI/D32FREE/COPYFDLL.ZIP
      

  4.   

    楼上的大哥给我的是动态创建一个进度条,和用shell来拷贝是一样的。能不能获取当前form上的progressbar控件,然后让函数指定到该progressbar?
      

  5.   

    能不能请各位大侠说说怎么才能获得复制文件时的速度 KB/s,还有剩余时间!
      

  6.   

    转贴的:拷贝文件时的进度条
    procedure TForm1.Button1Click(Sender: TObject);
    begin
       CopyFileWithProgressBar('D:\setup.exe', 'e:\temp\Welcome.exe');
       end;procedure TForm1.CopyFileWithProgressBar(Source, Destination: string);
    var
        FromF, ToF: file of byte;
        Buffer: array[0..4096] of char;
        NumRead: integer;
        FileLength: longint;begin
        AssignFile(FromF, Source);
        reset(FromF);
        AssignFile(ToF, Destination);
        rewrite(ToF);
        FileLength := FileSize(FromF);
        with ProgressBar1 do
        begin
            Min := 0;
            Max := FileLength;
            while FileLength > 0 do
            begin
                BlockRead(FromF, Buffer[0], SizeOf(Buffer), NumRead);
                FileLength := FileLength - NumRead;
                BlockWrite(ToF, Buffer[0], NumRead);
                Position := Position + NumRead;
            end;
            CloseFile(FromF);
            CloseFile(ToF);
        end;
    end;
      

  7.   

    把函数改为:
      function StreamCopy(FromFile, ToFile: String, Bar: TProgressBar): Boolean;