Einzelnen Beitrag anzeigen

Popov
(Gast)

n/a Beiträge
 
#1

Das Problem mit MouseOver-Effekt

  Alt 23. Jan 2013, 16: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