AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein GUI-Design mit VCL / FireMonkey / Common Controls Delphi Ermitteln woher ein Control den Fokus erhalten hat
Thema durchsuchen
Ansicht
Themen-Optionen

Ermitteln woher ein Control den Fokus erhalten hat

Ein Thema von H4ndy · begonnen am 29. Apr 2010 · letzter Beitrag vom 1. Mai 2010
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von H4ndy
H4ndy

Registriert seit: 28. Jun 2003
Ort: Chemnitz
515 Beiträge
 
Delphi XE3 Professional
 
#1

Ermitteln woher ein Control den Fokus erhalten hat

  Alt 29. Apr 2010, 20:23
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 (www.keepass.info) beim Auto-Ausfuellen das letzte Fenster wieder in den Vordergrund holt und dort dann Logindaten eintraegt.

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
Manuel
  Mit Zitat antworten Zitat
David Martens

Registriert seit: 29. Sep 2003
205 Beiträge
 
Delphi XE Enterprise
 
#2

Re: Ermitteln woher ein Control den Fokus erhalten hat

  Alt 29. Apr 2010, 20:47
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
  Mit Zitat antworten Zitat
Benutzerbild von H4ndy
H4ndy

Registriert seit: 28. Jun 2003
Ort: Chemnitz
515 Beiträge
 
Delphi XE3 Professional
 
#3

Re: Ermitteln woher ein Control den Fokus erhalten hat

  Alt 29. Apr 2010, 21:06
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 von David Martens:
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.
Richtig, aber ich brauche zusaetzlich noch die Info, ob das Popup jetzt geschlossen wurde, weil ich nochmal auf die Statusbar geklickt habe oder einfach irgendwo ins Formular.

Ich hoffe ich hab jetzt nix verdreht im Kopf
Manuel
  Mit Zitat antworten Zitat
Tryer

Registriert seit: 16. Aug 2003
200 Beiträge
 
#4

Re: Ermitteln woher ein Control den Fokus erhalten hat

  Alt 29. Apr 2010, 22:49
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:
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;
Grüsse, Dirk
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#5

Re: Ermitteln woher ein Control den Fokus erhalten hat

  Alt 30. Apr 2010, 07:12
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;
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
Tryer

Registriert seit: 16. Aug 2003
200 Beiträge
 
#6

Re: Ermitteln woher ein Control den Fokus erhalten hat

  Alt 30. Apr 2010, 08:08
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
  Mit Zitat antworten Zitat
idefix2

Registriert seit: 17. Mär 2010
Ort: Wien
1.027 Beiträge
 
RAD-Studio 2009 Pro
 
#7

Re: Ermitteln woher ein Control den Fokus erhalten hat

  Alt 30. Apr 2010, 08:21
Zitat:
// Problem: Haben die Controls schon ein OnEnter / OnClick, wird das hier überschrieben.
Das Problem lässt sich durch den Einsatz einer ClassHelper Klasse für TWinControl vermeiden. Dort kann das Original-Onenter und onclick Ereignis überschrieben, aber der Einstiegspunkt, falls er existiert, gemerkt und in dem überschriebenen Ereignis anschliessend aufgerufen werden.
  Mit Zitat antworten Zitat
Benutzerbild von H4ndy
H4ndy

Registriert seit: 28. Jun 2003
Ort: Chemnitz
515 Beiträge
 
Delphi XE3 Professional
 
#8

Re: Ermitteln woher ein Control den Fokus erhalten hat

  Alt 30. Apr 2010, 14:25
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!


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;
Manuel
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#9

Re: Ermitteln woher ein Control den Fokus erhalten hat

  Alt 30. Apr 2010, 15:35
Zitat von idefix2:
Zitat:
// Problem: Haben die Controls schon ein OnEnter / OnClick, wird das hier überschrieben.
Das Problem lässt sich durch den Einsatz einer ClassHelper Klasse für TWinControl vermeiden. Dort kann das Original-Onenter und onclick Ereignis überschrieben, aber der Einstiegspunkt, falls er existiert, gemerkt und in dem überschriebenen Ereignis anschliessend aufgerufen werden.
Genau. Das wollte ich aber dem Fragesteller überlassen.
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
Hawkeye219

Registriert seit: 18. Feb 2006
Ort: Stolberg
2.227 Beiträge
 
Delphi 2010 Professional
 
#10

Re: Ermitteln woher ein Control den Fokus erhalten hat

  Alt 30. Apr 2010, 16:46
Hallo,

hier ist noch ein Vorschlag:

Delphi-Quellcode:
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;
Gruß Hawkeye
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:53 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz