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.
 |
procedure IProgressAlert. AddArea (weight: int64; text: string = '');
|
|
When the progress areas are all setup correctly, you can finally show the
progress bar window:
 |
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.
 |
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.
 |
procedure IProgressAlert. Close;
|
|
There are some more properties and methods, which you can use, if you like.
 |
property IProgressAlert. Title : string;
property IProgressAlert. CurrentArea : integer;
procedure IProgressAlert. ClearAreas;
|
|
To make things more clear, here's a full little example for you:
 |
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;
|
|