如何将ProgressBar用于SaveToFile
方法?实际上我想将资源保存到文件中,并且在保存时将进度条从0%更新到100%,我该怎么做?
答案 0 :(得分:6)
您可以在下面的代码中创建自己的TResourceStream后代。但对于大型资源(可能就是这种情况,否则你不必看到进展)最好将它“包装”在一个单独的线程中。如果你需要帮助,请大喊大叫。
type
TForm1 = class(TForm)
Button: TButton;
ProgressBar: TProgressBar;
procedure ButtonClick(Sender: TObject);
private
procedure StreamProgress(Sender: TObject; Percentage: Single);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
type
TStreamProgressEvent = procedure(Sender: TObject;
Percentage: Single) of object;
TProgressResourceStream = class(TResourceStream)
private
FOnProgress: TStreamProgressEvent;
public
procedure SaveToFile(const FileName: TFileName);
property OnProgress: TStreamProgressEvent read FOnProgress
write FOnProgress;
end;
{ TProgressResourceStream }
procedure TProgressResourceStream.SaveToFile(const FileName: TFileName);
var
Count: Int64;
Stream: TStream;
BlockSize: Int64;
P: PAnsiChar;
WriteCount: Int64;
begin
if Assigned(FOnProgress) then
begin
Count := Size;
if Count <> 0 then
begin
Stream := TFileStream.Create(FileName, fmCreate);
try
if Count < 500 then
BlockSize := 5
else
BlockSize := Count div 50;
P := Memory;
WriteCount := 0;
while WriteCount < Count do
begin
if WriteCount < Count - BlockSize then
Inc(WriteCount, Stream.Write(P^, BlockSize))
else
Inc(WriteCount, Stream.Write(P^, Count - WriteCount));
Inc(P, BlockSize);
FOnProgress(Self, WriteCount / Count);
end;
finally
Stream.Free;
end;
end;
end
else
inherited SaveToFile(FileName);
end;
{ TForm1 }
procedure TForm1.ButtonClick(Sender: TObject);
var
Stream: TProgressResourceStream;
begin
ProgressBar.Min := 0;
Stream := TProgressResourceStream.Create(HInstance, 'TFORM1', RT_RCDATA);
try
Stream.OnProgress := StreamProgress;
Stream.SaveToFile('TForm1.dat');
finally
Stream.Free;
end;
end;
procedure TForm1.StreamProgress(Sender: TObject; Percentage: Single);
begin
with ProgressBar do
Position := Round(Percentage * Max);
end;
答案 1 :(得分:4)
由于它继承自TStream,您可以使用Size属性获取总大小,使用Position来获取当前位置。您可以使用它们来“驱动”您的进度条。然后,不使用SaveToFile写入文件,而是使用单独的TFileStream并从TResourceStream逐块写入。您可以在最后一部分使用TStream.CopyFrom方法。