Delphi-PRAXiS
Seite 9 von 10   « Erste     789 10      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Tutorials und Kurse (https://www.delphipraxis.net/36-tutorials-und-kurse/)
-   -   Delphi Tutorial: Splash Screens (https://www.delphipraxis.net/8637-tutorial-splash-screens.html)

Svenkan 2. Mai 2007 15:41

Re: Tutorial: Splash Screens
 
3000

Nur sollten diese 3sec eigtl keine Ewigkeit dauern. ^^
Der OnClose-Befehl wird ja auch ausgeführt, aber das Fenster lässt sich einfach nicht schließen.
Also kommt der Befehl ja auch an. Es passiert nur einfach nichts. oO

/edit: Habe in die Prozedur 'SetInitializationDone' einen Labelwechsel mit eingebaut und merke grade, dass dieser nie vorgenommen wird.
Ich glaube jetzt mal, dass dort der Fehler liegt und deswegen 'CanClose' auf auf 'False' bleibt.

/edit2: Ich habs! Ich hab vergessen 'Application.CreateForm(TSplash, Splash);' rauszunehmen. :wall:

bacci 6. Feb 2008 23:39

Re: Tutorial: Splash Screens
 
[quote="Kernel32.DLL"]@DymonD

Jepp, so in etwa...

In der Delphi 5 Hilfe steht:
Delphi-Quellcode:
begin
  Application.Initialize;
  with TForm5.Create(nil) do
  try
    ProgressBar1.Max := 100;
    Show;  // Startbildschirm mit ProgressBar anzeigen
    Update; // Anzeige von Form5 auslösen
    Application.CreateForm(TForm1, Form1);
    ProgressBar1.StepBy(25);
    Application.CreateForm(TForm2, Form2);
    ProgressBar1.StepBy(25);
    Application.CreateForm(TForm3, Form3);
    ProgressBar1.StepBy(25);
    Application.CreateForm(TForm4, Form4);

    ProgressBar1.StepBy(25);
  finally
    Free;
  end;
  Application.Run;
end.


[quote]

So ... leider ist mein Delphi wissen noch vieeeel zu wenig, ich hab das auch so versucht, aber hat nicht geklappt, die ProgressBar zeigt nichts an.
Habe mal die RzProgressbar versucht, auch da klappts nicht.

kann mir jemand sagen was ich schon wieder falsch mache, bzw vergessen habe ;-(

Mein dpr- file:

Delphi-Quellcode:
program Kundenverwaltung;

uses
  Forms,
  form_kunden in 'form_kunden.pas' {kunden},
  main in 'main.pas' {Master},
  form_mitarbeiter in 'form_mitarbeiter.pas' {Mitarbeiter},
  form_artikel in 'form_artikel.pas' {Artikel},
  form_auftragsverwaltung in 'form_auftragsverwaltung.pas' {Auftragsverwaltung},
  form_bestellung in 'form_bestellung.pas' {bestellung},
  form_rechnung in 'form_rechnung.pas' {Rechnung},
  splash in 'splash.pas' {Form1},
  form_alte_bestellung in 'form_alte_bestellung.pas' {alte_bestellungen};

{$R *.res}

begin
 //


Form1 := TForm1.Create(Application);
  with TForm1.Create(nil) do
 try
RzProgressBar1.visible:=true;
RzProgressBar1.percent:=0;
  Form1.Show;
  Form1.Refresh;
  Application.Title := 'KAV - IDL stone solutions';
  Application.Initialize;
  Application.Title := 'IDL KAV';
  Application.CreateForm(TMaster, Master);
  Application.CreateForm(Tkunden, kunden);
RzProgressBar1.percent:=40;
  Application.CreateForm(Tbestellung, bestellung);
  Application.CreateForm(TRechnung, Rechnung);
RzProgressBar1.percent:=60;
  Application.CreateForm(Talte_bestellungen, alte_bestellungen);
  Application.CreateForm(TMitarbeiter, Mitarbeiter);
RzProgressBar1.percent:=80;
  Application.CreateForm(TArtikel, Artikel);
  Application.CreateForm(TAuftragsverwaltung, Auftragsverwaltung);
RzProgressBar1.percent:=100;
RzProgressBar1.visible:=false;

  Finally
// SplashScreen Fenster freigeben
 Form1.InitializationDone := True;
end;
//  while form1 <> nil do
//  Application.ProcessMessages;
  Application.Run;
end.

Danke für eure Mühe, aber nach 2 Tagen Google und Forum durchsuchen hab ich jetzt aufgegeben und frage dann doch ... ;-((

xZise 20. Mär 2008 19:26

Re: Tutorial: Splash Screens
 
Zitat:

Zitat von bacci
[...]

Delphi-Quellcode:
program Kundenverwaltung;

uses
  Forms,
  form_kunden in 'form_kunden.pas' {kunden},
  main in 'main.pas' {Master},
  form_mitarbeiter in 'form_mitarbeiter.pas' {Mitarbeiter},
  form_artikel in 'form_artikel.pas' {Artikel},
  form_auftragsverwaltung in 'form_auftragsverwaltung.pas' {Auftragsverwaltung},
  form_bestellung in 'form_bestellung.pas' {bestellung},
  form_rechnung in 'form_rechnung.pas' {Rechnung},
  splash in 'splash.pas' {Form1},
  form_alte_bestellung in 'form_alte_bestellung.pas' {alte_bestellungen};

{$R *.res}

begin
 //


Form1 := TForm1.Create(Application);
  with TForm1.Create(nil) do
 try
RzProgressBar1.visible:=true;
RzProgressBar1.percent:=0;
  Form1.Show;
  Form1.Refresh;
  Application.Title := 'KAV - IDL stone solutions';
  Application.Initialize;
  Application.Title := 'IDL KAV';
  Application.CreateForm(TMaster, Master);
  Application.CreateForm(Tkunden, kunden);
RzProgressBar1.percent:=40;
  Application.CreateForm(Tbestellung, bestellung);
  Application.CreateForm(TRechnung, Rechnung);
RzProgressBar1.percent:=60;
  Application.CreateForm(Talte_bestellungen, alte_bestellungen);
  Application.CreateForm(TMitarbeiter, Mitarbeiter);
RzProgressBar1.percent:=80;
  Application.CreateForm(TArtikel, Artikel);
  Application.CreateForm(TAuftragsverwaltung, Auftragsverwaltung);
RzProgressBar1.percent:=100;
RzProgressBar1.visible:=false;

  Finally
// SplashScreen Fenster freigeben
 Form1.InitializationDone := True;
end;
//  while form1 <> nil do
//  Application.ProcessMessages;
  Application.Run;
end.

Danke für eure Mühe, aber nach 2 Tagen Google und Forum durchsuchen hab ich jetzt aufgegeben und frage dann doch ... ;-((

Is zwar schon etwas her.
Aber: Ich würde folgendes machen.
Erstmal solltest du verstehen, was "with" macht. Dann solltest du wissen, was ".Create" für auswirkungen hat, und dann ist es ganz einfach ;)

Ich mach das mal ganz kurz:
Delphi-Quellcode:
Form1 := TForm1.Create(Application);
with Form1 do // Du arbeitest mit dem Objekt bzw. der Instanz "Form1" und nicht mit einem neuen Objekt!
  try
    // Fenster erstellen
    ...
    // Hier nun die Progressbar weitergehen lassen ^^
    RzProgressBar1.Percent := <0..100>
    // Und jedesmal NEUZEICHNEN
    RzProgressBar1.Repaint;

    // Und nochmal
    // Fenster erstellen
    ...
    // Hier nun die Progressbar weitergehen lassen ^^
    RzProgressBar1.Percent := <0..100>
    // Und jedesmal NEUZEICHNEN
    RzProgressBar1.Repaint;

    // Und nochmal
    // Fenster erstellen
    ...
    // Hier nun die Progressbar weitergehen lassen ^^
    RzProgressBar1.Percent := <0..100>
    // Und jedesmal NEUZEICHNEN
    RzProgressBar1.Repaint;

    // Bis alle Fenster erstellt wurden!
  finally
    InitializationDone := true; // Kein Form1 weil du ja schon sagst, dass er überall "Form1" davorsetzen soll (with <...> do)
  end;

Application.Done;

bacci 20. Mär 2008 21:45

Re: Tutorial: Splash Screens
 
Vielen Dank,

auch für die gute Erklärung, werde das die Tage mal ausprobieren.
Melde mich dann nochmal.
Ich hab da noch ein Problem und zwar möchte ich, bevor er das alle macht erst testen lassen ob die Datenbankverbindung da ist, diese ist Extern (MySQL) und wenn die Verbindung nicht da ist soll er das "sozusagen" mit einer Meldung bekanntgeben und das Programm dann gar nicht erst öffnen, da es ein haufen fehlermeldungen gibt wenn die Verbindung nicht steht.

Dazu schreibe ich aber noch genaueres, kann gerade nicht an meinen Notebook ran wo alles drauf ist ;-(


Special TXH an xZise

Deltachaos 13. Mai 2008 15:08

Re: Tutorial: Splash Screens
 
Ich glaube ich habe eine Möglichkeit die einfacher und schneller ist:

So geht's:

* Ein weiteres Formular erstellen. Dieses wird unser Splash Screen werden.
* Den Namen des Formulars z. B. in "SplashScreen" ändern. Dieser wird später noch verwendet.
* Diese Eigenschaften des Formulars ändern: BorderStyle auf bsNone und Position auf poScreenCenter
* Das Formular frei gestalten: Beschriftungen, Grafiken oder andere Komponenten hinzufügen.
* Im Menü: Projekt>>Optionen>>Formulare das Splash-Formular auf die rechte Seite bringen (als verfügbares/available Formular). Das Formular werden wir später nämlich dynamisch laden.
* Den Quelltext des Projekts (Hauptprogramm - nicht eine der Units!!!) anzeigen lassen. Dazu im Menü: Projekt>>Quellcode anschauen. Für Delphi kleiner Version 4: Ansicht>>Projekt-Quelltext.
* Folgenden Code nach der Begin-Anweisung einfügen:

SplashScreen := TSplashScreen.Create(Application);
SplashScreen.Show;
Application.Initialize; //diese Zeile existiert schon! - nicht noch mal rein
SplashScreen.Update;

* Nach der letzten Application.Create() und vor der Application.Run-Anweisung folgendes hinzufügen:

SplashScreen.Hide;
SplashScreen.Release;

* Das war's! Jetzt müsste der Splash Screen solange angezeigt werden, wie das Hauptformular lädt.
Und wenn man ihn für eine bestimmte Zeit anzeigen lassen möchte dann muss man nur in das Hauptforular an erster stelle ein sleep(3000); einfügen

MasterEvil 7. Jul 2008 14:07

Re: Tutorial: Splash Screens
 
Hat auch jemand eine Lösung mti Delphi2007 und Application.MainFormOnTaskbar:=true?
Dort ist das Problem: wenn du MainFormOnTaskbar auf true stellst vor dem Application.Initialize, dann hat der SplashScreen keinen Taskbar-Eintrag. Stellt man MaiNFormOnTaskbar erst nach dem Anzeigen des SplashScreens auf true gibt es interessante Nebenwirkungen (zusätzlicher leerer Taskbar-Eintrag).
Gebe ich dem SplashScreen über CreateParams einen eigenen Taskbar-Eintrag und setze MainFormOnTaskbar wieder vor Initialize, dann kann es unter Vista passieren, dass es einen zweiten leeren Eintrag gibt ...
Dort schon jemand eine Möglichkeit gefunden?

Gruß,
Steffen

Cosamia 4. Aug 2008 08:53

Re: Tutorial: Splash Screens
 
Zitat:

Zitat von MasterEvil
Hat auch jemand eine Lösung mti Delphi2007 und Application.MainFormOnTaskbar:=true?
Dort ist das Problem: wenn du MainFormOnTaskbar auf true stellst vor dem Application.Initialize, dann hat der SplashScreen keinen Taskbar-Eintrag. Stellt man MaiNFormOnTaskbar erst nach dem Anzeigen des SplashScreens auf true gibt es interessante Nebenwirkungen (zusätzlicher leerer Taskbar-Eintrag).
Gebe ich dem SplashScreen über CreateParams einen eigenen Taskbar-Eintrag und setze MainFormOnTaskbar wieder vor Initialize, dann kann es unter Vista passieren, dass es einen zweiten leeren Eintrag gibt ...
Dort schon jemand eine Möglichkeit gefunden?

Gruß,
Steffen

selbiges Problem habe ich auch. Delphi 2007 verhält sich da unter Vista etwas seltsam. :pale:

derula 26. Sep 2008 03:25

Re: Tutorial: Splash Screens
 
Hi, keine Ahnung, ob das erwünscht ist, aber ich hätte ne Modifikation des Originaltutorials mit Fade-In /-Out. Und zwar wird dies über einen Thread gesteuert. Funktioniert, und es wird auch wie ich das sehen kann alles wieder ordnungsgemäß freigegeben.

DPR:
Delphi-Quellcode:
begin
  SplashForm := TSplashForm.Create(Application);
  try
    SplashForm.Show;
    SplashForm.Refresh;
    FadeThread := TFadeThread.Create(False);
    Application.Initialize;
    Application.CreateForm(TMainForm, MainForm);
  finally
    SplashForm.InitializationDone := True;
  end;
  Application.Run;
end.
SplashUnit.pas (bei mir):
Delphi-Quellcode:
type
  TSplashForm = class(TTntForm)
    SplashImage: TImage;
    SplashTimer: TTimer;
    CloseBtn: TTntButton;
    procedure SplashTimerTimer(Sender: TObject);
    procedure TntFormCloseQuery(Sender: TObject; var CanClose: Boolean);
    procedure TntFormClose(Sender: TObject; var Action: TCloseAction);
  private
    FInitializationDone: Boolean;
    { Private declarations }
    procedure SetInitializationDone(const Value: Boolean);
  public
    { Public declarations }
    property InitializationDone: Boolean read FInitializationDone write SetInitializationDone;
  end;

type
  TFadeThread = class(TThread)
  private
    { Private-Deklarationen }
  protected
    procedure Execute; override;
  public
    FadeActive: Boolean;
  end;

var
  SplashForm: TSplashForm;
  FadeThread: TFadeThread;

implementation

{$R *.DFM}

procedure TFadeThread.Execute;
begin
  FadeActive := True;
  while (SplashForm <> nil) and not Terminated do
  begin
    if not SplashForm.InitializationDone or SplashForm.SplashTimer.Enabled then
    begin
      //Fade-In
      if SplashForm.AlphaBlendValue < 255 then
        SplashForm.AlphaBlendValue := SplashForm.AlphaBlendValue + 17
      else
        FadeActive := False;
    end else
    begin
      //Fade-Out
      if SplashForm.AlphaBlendValue > 0 then
        SplashForm.AlphaBlendValue := SplashForm.AlphaBlendValue - 17
      else
      begin
        FadeActive := False;
        Terminate;
        SplashForm.Close;
      end;
    end;
    Sleep(40);
  end;
end;

procedure TSplashForm.SetInitializationDone(const Value: Boolean);
begin
  FInitializationDone := Value;
  Close;
end;

procedure TSplashForm.SplashTimerTimer(Sender: TObject);
begin
  SplashTimer.Enabled := False;
  FadeThread.FadeActive := True;
end;

procedure TSplashForm.TntFormCloseQuery(Sender: TObject;
  var CanClose: Boolean);
begin
  CanClose := FadeThread.Terminated;
end;

procedure TSplashForm.TntFormClose(Sender: TObject;
  var Action: TCloseAction);
begin
  FadeThread := nil;
  Action := caFree;
  SplashForm := nil;
end;
Warum 17? Weil 17*15=255. ^^ Das Form muss natürlich vorher mit AlphaBlend := True bestückt werden.

In diesem Sinne: Viel Spaß (und gute Nacht *aufdieuhrseh*)

SirThornberry 26. Sep 2008 06:15

Re: Tutorial: Splash Screens
 
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.
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 :-)

derula 26. Sep 2008 07:10

Re: Tutorial: Splash Screens
 
Zitat:

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:

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?


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:10 Uhr.
Seite 9 von 10   « Erste     789 10      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz