Mit der CONZEPT 16-Version 5.5.04 wurde das Ereignis EvtCreated eingeführt. Der vorliegende Artikel beleuchtet das Event näher.
Initialisierung vs. Erstellung
Für die Initialisierung eines Oberflächen-Objektes stellt CONZEPT 16 das Ereignis EvtInit zur Verfügung. Warum gibt es also die Notwendigkeit für ein weiteres Ereignis?
WinDialog
Hierzu schauen wir uns an, was bei der Ausführung des WinDialog
-Befehls passiert (Abb.1).
Beim Laden des Dialoges aus der Datenbank – anhand des übergebenen Namens – werden die Eigenschaften und Ereignisse geladen sowie die untergeordneten Objekte. Wenn dieser Vorgang abgeschlossen ist, wird das Ereignis EvtInit des Dialoges aufgerufen. Der Dialog und seine untergeordneten Objekte existieren nun CONZEPT 16-seitig (VSO).
Windows-seitig (in der Grafik grün) ist jedoch noch kein Steuerelement vorhanden, mit dem der Anwender interagieren könnte. Dieses wird erst nach der Durchführung des EvtInit-Ereignisses erstellt.
Ähnlich dem Deskriptor in CONZEPT 16 verwaltet Windows für jedes Fenster ein sogenanntes Window-Handle (HWND). Zu den Fenstern zählen hierbei nicht nur Frame-Objekte, sondern auch Buttons, Eingabefelder, Checkboxen, etc.
Die Fenstererstellung wird durch den Aufruf der Win32-API Funktion CreateWindow erledigt. Nach dessen Rückkehr präsentiert sich der Dialog auf dem Bildschirm des Anwenders und erst jetzt wird das Ereignis EvtCreated des Frame-Objektes durchgeführt.
Objektorientierung
Der beschriebene Ablauf ermöglicht die Modifikation eines Objektes bereits vor dessen Erstellung durch Windows. So können sie beispielsweise die zukünftige Position und Größe des Dialoges auf dem Bildschirm anpassen (wpArea
-Eigenschaft), auch wenn das Steuerelement noch gar nicht vorhanden ist. Die veränderten Werte der Eigenschaft werden später bei der Fenster-Erstellung an Windows übergeben. Genauso verhält es sich auch mit den anderen Eigenschaften (z.B. wpCaption
zum Setzen des Fenster-Titels).
Anwendungsfall
Die CtxDocEdit-Befehle (wie z.B. WinDocLoadName
) funktionieren nicht im Ereignis EvtInit. Das Objekt benötigt zwangsläufig das zugrundeliegende COM-Objekt für die Durchführung der Befehle. Hier bietet sich das Ereignis EvtCreated an, damit ein Dokument unmittelbar nach der Dialog-Erstellung in das CtxDocEdit-Objekt geladen werden kann. Auch die spezifischen COM-Eigenschaften setzen die Fenster-Erstellung voraus. Die CONZEPT 16-Eigenschaften (wie z.B. wpViewMode
) können jedoch bereits früher gesetzt werden. Hier wird die Ausführung der Eigenschaften einfach bis zur Fenster-Erstellung aufgeschoben.
Fazit
Mit dem Ereignis EvtCreated haben Sie die Möglichkeit Code zu einem definierten Zeitpunkt nach der Fenster-Erstellung des Frame-Objektes und all seiner Unterobjekte auszuführen.
6 Antworten
@Fabian
Ja. Frame-Objekte werden nach der Erstellung sichtbar gemacht. Selbst die Option _WinDialogCreateHidden verhindert dies nicht.
Auch dann, wenn ich im EvtInit Visible = False gesetzt habe?
@Fabian
Prinzipiell ja. Nur ist der Frame beim Auslösen des EvtCreated-Ereignisses bereits sichtbar.
Wir haben bisher für Sachen, die nicht im FrameInit gemacht werden konnten, immer im EvtPosChanged-Ereignis ein WinUserEvent() ausgelöst. Im EvtUser-Ereignis haben wir dann schlussendlich das gemacht, was wir effektiv wollten. Damit die Anpassungen nicht sichtbar durchgeführt wurden, haben wir im EvtInit das Fenster auf Visible = False und am Ende vom EvtUser wieder auf Visible = True gesetzt.
Ich gehe davon aus, dass genau solche Geschichten nun über das EvtCreated viel einfacher gelöst werden können?
@Th.Eichele
Genau. Das EvtCreated soll kein Ersatz für das EvtInit-Ereignis sein. Generell gilt auch für die Initialisierung im EvtInit-Ereignis: nur die wirklich notwendigen Dinge durchführen. Denn hier kommt noch zum tragen, dass das EvtInit auch bei untergeordneten Objekten des Frame aufgerufen wird, sofern dort eingetragen.
zur Laufzeit-Optimierung sollte man aber wohl nur das in EvtCreated machen, was in EvtInit nicht möglich ist ?