![]() |
Delphi-Version: 10.2 Tokyo
Modaler Doppelklick gibt Event an Ursprungsfenster weiter
Hallo alle,
mir ist da was ganz komisches aufgefallen. Ich habe ein Fenster, in dem ein DBGrid ist. Dieses Grid hat ein OnTitleClick-Event, welches eine Umsortierung ausführt und sich merkt, welche Spalte gerade sortiert ist (dazu später). Nun öffne ich einen modalen Dialog, welcher ganz normal mit Showmodal aufgerufen wird. In diesem modalen Fenster ist ein cxGrid mit einer Liste von Datensätzen (eine Art Suchfenster). Das Doppelclick-Event auf einer Zeile schliesst den Dialog mit modalresult:=mrok; Wenn ich nun auf einem bestimmten Datensatz doppelklicke, der genau auf Höhe der Spaltenüberschrift des anderen im Hintergrund liegenden Fensters liegt, wird zusätzlich das OnTitleclick des anderen Fensters aufgerufen, nachdem der modale Dialog geschlossen wurde. Ich habe in den Fenstern keinerlei Windows-Events überschrieben oder ähnliches. Der modale Dialog wird auch für die Application erzeugt, nicht für das Form, von dem es aus aufgerufen wurde, dass heisst eigentlich haben die beiden Fenster gar nichts miteinanders zu tun. Es ist sehr merkwürdig und sehe eine elementare Problematik. Ich hab schon gelesen, dass ein Doppelklick eigentlich aus vier Mouseevents besteht. Aber die müssten dann doch abgearbeitet sein, wenn ich wieder in das Ursprungsfenster zurückkomme. Hab noch kein kleines Beispielprogramm geschrieben, was ich hier posten könnte. Bevor ich mir die Mühe mache, wollte ich fragen, ob es eine Möglichkeit gibt, dem modalen Dialog oder der Applikation oder Windows zu sagen, dass genau dieses Event abgearbeitet ist, so dass im Ursprungsfenster kein OnTitleclick mehr ankommt. Oder eben irgendwie zu verhindern, dass das Event im Ursprungsfenster auch noch aufgerufen wird. Weiß jemand was dazu? |
AW: Modaler Doppelklick gibt Event an Ursprungsfenster weiter
Hallo
Ich verlinke mal einen anderen Beitrag auf stackoverflow. Dort handelt es sich um eine gleiche/ähnliche Problemstelling. ![]() |
AW: Modaler Doppelklick gibt Event an Ursprungsfenster weiter
Der Grund liegt daran, dass ein DoubleClick beim MouseDown erfolgt. Der TitleClick aber beim MouseUp.
Und da erst MouseDown und dann MouseUp, erfolgt erst der Aufruf von DoubleClick, dann das Schließen des Fensters, und dann der MouseUp der dann von der Titel-Zeile behandelt wird. Lösen kann man das durch einen Timer, der das Setzen von ModalResult entsprechend verzögert (100ms sind mehr als ausreichend und nicht spürbar). Hier mal ein Ablauf der relevanten Events die bei einem DblClick passieren
|
AW: Modaler Doppelklick gibt Event an Ursprungsfenster weiter
Wäre das dann nicht schlauer man hätte den DblClick über MouseUp gesteuert?
Hat das einen tieferen Sinn, dass das so festgelegt ist? |
AW: Modaler Doppelklick gibt Event an Ursprungsfenster weiter
Ja, es gibt einen Grund.
Du kannst mit einem Doppel-Klick in einem Text ein ganzes Wort markieren. Klickst du jetzt aber nur MouseDown/MouseUp/MouseDown dann ist das Wort markiert und du kannst noch weitere Wörter durch Bewegen der Maus selektieren bis zum MouseUp. Nennt sich auch Double-Click-And-Drag |
AW: Modaler Doppelklick gibt Event an Ursprungsfenster weiter
Ah, ok. An sowas hab ich gar nicht gedacht.
|
AW: Modaler Doppelklick gibt Event an Ursprungsfenster weiter
Hallo,
das hatte ich beim TAdvStringGrid (TMS) auch. Lösung: Vor dem Erzeugen des modalen Fensters das eigene Fensters disablen Self.Enabled:= False; Dialog->ShowModal Self.Enabled:= True; Hatte zumindestens mir geholfen. |
AW: Modaler Doppelklick gibt Event an Ursprungsfenster weiter
Zitat:
In dem Fall braucht man kein Modales Fenster wenn das Parent bedient werden kann. Denn das ist der einzige sinn und zweck eines Modalen Fensters. PS: [OT] Nebenbei ein Modales Fenster ist unter Delphi ein Nonsens denn es erschließt sich mir nicht welchen sinn es bezwecken soll. Da liegt wohl ein Design technisches Problem vor. Ein Modales Fenster unter VB6 erstellt hat folgende Eigenschaften. ZOrder = -1 (HWND_TOPMOST) Parent Fenster Disabled Delphi. ZOrder = 0 (HWND_TOP) Parent Fenster Enabled. Welcher sinn und zweck steckt also dahinter dann kann ich direkt ein normales Fenster erstellen mit anschließenden SetWindowPos um die Zorder festzulegen. Irgendwie quatsch das Modale Fenster unter Delphi! ![]() Zitat:
Es ist etwas anderes wenn man sich der Rückgabe Parameter einer Modalen Form bedienen möchte um in der Hauptform auf ein Ereignis zu warten. bsp.
Delphi-Quellcode:
if Form.ShowModal = mrCancel then
Ansonsten sehe ich da keine Sinnvolle Verwendung für. [/OT] War Blödsinn habe mich über ein altes Problem ausgelassen was scheinbar gefixt wurde. :duck: Dein Problem ist also das der Wert der Eigenschaft ModalResult zurückgegeben wird.. weil dein Parent Fenster aktiv ist. Und zwar an die Funktion aus der du das Modale Fenster erstellst. Erstelle ein normales Fenster wenn du ModalResult nicht auswerten willst und gut ist. Ein .Show mit angehängter SetWindowPos wäre dann die bessere alternative. gruss |
AW: Modaler Doppelklick gibt Event an Ursprungsfenster weiter
Zitat:
Unter Delphi 10.2 Tokyo wird beim ShowModal für jedes Fenster der Anwendung ![]()
Delphi-Quellcode:
.
bEnable = false
Delphi-Quellcode:
Diesen Wert kann man aber nicht über
// Vcl.Forms.pas 2215
function DoDisableWindow(Window: HWnd; Data: LPARAM): Bool; {$IFNDEF CLR}stdcall;{$ENDIF} var P: TTaskWindowType; begin if (Window <> TaskActiveWindow) and IsWindowVisible(Window) and IsWindowEnabled(Window) then begin {$IF DEFINED(CLR)} P := TTaskWindow.Create; {$ELSE} New(P); {$ENDIF} P.Next := TaskWindowList; P.Window := Window; TaskWindowList := P; EnableWindow(Window, False); end; Result := True; end; ![]() ![]()
Delphi-Quellcode:
steht, ist es für das Betriebssystem aber disabled.
true
Das Problem ist, dass das modale Fenster versteckt wird und das vorherige Fenster aktiviert wird, obwohl in der Message-Queue noch Nachrichten enthalten sind, die vom modalen Fenster verarbeitet werden müssten (MouseUp) und jetzt aber vom falschen Fenster verarbeitet werden.
Delphi-Quellcode:
// VCL.Forms.pas 7352
function TCustomForm.ShowModal: Integer; var WindowList: TTaskWindowList; LSaveFocusState: TFocusState; SaveCursor: TCursor; SaveCount: Integer; ActiveWindow: HWnd; begin // ... schnipp ... Application.ModalStarted; try { RecreateWnd could change the active window } ActiveWindow := GetActiveWindow; // ... schnipp ... WindowList := DisableTaskWindows(0); try Show; try SendMessage(Handle, CM_ACTIVATE, 0, 0); ModalResult := 0; repeat // Message-Loop zum Verarbeiten der Messages Application.HandleMessage; if Application.Terminated then ModalResult := mrCancel else if ModalResult <> 0 then CloseModal; until ModalResult <> 0; Result := ModalResult; SendMessage(Handle, CM_DEACTIVATE, 0, 0); if GetActiveWindow <> Handle then ActiveWindow := 0; finally Hide; end; finally if Screen.CursorCount = SaveCount then Screen.Cursor := SaveCursor else Screen.Cursor := crDefault; EnableTaskWindows(WindowList); if Screen.SaveFocusedList.Count > 0 then begin Screen.FocusedForm := TCustomForm(Screen.SaveFocusedList.First); Screen.SaveFocusedList.Remove(Screen.FocusedForm); end else Screen.FocusedForm := nil; // Hier wird jetzt versucht das alte Fenster wieder zu aktivieren { ActiveWindow might have been destroyed and using it as active window will force Windows to activate another application } if (ActiveWindow <> 0) and not IsWindow(ActiveWindow) then ActiveWindow := FindTopMostWindow(0); if ActiveWindow <> 0 then SetActiveWindow(ActiveWindow); RestoreFocusState(LSaveFocusState); Exclude(FFormState, fsModal); end; finally Application.ModalFinished; end; end; |
AW: Modaler Doppelklick gibt Event an Ursprungsfenster weiter
Vielleicht hilft es auch im Event sowas hier einzubauen, damit werden folge-Befehle für Maus-Input gelöscht.
Delphi-Quellcode:
procedure EmptyMouseQueue;
var Msg: TMsg; begin while PeekMessage(Msg, 0, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE or PM_NOYIELD) do; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:48 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