madNVPrgrAlert Unit 

www.madshi.net

In some situations madExcept needs to show a progress bar. Since that often happens to be in the context of secondary threads, the progress bar window has to be thread safe. The unit "madNVPrgrAlert" simply implements a nice little thread safe progress bar window.

The progress bar window is represented by an interface named "IProgressAlert". You can create a new progress bar by calling "NewProgressAlert", which returns an instance of the mentioned interface. Optionally you can specify a module handle and resource name for a 32x32 sized bitmap (must have a color depth of 32 bits per pixel including an 8 bit alpha channel), which will then be shown in the progress window.

type
  IProgressAlert = interface ['{45B8448C-47B8-4F1C-886E-95ED5FD41E5F}'];

function NewProgressAlert (title     : string;
                           bmpModule : dword  = 0;
                           bmpName   : string = '') : IProgressAlert;

Before really using the progress alert you should set up the progress bar properties. This works by specifying the progress areas which you plan to run through later. E.g. if you want to copy 10 files, you could set up one progress area for each file. Generally please set up all progress areas, before you even show the window. That makes sure that the size of the window is correctly set up, so that all area texts can be written in it without needing a resize.

// step 1: setup all progress areas
procedure IProgressAlert.AddArea (weight: int64; text: string = '');

When the progress areas are all setup correctly, you can finally show the progress bar window:

// step 2: show the progress alert
function IProgressAlert.Show (parentWindow: dword = 0; activate: boolean = true) : boolean;

Each area always goes from 0 to 1000. So let's say the first file which you want to copy is 10000 bytes long. In that case you should move the progress bar by 1 every 10 bytes you've copied. If you're doing time consuming stuff, you might want to call the "ProcessMessages" method from time to time, so that the progress bar window still redraws correctly. After each progress area is through, call "AreaDone" to enter the next area.

// step 3: update the progress bar position & loop through the progress areas
property  IProgressAlert.Position : integer;
procedure IProgressAlert.ProcessMessages;
procedure IProgressAlert.AreaDone;

When everything is done, you can close the progress bar window. This is automatically done when the "IProgressAlert" interface is destroyed. However, if you don't want to rely on Delphi's interface reference counting mechanism, you can manually close the window.

// step 4: closing the progress bar window
procedure IProgressAlert.Close;

There are some more properties and methods, which you can use, if you like.

property  IProgressAlert.Title       : string;   // progress bar window title
property  IProgressAlert.CurrentArea : integer;  // which progress area are we currently in?
procedure IProgressAlert.ClearAreas;             // delete all progress areas

To make things more clear, here's a full little example for you:

// Example:

var i1, i2 : integer;
begin
  with NewProgressAlert('Progress window title...') do begin
    AddArea(1000, 'This is the first progress area.');
    AddArea(2000, 'The 2nd area is more time consuming...');
    Show;
    for i1 := 1 to 2 do begin
      for i2 := 1 to 100 do begin
        Sleep(10 * i1);
        Position := i2 * 10;
        ProcessMessages;
      end;
      AreaDone;
    end;
    Close;
  end;