Hallo,
vielleicht kann jemand hier helfen.
Wir haben in einem größeren Projekt hartnäckige Probleme.
- zahlreiche Formulare werden dynamisch erzeugt
- einige Formulare sind normal (FormStyle=fsNormal), andere sollen vor den normalen sein
- für diese "Vorne"-Formulare haben wir FormStyle=fsStayOnTop gesetzt
alternativ: CreateParams überschrieben und Params.ExStyle := Params.ExStyle or WS_EX_TOPMOST
Jetzt die Probleme:
- "Vorne"-Formulare geraten sporadisch hinter normale
- "Vorne"-Formulare kommen sporadisch vor Fenster eines ANDEREN aktiven Programms (z.B. Outlook)
- Modale Dialoge erscheinen hinter ihren Vater-Fenstern (Vorne-Formulare)
Das ganze vor allem in Verbindung mit Minimieren/Wiederherstellen bzw. Umschalten zu anderen Programmen.
Nach längerer Untersuchung sieht es so aus, als ob die Methode DoNormalizeTopMosts der TApplication-Klasse nicht sauber funktioniert. Delphi normalisiert nämlich Fenster mit Eigenschaft WS_EX_TOPMOST beim Deaktivieren der Applikation (bzw. beim Aufrufen eines modalen Dialogs), und stellt die Z-Order beim Aktivieren der Applikation (bzw. Ende eines modalen Dialogs) wieder her. Diese zweite Methode ist die RestoreTopMosts, dürfte aber nicht die Problemursache sein.
Wir verwenden Delphi5. Dort steht in der Forms.pas
Delphi-Quellcode:
procedure TApplication.DoNormalizeTopMosts(IncludeMain: Boolean);
...
EnumWindows(@GetTopMostWindows, Longint(@Info));
...
for I := FTopMostList.Count - 1 downto 0 do
SetWindowPos(HWND(FTopMostList[I]), Info.TopWindow, 0, 0, 0, 0,
SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE);
Umstellung auf Delphi2009 brachte keine Verbesserung. Dort gibts in der Forms.pas nur die Änderung "or SWP_NOOWNERZORDER". Diese Änderung von Hand in der Delphi5-Forms.pas nachzuziehen hatte ebenfalls keinen Effekt.
Delphi-Quellcode:
procedure TApplication.DoNormalizeTopMosts(IncludeMain: Boolean);
...
EnumWindows(@GetTopMostWindows, Longint(@Info));
...
for I := FTopMostList.Count - 1 downto 0 do
SetWindowPos(HWND(FTopMostList[I]), Info.TopWindow, 0, 0, 0, 0,
SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE [b]or SWP_NOOWNERZORDER[/b]);
Hat jemand ähnliche Erfahrungen ?
Grüße,
blauweiss
p.s. Wir experimentieren gerade mit einer Alternativlösung in der überschriebenen CreateParams in der Art:
Params.WndParent := MyActiveSubform.Handle
dann gibt es aber Probleme beim Minimize/Restore der Applikation, d.h. die "Vorne"-Formulare bleiben stehen beim Minimize