Discussion:
Form Z-Order
(zu alt für eine Antwort)
Hans-Peter Diettrich
2014-06-21 09:12:44 UTC
Permalink
Bei meinem ersten ernsthaften Projekt mit XE bin ich über ein seltsames
Verhalten von mehreren Formularen gestolpert. Die Aufgabe ist eigentlich
ganz einfach, und völlig unproblematisch z.B. mit D7:

Das Hauptfenster zeigt ein Diagramm (oder was auch immer) an, und ein
Button (Menü...) erlaubt die Anzeige eines nicht-modalen
Konfigurationsfensters. Beide Fenster werden automatisch erzeugt, falls
das von Belang ist. Nun soll es dem Benutzer möglich sein, zwischen
beiden Fenstern zu wechseln, d.h. eines von beiden in den Vordergrund zu
holen.

Bei XE wird das zweite Fenster *immer* als Popup über dem Hauptfenster
dargestellt, selbst wenn es nicht aktiv ist, und das auch bei
PopupMode=pmNone, der eigentlich für pre-D8 Kompatibilität sorgen
sollte. Die Hilfe hierzu ist etwas schwammig, gilt Popupmode etwa nur
zur Designzeit, in der IDE?

Weiß jeman, welche Klimmzüge tatsächlich notwendig sind, um die beiden
Fenster einfach unabhängig voneinander in den Vordergrund holen zu können?

DoDi
Peter
2014-06-21 10:09:55 UTC
Permalink
Post by Hans-Peter Diettrich
Bei meinem ersten ernsthaften Projekt mit XE bin ich über ein
seltsames Verhalten von mehreren Formularen gestolpert. Die Aufgabe
Das Hauptfenster zeigt ein Diagramm (oder was auch immer) an, und ein
Button (Menü...) erlaubt die Anzeige eines nicht-modalen
Konfigurationsfensters. Beide Fenster werden automatisch erzeugt,
falls das von Belang ist. Nun soll es dem Benutzer möglich sein,
zwischen beiden Fenstern zu wechseln, d.h. eines von beiden in den
Vordergrund zu holen.
Bei XE wird das zweite Fenster immer als Popup über dem Hauptfenster
dargestellt, selbst wenn es nicht aktiv ist, und das auch bei
PopupMode=pmNone, der eigentlich für pre-D8 Kompatibilität sorgen
sollte. Die Hilfe hierzu ist etwas schwammig, gilt Popupmode etwa nur
zur Designzeit, in der IDE?
Nein, Popupmode ist nur für *modale* Fenster von Bedeutung.

Setz im DPR file Application.MainformOntaskbar := false (der Default
ist true seit diese Eigenschaft eingeführt wurde).

In D7 war das Application-Window (nicht sichtbar) der API-Parent für
alle Forms, d. h. sie waren alle "Geschwister" in der
Fenster-Hierarchie. Das Taskbar-Button der Anwendung gehörte dem
Application-Window.
Der API-Parent bestimmt die Z-Ordnung der Fenster und Windows sorgt
dafür, dass ein Fenster immer über seinem API-Parent in der Z-Ordnung
liegt.

Seit D2009 ist das Mainform standardmäßig der API-Parent für alle
anderen Forms und der Taskbar-Button gehört zum Mainform. Das war
notwendig, um Anzeigeprobleme auf dem Vista Aero-Desktop zu vermeiden.
Damit liegen aber auch alle anderen Fenster in der Z-Ordnung über dem
Mainform.
Application.MainformOntaskbar := false geht zum Verhalten von D7
zurück, mit den damit verbundenen Problemen auf dem Aero-Desktop
(betrifft wohl diese Mini-Fensteransicht, die man kriegt, wenn die Maus
über einem Taskbar-Button schwebt).

Es gibt eine Alternative: wenn man ein spezielles Form aus dieser
Z-Ordung lösen will kann man seine CreateParams-Methode überschreiben.

inherited;
params.WndParent := 0;

Damit bekommt man ein Fenster ohne API-Parent, das also in der
Z-Ordnung von den anderen Fenstern der Anwendung losgelöst ist. Wenn
man statt 0 Application.Handle verwendet sollte das Fenster auf der
gleichen Ebene der Fensterhierarchie landen wie das Mainform. In beiden
Fällen kann es sinnvoll sein, dem Fenster einen eigenen Taskbar-Button
zu verschaffen. Dazu kommt folgende Zeile in die überschriebene
CreateParams-Methode:

params.ExStyle := params.ExStyle or WS_EX_APPWINDOW;
--
Peter Below
Hans-Peter Diettrich
2014-06-21 11:04:29 UTC
Permalink
Post by Peter
Post by Hans-Peter Diettrich
Bei XE wird das zweite Fenster immer als Popup über dem Hauptfenster
dargestellt, selbst wenn es nicht aktiv ist, und das auch bei
PopupMode=pmNone, der eigentlich für pre-D8 Kompatibilität sorgen
sollte. Die Hilfe hierzu ist etwas schwammig, gilt Popupmode etwa nur
zur Designzeit, in der IDE?
Nein, Popupmode ist nur für *modale* Fenster von Bedeutung.
Ach, jetzt dämmert mir wieder die Bedeutung von WS_POPUP. Da muß man
erst mal draufkommen, daß die TForm Fenster *nicht* WS_OVERLAPPED sind,
wie das vom früheren Verhalten her eigentlich zu erwarten war.
Post by Peter
Setz im DPR file Application.MainformOntaskbar := false (der Default
ist true seit diese Eigenschaft eingeführt wurde).
Danke, das wars! :-)
Post by Peter
Der API-Parent bestimmt die Z-Ordnung der Fenster und Windows sorgt
dafür, dass ein Fenster immer über seinem API-Parent in der Z-Ordnung
liegt.
Soweit klar, aber wie stellt man den API-Parent ein, falls man mal eine
bestimmte Ordnung braucht? Gilt PopupParent auch für nichtmodale Fenster?

Ach je, da gibt es so viele Unklarheiten, also ziehe ich alle Fragen
zurück - sooo genau wollte ich das dann auch wieder nicht wissen :-(
[Die Hilfe könnte aber wirklich besser sein - oder steckt da Absicht
dahinter, AKA Support-Verträge? :-]
Post by Peter
Es gibt eine Alternative: wenn man ein spezielles Form aus dieser
Z-Ordung lösen will kann man seine CreateParams-Methode überschreiben.
inherited;
params.WndParent := 0;
Dafür hätte ich jetzt WS_OVERLAPPED genommen, aber das könnte heutzutage
nicht mehr funktionieren, wenn ich mir Deine Erklärungen so anschaue.
Win 3.x war da ja noch um Größenordnungen übersichtlicher ;-)

DoDi
Peter
2014-06-21 12:15:42 UTC
Permalink
Post by Hans-Peter Diettrich
Soweit klar, aber wie stellt man den API-Parent ein, falls man mal
eine bestimmte Ordnung braucht? Gilt PopupParent auch für nichtmodale
Fenster?
Ja.
--
Peter Below
Lesen Sie weiter auf narkive:
Loading...