![]() |
Das Problem mit MouseOver-Effekt
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:
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.
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; Eine andere Methode die ich mal entwickelt habe ist die mit dem Timer:
Delphi-Quellcode:
Funktioniert eigentlich sehr gut, bis auf, dass es nicht elegant ist, und etwas aufwendig.
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; Zuletzt eine dritte Methode (die bin ich noch am entwickeln):
Delphi-Quellcode:
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.
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; 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? |
AW: Das Problem mit MouseOver-Effekt
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. |
AW: Das Problem mit MouseOver-Effekt
Zitat:
Hatte allerdings ein anderes Problem: Die Farbe des Panels kann ich nicht setzen; habe dafür dann halt die Caption geändert. |
AW: Das Problem mit MouseOver-Effekt
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.
|
AW: Das Problem mit MouseOver-Effekt
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. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:50 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