AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Das Problem mit MouseOver-Effekt

Ein Thema von Popov · begonnen am 23. Jan 2013 · letzter Beitrag vom 30. Jan 2013
Antwort Antwort
Popov
(Gast)

n/a Beiträge
 
#1

Das Problem mit MouseOver-Effekt

  Alt 23. Jan 2013, 15:01
Ich entwickle nur selten Komponenten. Vielleicht ist das Problem also überhaupt nicht der Rede wert und allgemein bekannt, nur ich komme nicht drauf.

Es ist das Problem mit MouseOver-Effekt. Es klappt nicht so wie ich es mir denke. Ich habe hier drei Methoden. Die erste ist die einzig wahre Methode, die funktioniert aber nicht so richtig. Zumindest nicht wie ich es brauche. Die anderen zwei sind getrickst, aber funktionieren.

Eines vorweg, es geht hier nicht um Panel, es ist nur für das Beispiel, mir geht es allgemein um andere Komponenten. Also bitte nicht auf Panel versteifen.

Beispiel mit MouseEnter und MoseLave Messages:

Delphi-Quellcode:
  TPanel2 = class(TPanel)
    procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER;
    procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
  end;

implementation

procedure TPanel2.CMMouseEnter(var Message: TMessage);
begin
  Color := clGreen;
end;

procedure TPanel2.CMMouseLeave(var Message: TMessage);
begin
  Color := clRed;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  Panel: TPanel2;
begin
  Panel := TPanel2.Create(Self); //hier wird das Panel zur Laufzeit erzeugt
  Panel.Parent := Self;
  Panel.Align := alClient;
end;
Es ist zwar eine auf das notwendigste verkürzte Version, aber das wesentliche ist drinn. Nur funktioniert es nicht so wie ich mir das vorstelle, denn auch wenn auf beide Ereignisse reagiert wird (Mauszeiger rein und raus), es funktioniert nicht, wenn der Mauszeiger zu schnell ist. Bewege ich den Mauszeiger ruckartig aus dem Formular, wird nicht reagiert. Es funktioniert also nur wenn der Mauszeiger beim Verlassen des Panels das Formular berührt. In der Form ist es für mich unbrauchbar, da hier immer klar sein muss wenn dier Mauszeiger draußen ist.

Eine andere Methode die ich mal entwickelt habe ist die mit dem Timer:

Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
begin
  Panel1.Align := alClient;
  Timer1.Interval := 50;
  Timer1.Enabled := False;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var
  P: TPoint;
  R: TRect;
  H: THandle;
begin
  with Panel1 do
  begin
    if Boolean(GetCursorPos(P)) then
    begin
      H := WindowFromPoint(P);
      GetWindowRect(H, R);

      if PtInRect(R, P) and (H = Handle)then
        Color := clRed else
      begin
        Color := clGreen;
        Timer1.Enabled := False;
      end;
    end;
  end;
end;

procedure TForm1.Panel1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  Timer1.Enabled := True;
end;
Funktioniert eigentlich sehr gut, bis auf, dass es nicht elegant ist, und etwas aufwendig.

Zuletzt eine dritte Methode (die bin ich noch am entwickeln):

Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
begin
  Panel1.Align := alClient;
end;

procedure TForm1.Panel1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
var
  R: TRect;
  P: TPoint;
begin
  with Panel1 do
  begin
    GetWindowRect(Handle, R);
    P := ClientToScreen(Point(X, Y));

    if GetCapture = 0 then
      SetCapture(Handle);

    if PtInRect(R, P) and (WindowFromPoint(P) = Handle) then
      Color := clGreen;
    else
    begin
      Color := clRed;
      ReleaseCapture;
    end;
  end;
end;
Funktioniert eigentlich auch sehr gut, bis auf, dass, ich vor Monaten, als ich es entwickelt habe, am Beispiel den Vermerk angebracht habe, dass es u. U. Probleme bereitet (ich kann mich aber nicht erinnern wo und was), und das man dazu ein Handle der Komponente braucht.

So, und nun mein Problem - die beiden letzten Beispiele sind getrickst, funktionieren aber wie ich es brauche. Es wird auch dann erkannt, dass der Zeiger sich außerhalb der Komponente befindet, wenn er außerhalb des Formulars ist. Das erste Beispiel soll wohl das einzig wahre sein, funktioniert aber nicht perfekt. Ich würde also gerne die erste Methode nutzen, aber ich hab keine Ideen wie ich es an meine Bedürfnisse anpassen kann.

Hat irgendwer Ideen?
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.336 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: Das Problem mit MouseOver-Effekt

  Alt 23. Jan 2013, 16:20
Ich denke, besser wirst Du es nicht lösen können.
Evtl. könnte man auf Mausereignisse im Application-Objekt reagieren und dann die Mauspostion prüfen. Aber das käme letztlich auf´s gleiche raus.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Benutzerbild von Olli73
Olli73

Registriert seit: 25. Apr 2008
Ort: Neunkirchen
662 Beiträge
 
#3

AW: Das Problem mit MouseOver-Effekt

  Alt 23. Jan 2013, 16:25
es funktioniert nicht, wenn der Mauszeiger zu schnell ist. Bewege ich den Mauszeiger ruckartig aus dem Formular, wird nicht reagiert. Es funktioniert also nur wenn der Mauszeiger beim Verlassen des Panels das Formular berührt.
Ich habe das mal unter W8 und XE3 getestet und keine Probleme festgestellt. Vielleicht bin ich aber auch nur zu langsam?

Hatte allerdings ein anderes Problem: Die Farbe des Panels kann ich nicht setzen; habe dafür dann halt die Caption geändert.
  Mit Zitat antworten Zitat
RSE

Registriert seit: 26. Mär 2010
254 Beiträge
 
Delphi XE Enterprise
 
#4

AW: Das Problem mit MouseOver-Effekt

  Alt 30. Jan 2013, 12:08
Ungetestete Idee: Was passiert, wenn du in der ersten Methode noch OnMouseLeave des Formulars mit einbeziehst? Das ist zwar für die Komponente evtl. nur schwerlich umsetzbar, wäre aber testweise sicherlich interessant.
"Seit er seinen neuen Computer hat, löst er alle seine Probleme, die er vorher nicht hatte."
  Mit Zitat antworten Zitat
CCRDude

Registriert seit: 9. Jun 2011
675 Beiträge
 
FreePascal / Lazarus
 
#5

AW: Das Problem mit MouseOver-Effekt

  Alt 30. Jan 2013, 12:47
Die Probleme mit ersterer Methode kann ich bestätigen, "massiver" werden die, wenn man andere Kompontenten abhängig von der Maus sichtbar/unsichtbar schaltet oder in der Größe verändert.

Ich weiß allerdings nicht, warum die das einzig wahre sein soll, oder warum nur eine einzige Methode "die" wahre Methode sein soll

Anstelle des Timers habe ich schonmal das OnIdle der Application verwendet, und halt die Events des Formulares. Also halte ich Varianten 2 und 3 prinzipiell auch nicht für total verkehrt.

Übrigens: anstelle der Zuweisung (hier an Color) würde ich den aktuellen Status erst überprüfen, das vermeidet ggfls. überflüssiges Neugezeichne.
  Mit Zitat antworten Zitat
Antwort Antwort


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 12:56 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