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?