Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - Bearbeitungsreihenfolge bei Programmstart


GuaAck - Mi 13.02.13 00:24
Titel: Bearbeitungsreihenfolge bei Programmstart
Hallo,

ich möchte mein eher allgemeines Problem mit einem aktuelle Beispiel anfragen: Mit einem kleinen Programm pinge ich nach einer festen Liste mein Netzwerk durch und sehe, was lebend ist. Dazu habe ich in Mainform einen Button, der die Ping-Umfrage startet, und ein TMemo, in das ich das Ergebnis jedes Pings zeilenweise schreibe. Mit Klick auf Button sehe ich im TMemo live was passiert, bei nicht vorhandenen IPs verzögert sich die Zeile entsprechend des Ping-Timeouts etwas. Bestens.

Nun zur Frage: Ich möchte, dass der Vorgang schon bei Start des Programms gemacht wird, ich also nicht extra meinen Button anklicken muss. Habe viele Dinge versucht, aber es ist immer so, dass zunächst bei unsichtbarem Form die Ping-Reihe abläuft und dann mit einem Schlag das Form mit dem ausgefüllten Memo erscheint.
"OnShow","Visible", "OnCreate" usw. habe ich probiert. Sicher würde ein Timer funktionieren, aber das wäre doch Pfusch (musste ich leider in der Vergangenheit gelegentlich machen, damit eine Lösung da war).

Hat jemand eine Idee wie man die Aktion starten kann, nachdem (!!) das Form auf dem Bildschirm wirklich sichtbar ist?

Gruß GuaAck


Narses - Mi 13.02.13 00:59

Moin!

Poste dir im FormCreate eine eigene Message, in deren Handler rufst du dann den Button-Handler auf. :idea:

cu
Narses


Gerd Kayser - Mi 13.02.13 02:25

user profile iconGuaAck hat folgendes geschrieben Zum zitierten Posting springen:
Hat jemand eine Idee wie man die Aktion starten kann, nachdem (!!) das Form auf dem Bildschirm wirklich sichtbar ist?

Ich würde den Code im Ereignis OnActivate des Formulars ausführen.

Zwei Punkte sind dabei zu beachten:
1. Beim Wechsel von einer anderen Anwendung zu Deinem Programm wird OnActivate von TApplication ausgelöst, nicht vom jeweiligen Formular.
2. Wird innerhalb Deiner Anwendung von einem anderen Formular auf das Formular mit dem OnActivate-Ereignis gewechselt, wird das Ereignis OnActivate des Formulars ausgelöst.

Punkt 2 ist sicherlich nicht erwünscht. Man kann das aber abfangen. Beispiel:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
var
  Mainform  : TMainform;
  Aktiviert : boolean;

implementation

uses Unit1;

{$R *.dfm}

procedure TMainform.Button1Click(Sender: TObject);
begin
  Form1.Show;
end;

procedure TMainform.FormActivate(Sender: TObject);
begin
  if not Aktiviert then
    ShowMessage('Erstmalige Aktivierung');   // <-----
  Aktiviert := true;
end;

procedure TMainform.FormCreate(Sender: TObject);
begin
  ReportMemoryLeaksOnShutdown := true;
end;

initialization
  Aktiviert := false;

end.


Oder man schreibt die Anwendung so, daß alle anderen Formulare in einer speziellen Komponente des Hauptformulars angezeigt werden, also innerhalb des Hauptformulars integriert sind. Siehe z. B. TLMDFormDisplay der LMD-Tools. Dann wird OnActivate auch nur einmal ausgelöst.


jaenicke - Mi 13.02.13 08:38

Die Lösung von Narses ist da aber deutlich besser, denn bei der muss man nicht tricksen. Zudem ist man dann nicht mehr in einem Eventhandler drin.


colaka - Mi 13.02.13 08:44

Hallo,

mich würde mal interessieren, warum die Lösung mit dem Timer Pfusch ist.


jaenicke - Mi 13.02.13 10:10

Ein Timer basiert intern doch auch nur darauf, dass der Windows-Zeitgeber dir eine Nachricht WM_TIMER schickt. Der Overhead ist aber viel größer, denn du hast ein Timer-Objekt, das sich bei Windows registriert, dort muss geprüft werden, wann die Nachricht rausgeht, bei dir muss die Nachricht verarbeitet und dem richtigen Timer zugestellt werden, ...

Wozu das ganze? Da kannst du dir auch selbst eine Nachricht schicken, da hängt sonst nix dran, zudem bekommst du diese auch auf jeden Fall sobald die Nachrichtenwarteschlange von deinem Programm abgearbeitet wurde. Bei einem Timer ist das zwar meistens so, bei viel Systemlast aber nicht immer, d.h. es kann sein, dass der Timer auch mal erst etwas später losgeht (meistens nur einen Bruchteil einer Sekunde, aber auch eine halbe Sekunde ist für den Benutzer schon deutlich sichtbar).


GuaAck - Mi 13.02.13 16:15

Danke allen,

das mit postmessage (Narses) ist super einfach und geht bestens!

Zu Timer: Mich stört, dass die zeit ja mehr oder weniger willkürlich ist. Wenn die CPU mal viel zu tun hat, dann reicht sie evtl nicht und ansonsten ist sie vielleicht viel zu lang.

Gruß
GuaAck