![]() |
AW: AlwaysOnTop mit mehreren Formularen
Zitat:
Zwischenzeitlich hab ich das zweite Form in eine eigene Anwendung überführt (weil ich für ein anderes Projekt fix eine Lösung brauchte), aber ich bin dennoch an einer Lösung innerhalb einer Anwendung interessiert. Grüße Dalai |
AW: AlwaysOnTop mit mehreren Formularen
siehe #5 ?
[edit] Hab's aber grad nochmal probiert ... ich glaub Delphi bzw. die VCL ist Schuld. Vorhin falsch geguckt, denn so ist es aktuell in Windows 10 + Delphi 10.3: * das zweite Fenster ist immer über dem Ersten * wären Beide gleich (StayOnTop oder nicht), müsste jeweils das Aktive oben sein * vermutlich irgendwas in Richtung PopupMode, aber das steht (standardmäßig) eigentlich auf pmNone :grueble: [edit2]
Delphi-Quellcode:
Keine Ahnung wer auf diese bescheuerte Idee gekommen ist auch bei NONE etwas zu machen.
procedure TCustomForm.CreateParams(var Params: TCreateParams);
... case LPopupMode of pmNone: begin if Application.MainFormOnTaskBar then begin // FCreatingMainForm is True when the MainForm is // being created, Self = Application.MainForm during CM_RECREATEWND. if FCreatingMainForm or (Self = Application.MainForm) then WndParent := 0 else if Assigned(Application.MainForm) and Application.MainForm.HandleAllocated then begin WndParent := Application.MainFormHandle; if WndParent = Application.MainForm.Handle then begin if Application.MainForm.PopupChildren.IndexOf(Self) < 0 then Application.MainForm.PopupChildren.Add(Self); <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< FreeNotification(Application.MainForm); end; end else WndParent := Application.Handle; end else begin WndParent := Application.Handle; SetWindowLong(WndParent, GWL_EXSTYLE, GetWindowLong(WndParent, GWL_EXSTYLE) and not WS_EX_TOOLWINDOW); end; end; pmAuto: begin if FCreatingMainForm then WndParent := 0 // A main form can't be parented to another form else Lösung: Und statt OnActivate, ist sowieso CreateWnd besser. (auch wenn Beides geht)
Delphi-Quellcode:
[Edit3]
type
TForm3 = class(TForm) procedure FormCreate(Sender: TObject); protected procedure CreateWnd; override; end; var Form3: TForm3; implementation {$R *.dfm} procedure TForm3.CreateWnd; begin inherited; SetWindowPos(Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE); end; procedure TForm3.FormCreate(Sender: TObject); begin PopupMode := TPopupMode(9); end; Oder Application.OnGetMainFormHandle benutzen und dort
Delphi-Quellcode:
zurückgeben.
HWND(-1)
|
AW: AlwaysOnTop mit mehreren Formularen
Zitat:
Zitat:
Man kann auch noch mit PopupParent experimentieren. Ist das nicht gesetzt, wird implizit das MainForm verwendet. Das hat aber nur Auswirkungen auf die eigenen Anwendung. |
AW: AlwaysOnTop mit mehreren Formularen
Ja, "normal" war es so, dass bei mehreren TopMost beide vor allen anderen Nicht-TopMost blieb
und bei mehreren TopMost dort jeweils das ganz obe, was man zuletzt angeklickt/fokusiert hat. Wenn man den "neuen" Mist im TCustomForm.CreateParams "repariert", dann ist es auch wieder so. Wenn die Entwickler das Verhalten ändern wollen, dann dürfen sie gern pmAuto als Default festlegen, aber niemals pmNone kaputt machen. |
AW: AlwaysOnTop mit mehreren Formularen
OK, nachdem ich wieder etwas Luft habe, hab mir das jetzt im Detail angeschaut. Leider musste ich an mehreren Stellen drehen, um einige Nebeneffekte zu unterbinden.
Zitat:
Zitat:
Dummerweise hat das zur Folge, dass die Form2 im Beispiel einen eigenen Button in der Taskleiste bekommt. Das kann ich gar nicht brauchen. Nach einigen Versuchen hab ich eine Lösung gefunden, aber ich frag lieber nach, ob das eine saubere Variante ist. Unit1:
Delphi-Quellcode:
Restliche Funktionen der Unit wie gehabt.
procedure TForm1.FormCreate(Sender: TObject);
begin if bShowForm2 then begin Fform2:= TForm2.Create(nil); Fform2.BorderStyle:= bsNone; Fform2.PopupParent:= Self; end; end; Unit2:
Delphi-Quellcode:
---
procedure TForm2.FormCreate(Sender: TObject);
begin Self.PopupMode:= TPopupMode(99); end; Eine andere Variante kam mir gerade aufgrund eines anderen Projektes in den Sinn. Unit1: wie im OP. [EDIT]Der Aufruf von TForm2.Create muss natürlich etwas anders aussehen, aber der Rest bleibt gleich.
Delphi-Quellcode:
[/EDIT]
procedure TForm1.FormCreate(Sender: TObject);
begin if bShowForm2 then begin Fform2:= TForm2.Create(nil, Self.Handle); Fform2.BorderStyle:= bsNone; end; end; Unit2:
Delphi-Quellcode:
Vorteil: Kein Button erscheint für Form2 in der Taskleiste und ein Setzen des PopupMode entfällt, was den Nebeneffekt hat, dass es sogar im Delphi 5 funktioniert ;).
type
TForm2 = class(TForm) procedure FormActivate(Sender: TObject); private FWndParent: HWND; protected procedure CreateParams(var Params: TCreateParams); override; public constructor Create(AOwner: TComponent; AWndParent: HWND); reintroduce; overload; end; implementation constructor TForm2.Create(AOwner: TComponent; AWndParent: HWND); begin Self.FWndParent:= AWndParent; inherited Create(AOwner); end; procedure TForm2.CreateParams(var Params: TCreateParams); begin inherited; Params.WndParent:= Self.FWndParent; end; procedure TForm2.FormActivate(Sender: TObject); begin uGUIHelper.AlwaysOnTop(True, Self.Handle); end; Meinungen zu den beiden Lösungsvarianten? Ist eine besser geeignet als die andere? Und wenn ja, warum? Grüße Dalai |
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:26 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz