Zitat von
SirThornberry:
Naja, auf den ersten Blick ok. Auf den zweiten Blick sieht man das du im Thread auf ein
VCL-Object zugreifst ohne den Zugriff zu syncronisieren. Dabei ist es mehr als wahrscheinlich das als Effekt davon später im Programm tolle Effekte auftreten.
Hmm ja, naja das Problem ist halt, dass in der ersten Hälfte, während das Programm noch lädt, nichts von den Event-Handlern de Form bedient wird. Also zumindest hatte ich einen Timer drin, und mein Splash hat sich nicht eingefadet. Ich hab irgendwie das gefühl, wenn man das mit Synchronize macht, blendet sich das Ding erst ein wenn sich das Hauptfenster auch öffnet... liege ich falsch?
Zitat von
SirThornberry:
Zudem verwendet dein Thread eine globale Variable um das Splashform zu finden. Wenn wir aber einmal bei Objecten sind macht es doch mehr sinn dem Thread gleich das Fenster mitzugeben um zu vermeiden das da irgendwann 2 Threads mal auf dem gleichen Fenster rumrödeln
Hm, wäre einen Versuch Wert. Danke für die Tipps!
Edit: Habs jetzt mal so ummodelliert... und wie vermutet blendet sich die Form erst ein, wenn das Programm eh fertig geladen hat...
Delphi-Quellcode:
begin
FadeThread := TFadeThread.Create(False);
try
Application.Initialize;
Application.CreateForm(TMainForm, MainForm);
finally
FadeThread.InitializationDone := True;
end;
Application.Run;
end.
Delphi-Quellcode:
type
TSplashForm = class(TForm)
SplashImage: TImage;
SplashTimer: TTimer;
CloseBtn: TButton;
procedure SplashTimerTimer(Sender: TObject);
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
public
{ Public declarations }
end;
type
TFadeThread = class(TThread)
private
{ Private-Deklarationen }
FInitializationDone: Boolean;
FSplashForm: TSplashForm;
procedure CreateForm;
procedure DoFade;
procedure SetInitializationDone(const Value: Boolean);
protected
procedure Execute; override;
public
FadeActive: Boolean;
property InitializationDone: Boolean read FInitializationDone write SetInitializationDone;
end;
var
FadeThread: TFadeThread;
implementation
{$R *.DFM}
procedure TFadeThread.CreateForm;
begin
FSplashForm := TSplashForm.Create(Application);
FSplashForm.Show;
FSplashForm.Refresh;
end;
procedure TFadeThread.DoFade;
begin
if not FInitializationDone or FSplashForm.SplashTimer.Enabled then
begin
//Fade-In
if FSplashForm.AlphaBlendValue < 255 then
FSplashForm.AlphaBlendValue := FSplashForm.AlphaBlendValue + 17
else
FadeActive := False;
end else
begin
//Fade-Out
if FSplashForm.AlphaBlendValue > 0 then
FSplashForm.AlphaBlendValue := FSplashForm.AlphaBlendValue - 17
else
begin
FadeActive := False;
Terminate;
FSplashForm.Close;
FSplashForm := nil;
end;
end;
end;
procedure TFadeThread.Execute;
begin
FadeActive := True;
Synchronize(CreateForm);
while (FSplashForm <> nil) and not Terminated do
begin
Synchronize(DoFade);
Sleep(40);
end;
end;
procedure TFadeThread.SetInitializationDone(const Value: Boolean);
begin
FInitializationDone := Value;
end;
procedure TSplashForm.SplashTimerTimer(Sender: TObject);
begin
SplashTimer.Enabled := False;
FadeThread.FadeActive := True;
end;
procedure TSplashForm.FormCloseQuery(Sender: TObject;
var CanClose: Boolean);
begin
CanClose := FadeThread.Terminated;
end;
procedure TSplashForm.FormClose(Sender: TObject;
var Action: TCloseAction);
begin
FadeThread := nil;
Action := caFree;
end;
Was mache ich falsch? Oder ist das Problem, dass meine Variante so gar nicht realisierbar ist? Ich hab hier einen anderen Thread verlinkt gefunden mit Fade-In, aber da wurde das ei OnAvtivate im selben Thread gemacht - was dazu führt, dass die Startzeit um die Fade-In-Zeit verlängert wird - aber ich wollte ja eigentlich zumindest die gefühlte Wartezeit verkürzen
Edit: Ich habe es jetzt mal wiefolgt gemacht: Die SplashForm wird in der
DPR erzeugt und an den Thread zugewiesen (welcher erst nach der Zuweisung gestartet wird). Solange FInitializationDone noch auf false steht, wird ohne Synchronisierung gefadet, danach mit. Ich das in Ordnong? Oder nicht?