In den Cindy-Komponenten habe ich ein ProgressPanel gefunden und das wie Folgt adaptiert.
Die Threadlösung ist derzeit etwas zu groß für mich.
Bei dieser Lösung frieren aber auch alle Fenster ein. Das Progressfenster zeigt aber die Bars an und der Button kann den Prozess canceln.
Delphi-Quellcode:
type
TfrmProgress = class(TForm)
pb2: TProgressBar;
pb1: TProgressBar;
btn1: TButton;
procedure btn1Click(Sender: TObject);
procedure FormShow(Sender: TObject);
private
public
IsCanceled: Boolean;
function ProcessMessages(var Msg: TMsg): Boolean; overload;
procedure ProcessMessages; overload;
end;
var
frmProgress: TfrmProgress;
implementation
{$R *.dfm}
procedure TfrmProgress.ProcessMessages;
var
Msg: TMsg;
Cont: Boolean;
begin
cont := ProcessMessages(Msg);
while Cont do
cont := ProcessMessages(Msg);
end;
procedure TfrmProgress.btn1Click(Sender: TObject);
begin
IsCanceled := True;
end;
procedure TfrmProgress.FormShow(Sender: TObject);
begin
pb1.Position := 0;
IsCanceled := False;
end;
function TfrmProgress.ProcessMessages(var Msg: TMsg): Boolean;
var
aHandle: HWND;
begin
RESULT := false;
if IsCanceled then
EXIT;
aHandle := 0; // aHandle := FPanel.Handle doesn' t work if you click outiside the panel before clicking panel's cancel button ...
if PeekMessage(Msg, aHandle, 0, 0, PM_REMOVE) then
begin
Result := True;
if Msg.hwnd = btn1.Handle then
begin
Windows.TranslateMessage(Msg);
Windows.DispatchMessage(Msg);
end
else if Msg.message = WM_PAINT then // !!! Only WM_PAINT message are not removed from queue !!!
begin // In order to go outside while Cont do, we need to dispatch the message //
Windows.TranslateMessage(Msg);
Windows.DispatchMessage(Msg);
end;
end;
end;
Die Berechnungsschleife:
Delphi-Quellcode:
frmProgress.Show;
for i:= 0 to 1000
begin
Berechnung;
frmProgress.ProcessMessages;
if frmProgress.IsCanceled then
break;
end;
frmProgress.Close;