Abbrevia ProgressBar

2.2k Views Asked by At

I am using the Open Source Abbrevia Components to Archive some Files into a single Zip, whilst this is happening I am using the TAbMeter Gauge to display the progress.

I would prefer to use the TProgressBar for this purpose instead though (maintaining a standard interface with Windows).

How may I use a TProgressBar instead of the TAbMeter? I know I could code the progress myself, but seeing as the Abbrevia Components already have this done in the TAbMeter, I see no sense in rewriting it.

If I could even access the Position property of the TAbMeter I could simulate the TProgressBar's progress by synchronizing with the TAbMeter.

Here is a snippet, FileNames is a TStringList containing the Filenames to archive..

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;
2

There are 2 best solutions below

6
On BEST ANSWER

You are presumably setting the ArchiveSaveProgressMeter somewhere in your code. You can simply stop doing this and instead set the OnArchiveSaveProgress event. Then you need to supply an event with this signature:

procedure(Sender: TObject; Progress: Byte; var Abort: Boolean) of object;

You would respond to receipt of such an event by updating the Position value of the progress bar in your UI.

The method that surfaces this progress event also handles the progress meter version:

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;

So the designers of the component have simply provided two alternative routes to receiving progress: the meter or a callback.


In order to handle progress from a callback you need to write a method like this:

procedure TMyMainForm.OnArchiveSaveProgress(
  Sender: TObject; Progress: Byte; var Abort: Boolean);
begin
  FProgressBar.Position := Progress;
end;

You then assign this event handler to OnArchiveSaveProgress, most likely in the IDE. It's an identical procedure to assigning an OnClick event to a button.


Note: I've never used Abbrevia so I may have picked out a different component from the one you are using. However, all the components that interact with meters, also offer progress via a callback so this basic approach will work no matter which component you use.

0
On

In case it helps anyone else, I've created a new TAbProgressBar component that can be used instead of TAbMeter. They both implement the same interface, so it works with the same Archive*ProgressMeter properties. Just update Abbrevia from Subversion and recompile the AbbreviaVCL and AbbreviaVCLDesign packages.