Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   TForm anzeigen obwohl Terminate bei TForm OnCreate (https://www.delphipraxis.net/157530-tform-anzeigen-obwohl-terminate-bei-tform-oncreate.html)

Mike_ 15. Jan 2011 02:52

Delphi-Version: 2007

TForm anzeigen obwohl Terminate bei TForm OnCreate
 
Guten Abend,

es geht um folgenden Sachverhalt:

Ich habe einen Autoupdater geschrieben, welcher über Parameter das entsprechende Programm updated.

Er soll bei dem Startvorgang die GUI anzeigen als auch sofort die Prozeduren/Funktionen, welche ich über den Parameter aufrufe.


Derzeit habe ich diesen Teil in "OnCreate" hereingepackt, leider zeigt er mir dann aber keine GUI an und schließt das Programm nachdem die Funktionen/Prozeduren abgearbeitet sind.

Google und die Boarsuche ergaben ein altes Programm, welches den Mausklick eines Buttons simuliert.
M.M.n. ist das aber sehr schlecht programmiertechnisch gelöst und müsste doch viel einfacher gehen ?!


Also die Frage:

Wie kann man zu erst die GUI aufbauen lassen und danach die Funktionen automatisch abarbeiten lassen ?



Update1:
Als Lösung geht einfach folgendes in das OnCreate hinein zu schreiben:
Form1.Visible := True;

Allerdings ist die Frage: Ist das "sauber" programmiertechnisch gelöst ?


Update2:
Mit Visible := True klappt es nur bedingt.
Mein TImage wird mir nicht angezeigt/aufgebaut mit diesem Befehl.
Das Programm setzt wirklich nur die Form auf visible := true und arbeitet zu erst die ganzen anderen Prozeduren ab, bevor mein TImage auf der Form angezeigt wird...

Wie kann man denn sonst die Form zu erst aufrufen und danach (mit kleiner Verzögerung ?) eine andere Procedur aufrufen, welche alles in Gang bringt ?
[Möglichst kurzer, sauberer Quellcode]

Luckie 15. Jan 2011 05:21

AW: TForm anzeigen obwohl Terminate bei TForm OnCreate
 
Erst mal zu deiner Überschrift:
Zitat:

TForm anzeigen obwohl Terminate bei TForm OnCreate
Überlege mal, ob das funktionieren kann. Entweder zeigst du dein Fenster an oder du beendest das Programm. Eins von beiden geht nur. Du kannst ja auch nicht gleichzeitig in ein Auto einsteigen und aussteigen.

Führe den Programmcode im OnShow Ereignis der Form aus.

Mike_ 15. Jan 2011 05:52

AW: TForm anzeigen obwohl Terminate bei TForm OnCreate
 
Erst einmal danke für deine Antwort !

Ich habe als kleinen "Kniff" ein Sleep(5000) eingebaut, nicht dass das Programm gar nicht erscheint weil es so schnell durchgelaufen ist.

Bei OnShow zeigt er überhaupt nichts an und schließt nach erfolreichem ausführen.

Bei OnActivate zeigt er mir einen Tab in der Taskleiste vom Programm an, das Programm an sich ist aber "hidden" und schließt danach.

Bei dem Ereignis "OnPaint" klappt es nun endlich und er zeigt das Programm an, lädt mir aber mein TImage nicht (Sehe nur die Progressbar und leere Form)...

Das TImage ist nicht auf hidden gesetzt, wenn ich das Application.Terminate herausnehme zeigt er es mir nach dem Ausführen des Codes auch an... was kann ich tun ?

Habe versucht es zu hiden und manuell bei Codeaufruf auf Visible=True zu setzen, war leider vergebens.


Update1:
Ebenfalls habe ich versucht die Anweisungen für den Programmstart im "OnProgress" Event des TImage zu setzen, jedoch wird diese Anweisung dann nicht ausgeführt beim Programmstart.

Gibt es vllt eine Function die als Boolean zurückgibt dass ein TImage aufgebaut ist ? [Auf Visible ist es sowieso gesetzt...]

Anthrox 15. Jan 2011 06:39

AW: TForm anzeigen obwohl Terminate bei TForm OnCreate
 
Vielleicht liesse sich mit Threads etwas machen.
Ich habe es mir nicht genau durchüberlegt aber wenn du die Teile welche auch das Terminate enthalten in einen Thread auslagern würdest und am Ende vlt. noch ein Sleep(1000).
Das könnte gehen. Wieso willst du denn das die Form angezeigt wird? Du könntest vorher ja eine Message anzeigen lassen.

MfG Anthrox

haentschman 15. Jan 2011 07:23

AW: TForm anzeigen obwohl Terminate bei TForm OnCreate
 
Moin...
Zitat:

Bei OnShow zeigt er überhaupt nichts an und schließt nach erfolreichem ausführen.
- im OnShow kannst du auch noch nichts sehen, weil OnShow ausgeführt wird bevor die Controls / Form angezeigt werden.
- den Funktionscode im OnPaint ist das schlechteste, was du machen kannst.

Lösung:
- du mußt dir ein "OnAfterShow" Ereignis basteln damit OnShow komplett abgearbeitet wird und alles angezeigt wird.
Delphi-Quellcode:
const
  WM_FERTIG = WM_USER + 100; //Name frei wählbar
.
.
private
  procedure HabeFertig(var Msg: TMessage); Message WM_FERTIG;
.
.

procedure TFMain.FormShow(Sender: TObject);
begin
. // Controls einstellen etc.
.
  PostMessage(Handle, WM_FERTIG, 0, 0);
end;

.
.

procedure TFMain.HabeFertig(var Msg: TMessage);
begin
  // dein Funktionscode;
end;
:hi:

hoika 15. Jan 2011 08:07

AW: TForm anzeigen obwohl Terminate bei TForm OnCreate
 
Hallo,

OnActivate musst du nehmen.
Vor deinen eigenen Methoden noch ein Application.ProcessMessages.

Das Programm beendest du dann über PostMessage(Handle, WM_CLOSE, 0, 0);


Heiko

haentschman 15. Jan 2011 08:25

AW: TForm anzeigen obwohl Terminate bei TForm OnCreate
 
Zitat:

OnActivate musst du nehmen.
... na supi. 8-) Dann klick mal auf ein anderes Fenster und wieder zurück. Was meinst du was passiert ?

Uwe Raabe 15. Jan 2011 09:30

AW: TForm anzeigen obwohl Terminate bei TForm OnCreate
 
Ich habe zwar ncoh nicht genau verstanden, was du vorhast, aber du kannst einen Timer auf dein Form legen, diesen auf Enabled schalten und im OnTimer-Ereignis den Timer disablen und deinen Code ausführen.

Luckie 15. Jan 2011 09:59

AW: TForm anzeigen obwohl Terminate bei TForm OnCreate
 
Zitat:

Zitat von haentschman (Beitrag 1074832)
Zitat:

OnActivate musst du nehmen.
... na supi. 8-) Dann klick mal auf ein anderes Fenster und wieder zurück. Was meinst du was passiert ?

Dann setzt man sich einen Flag, ob es schon mal aufgerufen wurde oder nicht.

Richtig, OnShow war falsch. Ich nehme dazu immer OnPaint mit einem Flag.

Sir Rufo 15. Jan 2011 11:05

AW: TForm anzeigen obwohl Terminate bei TForm OnCreate
 
Benutze einfach die Komponente TApplicationEvents und dort das Event OnIdle.

Dort prüfst du ob du schon nach einem Update gesucht hast und startest dann die Update-Prüfung.

Das Event wird zum ersten Mal dann ausgeführt, wenn die Anwendung eben nix zu tun hat, also mit dem ganzen Erstellungsgeraffel am Ende ist und alle Formulare erzeugt und angezeigt wurden.

Noch besser ist es allerdings die Updateprüfung in einen Thread auszulagern, falls es mal wieder länger dauert mit der Prüfung ;)

hoika 15. Jan 2011 11:32

AW: TForm anzeigen obwohl Terminate bei TForm OnCreate
 
Hallo,

Zitat:

na supi. Dann klick mal auf ein anderes Fenster und wieder zurück. Was meinst du was passiert ?
Delphi-Quellcode:
procedure TForm1.Form1Activate;
begin
  OnActivate:= NIL;

// dein Code
end;
Erledigt, nächste Frage. ;)


Heiko

Mike_ 15. Jan 2011 12:53

AW: TForm anzeigen obwohl Terminate bei TForm OnCreate
 
Da sich jeder die Mühe gemacht hat eine Antwort zu schreiben.
Habe der Fairness und des Lerneffektes wegen jede Lösung ausprobiert.
Zitat:

Zitat von hoika (Beitrag 1074829)
Hallo,

OnActivate musst du nehmen.
Vor deinen eigenen Methoden noch ein Application.ProcessMessages.

Das Programm beendest du dann über PostMessage(Handle, WM_CLOSE, 0, 0);

Das ging super einfach.
Im FormActivate Event habe ich nur (Vor dem Code):

OnActivate := NIL;
Application.ProcessMessages;

schreiben müssen.

Super dass es einen solchen Befehl gibt, AutoIt hat auch so etwas, bei Delphi kam ich gar nicht darauf.

Zitat:

Zitat von Sir Rufo (Beitrag 1074852)
Benutze einfach die Komponente TApplicationEvents und dort das Event OnIdle.

Dort prüfst du ob du schon nach einem Update gesucht hast und startest dann die Update-Prüfung.

Das Event wird zum ersten Mal dann ausgeführt, wenn die Anwendung eben nix zu tun hat, also mit dem ganzen Erstellungsgeraffel am Ende ist und alle Formulare erzeugt und angezeigt wurden.

Noch besser ist es allerdings die Updateprüfung in einen Thread auszulagern, falls es mal wieder länger dauert mit der Prüfung ;)

Das klappt richtig klasse und war innerhalb ein paar Sekunden getan !

Reicht es, im OnIdle Event das Programm mit Application.Terminate zu beenden oder bringt PostMessage(Handle, WM_CLOSE, 0, 0) irgendwelche mir unbekannten Vorteile ?

Danke für zahlreichen Antworten in der kurzen Zeit !

Anmerkung:
(Der Updater ist ausgelagert, es ist nicht im "Hauptprogramm" enthalten)

@haentschman
Deine Methode ist quasi das "selbst erstellen eines OnIdle Ereignisses, welches ich mit dem EventManager erstellt habe.
Daher wollte ich, wie sagt man hier im Forum "Das Rad nicht neu erfinden" :)

@Uwe Raabe
Es wird ein Updater gestartet, bevor die "Hauptapplikation" gestartet wird.
Dieser Updater wurde aber nicht angezeigt bzw. nur ohne das TImage welches ich gesetzt hatte, darum ging es hier.
Danke für deine Antwort, allerdings empfinde ich es mit einem Time als "programmiertechnisch suboptimal" (Siehe Methode oben EventHandler).

hoika 15. Jan 2011 15:34

AW: TForm anzeigen obwohl Terminate bei TForm OnCreate
 
Hallo,

im OnActivate klappt als saubere Lösung nur das PostMessage.
Ein halt geht aber immer.



Heiko

Mike_ 16. Jan 2011 16:11

AW: TForm anzeigen obwohl Terminate bei TForm OnCreate
 
Zitat:

Zitat von Sir Rufo (Beitrag 1074852)
Benutze einfach die Komponente TApplicationEvents und dort das Event OnIdle.

Dort prüfst du ob du schon nach einem Update gesucht hast und startest dann die Update-Prüfung.

Das Event wird zum ersten Mal dann ausgeführt, wenn die Anwendung eben nix zu tun hat, also mit dem ganzen Erstellungsgeraffel am Ende ist und alle Formulare erzeugt und angezeigt wurden.

Noch besser ist es allerdings die Updateprüfung in einen Thread auszulagern, falls es mal wieder länger dauert mit der Prüfung ;)

Hier hatte ich das Problem, dass das Programm in einer Endlosschlaufe läuft, obwohl ich vorher eine Variable deklarierte und bei OnIdle sagte er solle nur weiter machen falls diese auf 0 steht.

Hat er wohl erkannt, jedoch blieb er in der Funktion einer Funktion stecken

Beispiel:
OnIdle -> CopyFileX Function -> WriteLogY Function
Nun blieb er mir, wenn ich z.B. eine MsgBox ind er WriteLogY Funktion reinpacke immer darin stecken und wiederholte sie von oben bis unten.

Es funktionierte tadellos ohne diese MsgBox, aber ist nicht der Sinn der Sache.

Zitat:

Zitat von Uwe Raabe (Beitrag 1074834)
Ich habe zwar ncoh nicht genau verstanden, was du vorhast, aber du kannst einen Timer auf dein Form legen, diesen auf Enabled schalten und im OnTimer-Ereignis den Timer disablen und deinen Code ausführen.

Das war doch die - für mich - beste Lösung und vor allem ohne "Nebenwirkungen".

Durch meine Unerfahrenheit habe ich es im letzten Post noch nicht erkannt, vielen Dank Herr Raabe :thumb:


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:04 Uhr.

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