![]() |
Ermitteln woher ein Control den Fokus erhalten hat
Hallo,
Ich habe im Moment eine ziemliche Kopfnuss zu knacken, welche mit einer Art Popup-Fenster zusammenhaengt. Das Popup soll sich immer schliessen, sobald es den Fokus verliert - soweit kein Problem. Ich habe eine Statusbar, drueckt man diese, dann geht das Popup auf. Druecke ich diese erneut, schliesst sich das Popup und geht wieder auf. Nicht verwunderlich, aber genau das will ich verhindern. Wenn man auf die Statusbar klickt, waehrend man sozusagen noch im Popup ist, bzw. dieses liest, dann soll es bei diesem Klick einfach zu gehen. Hier ist jetzt aber das Problem - das OnDeactivate und OnClose the Popups kommt immer vorm OnClick der Statusbar. Die einzige Loesung, die mir im Moment einfaellt, ist, irgendwie herauszufinden, welches Fenster zuletzt den Fokus hatte, allerdings hab ich keine Ahnung, wie ich das anstellen kann. Und genau das ist meine Frage: Jemand Ahnung ob, und wenn ja, wie man das ermitteln kann? Ich glaub jedenfalls das es geht, da z.B. KeePass ( ![]() Wenn ich diese Info habe, kann ich einfach die erneute Anzeige unterbinden... PS: Nicht ueber die nicht vorhandenen Umlaute wundern, aber ich sitze gerade in den USA an einem Notebook mit US-Tastatur ;) |
Re: Ermitteln woher ein Control den Fokus erhalten hat
Also ich würde das mit zwei boolean Variablen machen. z.B.: bPopupShows, bStatusbarPressed
- initial beide false - beim Click auf die Stausbar: bStatusbarPressed := true wenn bPopupShows = false und bStatusbarPressed = false sonst bStatusbarPressed := false - beim Click auf die Stausbar: bPopupShows := false wenn bPopupShows = true - beim OnShow des Popup: bPopupShows := true Ich hoffe ich hab jetzt nichts durcheinander gebracht. Eigentlich musst du dir nur über die Events hinaus merken was gedrückt wurde und was angezeigt worden ist. Das geht am einfachsten mit eigenen Variablen im Objekt. Gruß David |
Re: Ermitteln woher ein Control den Fokus erhalten hat
Hallo,
Die Idee ist gut, aber beruecksichtig nicht, dass das Popup jederzeit "von jedem Conrol" geschlossen werden kann. Mit deiner Loesung muesste ich zweimal auf die Statusbar klicken, um das Popup wieder anzuzeigen, auch wenn das Popup z.B. durch einen Klick ins Formular geschlossen wurde. Zitat:
Ich hoffe ich hab jetzt nix verdreht im Kopf :shock: |
Re: Ermitteln woher ein Control den Fokus erhalten hat
Das Problem ist auseinanderzuhalten ob Popup.Deactivate und StatusBar.Click "direkt" aufeinander folgen, ansonsten wäre es ja legitim das dein Popupfenster erst verschwindet um dann beim Click wieder zu erscheinen.
Delphi-Quellcode:
Grüsse, Dirk
type
TMainForm = class(TForm) .. private ShowPopupOnClick: Boolean; .. ... procedure TMainForm.StatusBarMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin //Würde sehr kurz nach Popup.Deactivate aufgerufen //wenn die Zeitspanne größer ist wird das Popup angezeigt ShowPopupOnClick := Abs(GetTickCount - Popup.TimeStampHide) > 20; end; procedure TMainForm.StatusbarClick(Sender: TObject); begin if ShowPopupOnClick then Popup.Show; end; //############################################################## type TPopup = class(TForm) .. public TimeStampHide: Integer; .. procedure TPopup.FormDeactivate(Sender: TObject); begin TimeStampHide := GetTickCount; Hide; end; |
Re: Ermitteln woher ein Control den Fokus erhalten hat
Verpasse jedem Control ein OnEnter-Ereignis, bei dem Du dir den Sender in einem privaten Feld merkst. Das ist nämlich das Control, das den Focus gerade erhalten hat.
Im OnClick prüfst Du einfach, wer den Focus zuletzt hatte und reagierst dann entsprechend:
Delphi-Quellcode:
Type
TPublicEventsWinControl = Class (TWinControl) Public property OnEnter; Property OnClick; End; procedure TForm1.FormCreate(Sender: TObject); Var i : integer; Begin For i:=0 to ComponentCount - 1 do If Components[i] is TWinControl Then Begin // Problem: Haben die Controls schon ein OnEnter / OnClick, wird das hier überschrieben. TPublicEventsWinControl(Components[i]).OnEnter := RememberFocus; TPublicEventsWinControl(Components[i]).OnClick := AllControlsOnClick; End; End; Procedure TForm11.AllControlsOnClick (Sender : TObject); Begin If fLastControl = MyStatusbar Then ThePopup.visible := Not ThePopup.Visible else ThePopup.Visible := False; End; Procedure TForm1.RememberFocus (Sender : TObject); Begin fLastControl := Sender as TWinControl; End; |
Re: Ermitteln woher ein Control den Fokus erhalten hat
OnClick von allen Controls zu überschreiben würde ich durchaus als Problem sehen..
Das On/Enter/OnClick der Form müsste auch noch überschrieben werden. Mangels Delphi kann ich gerade nur raten das dann beim Focuswechsel erst Form.OnEnter und danach Statusbar.OnEnter ausgelöst wird - dann hätte man dann wieder die "Doppeltriggerung". Vielleicht eher in der Art "Form.OnActivate: Wenn Maus über Statusbar und Maustaste gedrückt dann Veränderung bei OnClick bis zum nächsten MouseDown sperren (Hide passiert über Popup.Deactivate)" Mir gefällt die GetTickCount - Lösung auch nicht wirklich ;) Grüsse, Dirk |
Re: Ermitteln woher ein Control den Fokus erhalten hat
Zitat:
|
Re: Ermitteln woher ein Control den Fokus erhalten hat
Danke!
Ich hab es jetzt ueber den "Timer" im OnClose ueber eine Klassenvariable geloest, das erschien mir der Situation am angemessensten. Das Formular mit der Statusbar ist schon ziemlich "Resourcenintensiv", von daher finde ich das globale "Erweitern" aller OnActivates, etc. als zu kritisch bzw. unnoetig, zumal da wirklich viele Komponenten drauf sind. Noch mal vielen Danke fuer die qualitativen Beitraege! :dp: Und weil Teilen freude macht (D2010, k.A. ab welcher Version das noch funktioniert):
Delphi-Quellcode:
TPopup = class(TForm)
public class var LastVisibleTime: Cardinal; private class constructor Create; // initializes the LastVisibleTime class var procedure FormClose(Sender: TObject; var Action: TCloseAction); end; class constructor TPopup.Create; begin LastVisibleTime := 0; end; procedure TPopup.FormClose(Sender: TObject; var Action: TCloseAction); begin LastVisibleTime := GetTickCount; end; {Anderes Form} procedure TIrgendeinForm.StatusBarClick(Sender: TObject); begin if (TPopup.LastVisibleTime + 300) < GetTickCount then begin // Show only if there's a small time difference (300ms or more) to the // last OnClose of the Popup. This is to "close" the Popup with // clicking on the Statusbar again. TPopup.Execute(bla bla bla); end; end; |
Re: Ermitteln woher ein Control den Fokus erhalten hat
Zitat:
|
Re: Ermitteln woher ein Control den Fokus erhalten hat
Hallo,
hier ist noch ein Vorschlag:
Delphi-Quellcode:
Gruß Hawkeye
type
TPopupForm = class (TForm) procedure FormDeactivate (Sender: TObject); private const WM_HideWindow = WM_APP + 1; procedure WMHideWindow (var aMsg: TMessage); message WM_HideWindow; end; procedure TPopupForm.FormDeactivate (Sender: TObject); begin PostMessage(Handle, WM_HideWindow, 0, 0); end; procedure TPopupForm.WMHideWindow (var aMsg: TMessage); begin Hide; end; // procedure TMainForm.StatusBarMouseDown (Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin PopupForm.Visible := not PopupForm.Visible; end; |
Re: Ermitteln woher ein Control den Fokus erhalten hat
Du könntest auch man probieren das OnClick Ereignis des Formulars zu nehmen, das sollte bei jedem Click gefeuert werden, auch wenn du eigentlich auf ein Control im Formular clickst.
Gruß David |
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:32 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 by Thomas Breitkreuz