Thema: Delphi Tutorial: Splash Screens

Einzelnen Beitrag anzeigen

derula

Registriert seit: 16. Mär 2008
11 Beiträge
 
Delphi 7 Personal
 
#90

Re: Tutorial: Splash Screens

  Alt 26. Sep 2008, 08:10
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?
  Mit Zitat antworten Zitat