Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   OnMouseEnter bzw. -Leave-Events realisieren (https://www.delphipraxis.net/172054-onmouseenter-bzw-leave-events-realisieren.html)

sintronic86 11. Dez 2012 13:46

OnMouseEnter bzw. -Leave-Events realisieren
 
Hallo Community,

ich bins mal wieder.
Derzeit programmiere ich für mich privat ein kleines Tool.
Ich habe mir in einer Extra-Unit eine eigene Klasse von TToolBar abgeleitet und darauf liegen diverse andere Objekte wie TLabel, TPanel usw.
Jetzt habe ich ein kleines Problem. Unter anderem Liegt auf dieser Komponente ein Panel, welches bei OnMouseEnter größer und bei OnMouseLeave kleiner werden soll. Soweit ist es klar und funktioniert auch einwandfrei, vorallem durch die Funktion AnimationFloat() sieht es super aus.
Allerdings funktioniert das natürlich nicht mehr, wenn auf eben diesem Panel beispielsweise ein TEdit liegt. Denn wenn ich mit der Maus darüber fahre, tritt ja das OnMouseLeave-Event in Kraft, da die Maus sich nun über dem Edit befindet. Genau das soll aber nicht passieren.

Ich hoffe ihr versteht was ich meine und könnt mir einen kleinen Tipp geben.

P.S.: Mein erster Gedanke war, den auf dem Panel liegenden Objecten einfach dieselben Events zuzuweisen, aber dann treten die Events zu oft in Kraft.

DeddyH 11. Dez 2012 14:05

AW: OnMouseEnter bzw. -Leave-Events realisieren
 
Nur so ein Gedanke: im OnMouseLeave das Control unter dem Mauszeiger ermitteln und (ggf. rekursiv) dessen Parent untersuchen. Ist das irgendwann das Panel selbst, dann ignorieren.

Zacherl 11. Dez 2012 14:16

AW: OnMouseEnter bzw. -Leave-Events realisieren
 
Zitat:

Zitat von DeddyH (Beitrag 1195058)
Nur so ein Gedanke: im OnMouseLeave das Control unter dem Mauszeiger ermitteln und (ggf. rekursiv) dessen Parent untersuchen. Ist das irgendwann das Panel selbst, dann ignorieren.

Dazu noch ne Boolean Hilfsvariable, damit man auch OnMouseEnter ignorieren kann, wenn von einem Child Control wieder zurück aufs Panel gesprungen wird.

stahli 11. Dez 2012 16:13

AW: OnMouseEnter bzw. -Leave-Events realisieren
 
In der VCL habe ich das mal so gelöst:

Delphi-Quellcode:
procedure TodPanelCourt.CMMouseEnter(var Message: TMessage);
begin
  inherited;
  if not odExist(odCourt) then
    Exit;
  if not odPanelGame.Visible then
    Exit;
  BitBtnCancel.Visible := True;
  BitBtnCancel.Left := Width - BitBtnCancel.Width;
  BitBtnCancel.Top := 0;
end;

procedure TodPanelCourt.CMMouseLeave(var Message: TMessage);
var
  pt: TPoint;
  H: hwnd;
begin
  inherited;
  if not odExist(odCourt) then
    Exit;
  GetCursorPos(pt);
  H := WindowFromPoint(pt);
  if (H = Handle) or (H = BitBtnCancel.Handle) then
    Exit;
  BitBtnCancel.Visible := False;
end;
Funktioniert meistens ganz gut, aber nicht 100%ig.

Ansonsten könnte man sich mit einem Timer behelfen, der nach einer Verzögerung prüft, ob die Aktion noch relevant ist.
Die mögliche Startverzögerung der Animation wird da sicher nicht helfen, die die vermutlich nicht mehr abzubrechen ist - oder?

sintronic86 12. Dez 2012 07:33

AW: OnMouseEnter bzw. -Leave-Events realisieren
 
@DeddyH: Die Idee finde ich gut, aber ich bekomme die rekursive Abfrage nicht gebacken. :(

DeddyH 12. Dez 2012 07:59

AW: OnMouseEnter bzw. -Leave-Events realisieren
 
Du ermittelst den Parent des Controls. Ist das Dein Panel oder ein Formular, weißt Du ja schon Bescheid, ansonsten ermittelst Du den Parent des Parents und vergleichst wieder, und zwar solange, bis er nil, ein Formular oder eben Dein Panel ist.

Zacherl 12. Dez 2012 10:50

AW: OnMouseEnter bzw. -Leave-Events realisieren
 
Ganz anderer Ansatz:

Delphi-Quellcode:
var
  IsInside: Boolean;

procedure TForm2.Panel1MouseEnter(Sender: TObject);
begin
  if not IsInside then
  begin
    IsInside := true;
    // TODO:
  end;
end;

procedure TForm2.Panel1MouseLeave(Sender: TObject);
var
  P: TPoint;
begin
  GetCursorPos(P);
  Panel1.ScreenToClient(P);
  if not PtInRect(Panel1.ClientRect, P) then
  begin
    IsInside := false;
    // TODO:
  end;
end;

DeddyH 12. Dez 2012 11:02

AW: OnMouseEnter bzw. -Leave-Events realisieren
 
Oder etwas kürzer (ungetestet):
Delphi-Quellcode:
var
  IsInside: Boolean;

procedure TForm2.Panel1MouseEnter(Sender: TObject);
begin
  IsInside := true;
end;

procedure TForm2.Panel1MouseLeave(Sender: TObject);
begin
  IsInside := PtInRect(TPanel(Sender).ClientRect,
    TPanel(Sender).ScreenToClient(Mouse.CursorPos));
end;

sintronic86 12. Dez 2012 15:10

AW: OnMouseEnter bzw. -Leave-Events realisieren
 
@Zacherl & @DeddyH: Die Idee finde ich gut! Leider finde ich das ClientRect nicht wirklich. Jedenfalls wenn ich über "Refactur" -> "Unit suchen" gehe, zeigt er mir zwar eine Unit an, und implementiert diese auch, aber das TPanel (bzw. in meinem Fall die TToolBar) hat derartiges nicht. :(

Lediglich ClipRect gibt es, aber das enthält merkwürdige Werte: Left & Top = 0... Was doch ja nicht Sinn der Sache ist.

DeddyH 12. Dez 2012 15:13

AW: OnMouseEnter bzw. -Leave-Events realisieren
 
ClientRect gibt es ab TControl. Oder ist das am Ende eine Firemonkey-Anwendung? Da könnte es natürlich sein, dass es eine solche Property nicht gibt, das kann ich aber mangels Firemonkey nicht sagen.

sintronic86 12. Dez 2012 15:16

AW: OnMouseEnter bzw. -Leave-Events realisieren
 
Entschuldigt, ja es ist eine Firemonkey-Anwendung. :( :( :(

stahli 12. Dez 2012 15:24

AW: OnMouseEnter bzw. -Leave-Events realisieren
 
OT zu FireMonkey:

Ich hatte das schon wegen dem "AnimationFloat" vorausgesetzt.
Es wäre aber wohl doch nochmal sinnvoll, bei Daniel ein eigenes Unterforum für FM anzuregen (dessen Threads sich evtl. sogar farblich von VCL-Threads unterscheiden).
Sonst sind solche Missverständnisse ja vorprogrammiert...

sintronic86 12. Dez 2012 15:36

AW: OnMouseEnter bzw. -Leave-Events realisieren
 
Ja, da hast du wohl Recht. Tut mir Leid, dass ich das nicht gleich von Anfang an gesagt hab.

Ich hab mich jetzt mit dem Ermitteln des Controls unter dem Mauszeiger versucht. Das OnEnter-Event funktioniert auch, aber irgendwie hab ich nen Knoten im Gehirn, was das OnLeave-Event angeht... :(

sintronic86 12. Dez 2012 15:59

AW: OnMouseEnter bzw. -Leave-Events realisieren
 
Ok, ich hatte einen absoluten Denkfehler drin. Ich dachte, ich müsste für das OnLeave-Event auch eine Methode schreiben, aber es genügt ja, im OnEnter mit der Methode rekursiv zu prüfen und bei negativem Ergebnis, das gewünschte Panel wieder kleiner zu machen. Ohhhhhh man.... :wall:

Allerdings scheint es Schwierigkeiten zu geben, wenn ich mit der Maus zu schnell über mehrere dieser Panels fahre.... Das hat aber wohl mit der Animation selbst zu tun, wenn ich das Panel verlasse, bevor die Animation zum Größermachen beendet wurde, dann wird es nicht mehr kleiner

Sir Rufo 12. Dez 2012 16:27

AW: OnMouseEnter bzw. -Leave-Events realisieren
 
Da die Mouse Events nicht immer zuverlässig feuern hilft eigentlich nur das Pollen über einen Idle-Event.

Beispiel:
http://delphi.about.com/od/delphitip...-the-mouse.htm

sintronic86 13. Dez 2012 07:28

AW: OnMouseEnter bzw. -Leave-Events realisieren
 
@Sir Rufo: wie implementiere ich die procedure TForm3.ApplicationEvents1Idle(Sender: TObject; var Done: Boolean); ???

Bummi 13. Dez 2012 07:53

AW: OnMouseEnter bzw. -Leave-Events realisieren
 
entweder
Delphi-Quellcode:
procedure TForm6.FormCreate(Sender: TObject);
begin
  Application.OnIdle := OnIdle;
end;

procedure TForm6.OnIdle(Sender: TObject; var Done: Boolean);
begin
  // Dein Code
end;
Oder eine Komponente ApplicationEvents auf das Form legen und OnIdle versorgen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:18 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