ShowModal?
Bis zum WaitFor kommt der dann ja nicht, falls nicht jemand vorher das Fenster schließt.
Wäre es da nicht andersrum besser?
Delphi-Quellcode:
var
LForm : TForm;
LThread : TThread;
begin
LForm := TSplashScreen.Create(nil);
try
LThread := TStartupThread.Create(LForm);
try
LForm.Show;
LThread.WaitFor;
LForm.Hide;
finally
LThread.Free;
end;
finally
LForm.Free;
end;
end;
// oder
var
LForm : TForm;
LThread : TThread;
begin
LThread := TStartupThread.Create;
try
LForm := TSplashScreen.Create(nil);
try
LForm.Show;
LThread.WaitFor;
finally
LForm.Free;
end;
finally
LThread.Free;
end;
end;
Wie schon erwähnt, müssen die
VCL-Komponenten im
Hauptthread VCL-Thread bleiben.
Man könnte zwar in anderen Threads direkt via
WinAPI Formulare nzeigen, aber diese müssen dann komplett in dem Thread erstellt, behandelt und freigegeben werden, inkl. eigener Message-Loop.
Bei deiner Variante wird der MainThread aber blockiert
Delphi-Quellcode:
LForm.Show;
// Wir befinden uns im MainThread-Context und da tut sich jetzt nichts mehr, bis der Thread abgearbeitet ist
LThread.WaitFor;
und das ist bei meiner Variante eben genau
nicht der Fall.
TStartupThread
muss lediglich am Ende eine Nachricht an die Form schicken, damit die geschlossen wird.
Hier mal so ein Beispiel StartupThread
Delphi-Quellcode:
unit StartupThread;
interface
uses
FormThreadWait,
System.SysUtils,
Classes;
type
TStartupThread =
class( TThread )
private
FCloseForm : TThreadProcedure;
FInfoToForm : TProc<
string>;
procedure InfoToForm(
const AInfo :
string );
protected
procedure DoExecute;
virtual;
procedure Execute;
override;
public
constructor Create( AForm : TThreadWaitForm );
end;
implementation
{ TStartupThread }
constructor TStartupThread.Create( AForm : TThreadWaitForm );
begin
inherited Create( False );
// Anonyme Methode zum Schließen der Form
FCloseForm :=
procedure
begin
AForm.Close;
end;
FInfoToForm :=
procedure( AInfo :
string )
begin
AForm.Label1.Caption := AInfo;
end;
end;
procedure TStartupThread.DoExecute;
var
LIdx : Integer;
begin
InfoToForm( '
Initialisierung...' );
Sleep( 500 );
for LIdx := 1
to 20
do
begin
InfoToForm( '
Schritt ' + IntToStr( LIdx ) );
Sleep( 250 );
end;
end;
procedure TStartupThread.Execute;
begin
inherited;
try
DoExecute;
finally
// Form schließen synchronisiert abschicken
// Queue würde auch gehen, aber was sollen wir in der Zwischenzeit noch machen, wir sind fertig ;o)
Synchronize( FCloseForm );
end;
end;
procedure TStartupThread.InfoToForm(
const AInfo :
string );
begin
Queue(
procedure
begin
FInfoToForm( AInfo );
end );
end;
end.
Anwendung im Anhang (kompiliert und als Source)
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ea 0a 4c 14 0d b6 3a a4 c1 c5 b9
dc 90 9d f0 e9 de 13 da 60)