我正在使用开源Abbrevia组件将某些文件存档到单个Zip中,而这种情况正在发生,我正在使用TAbMeter量规来显示进度。
我宁愿为此而使用TProgressBar(与Windows保持标准接口(interface))。
如何使用TProgressBar代替TAbMeter?我知道我可以自己编写进度,但由于Abbrevia组件已经在TAbMeter中完成了此工作,因此我认为没有必要重写它。
如果我什至可以访问TAbMeter的Position属性,也可以通过与TAbMeter同步来模拟TProgressBar的进度。
这是一个代码段,FileNames是一个TStringList,其中包含要存档的文件名。
procedure ArchiveFiles(SaveAs: string; ProgressBar: TAbMeter);
var
AZipper: TAbZipper;
i: Integer;
begin
AZipper := TAbZipper.Create(nil);
try
AZipper.AutoSave := False;
AZipper.BaseDirectory := ExtractFilePath(SaveAs);
AZipper.ArchiveSaveProgressMeter := ProgressBar;
AZipper.FileName := SaveAs;
AZipper.StoreOptions := AZipper.StoreOptions + [soStripDrive, soRemoveDots]
- [soStripPath];
AZipper.TempDirectory := GetTempDirectory;
try
Screen.Cursor := crHourGlass;
ProgressBar.Visible := True;
for i := 0 to FileList.Count - 1 do
begin
AZipper.AddFiles(FileList.Strings[i], 0);
end;
finally
AZipper.Save;
AZipper.CloseArchive;
ProgressBar.Visible := False;
Screen.Cursor := crDefault;
end;
finally
AZipper.Free;
end;
end;
最佳答案
您大概在代码中的某处设置了ArchiveSaveProgressMeter
。您可以简单地停止这样做,而是设置OnArchiveSaveProgress
事件。然后,您需要提供一个带有此签名的事件:
procedure(Sender: TObject; Progress: Byte; var Abort: Boolean) of object;
您将通过更新UI中进度条的
Position
值来响应此类事件的接收。出现此进度事件的方法还可以处理进度表版本:
procedure TAbCustomZipper.DoArchiveSaveProgress(
Sender: TObject; Progress: Byte; var Abort : Boolean);
begin
Abort := False;
if Assigned(FArchiveSaveProgressMeter) then
FArchiveSaveProgressMeter.DoProgress(Progress);
if Assigned(FOnArchiveSaveProgress) then
FOnArchiveSaveProgress(Self, Progress, Abort);
end;
因此,组件的设计人员仅提供了两种接收进度的替代路线:仪表或回调。
为了处理回调的进度,您需要编写如下方法:
procedure TMyMainForm.OnArchiveSaveProgress(
Sender: TObject; Progress: Byte; var Abort: Boolean);
begin
FProgressBar.Position := Progress;
end;
然后,您可以将此事件处理程序分配给
OnArchiveSaveProgress
,这很可能是在IDE中进行的。向按钮分配OnClick
事件是一个完全相同的过程。注意:我从未使用过Abbrevia,所以我可能选择了与您使用的组件不同的组件。但是,与仪表交互的所有组件也都通过回调提供进度,因此,无论您使用哪个组件,此基本方法都将起作用。