Thema: Delphi Label unter Mausposition

Einzelnen Beitrag anzeigen

Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#34

Re: Label unter Mausposition

  Alt 13. Sep 2005, 21:50
super.

Zitat:
die arbeitsweise deiner lösung ist mir noch etwas schleierhaft
Für diejenigen die eine Erklärung wollen:

Delphi-Quellcode:
procedure TForm1.MouseMove();
var
  C: TControl;
begin
// 1.)
  C := FindDragTarget(ClientToScreen(Point(X, Y)), False);
// 2.)
  if C <> FCurrentLabel then
  begin
// 3.)
    if (FCurrentLabel is TLabel) and (FCurrentLabel.Owner = Self) then
      TLabel(FCurrentLabel).Font.Color := clBlack;
// 4.)
    FCurrentLabel := C;
// 5.)
    if (FCurrentLabel is TLabel) and (FCurrentLabel.Owner = Self) then
      TLabel(FCurrentLabel).Font.Color := clRed;
  end;
end;
1.) die Mauskoordinaten in fast allen Ereignissen beziehen sich immer auf die Clientkoordinaten des Senders. Im Falle eines TForm's also die Koordinaten relativ zur linken oberen Ecke des Formulars unterhalb der Menubar und rechts neben dem Rand des Formulars.
Diese Koordinaten müssen umgewandelt werden in absolute Korrdinaten relativ zum kompletten Bildschrim, sprich dem Screen. Dies macht man mit Control.ClientToScreen(TPoint). Die Funktion Point(X, Y) wandelt nur zwei X,Y Ordinale in einen TPoint um da .ClientToScreen() dies benötigt.

Nun haben wir die richtigen Koordinaten um global auf dem kompletten Screen mit FindDragTarget() das Control an diesen Koordinaten zu suchen. Die Funktion FindDragTarget() nimmt uns dabei sehr viel Arbeit ab, da sie zb. auch einfache Controls abgeleitet von TGraphicControl finden kann. Das besondere von solchen TGraphicControl Klassen ist es das sie für das Windows-OS quasi nicht existent sind, da sie keinerlei Fensterhandles besitzen.
Desweiteren findet FindDragTarget() auch nur die Controls der eigenen Anwendung, obwohl es durchaus möglich wäre auf ähnliche Weise die Controls fremder Delphi/BCB Anwendungen zu finden.

2.) wir haben nun das Control in C stehen. Und wollen nur auf eine Änderung zum aktuell gefundenen Control reagieren. Indirekt simulieren wir damit das was die Events .OnMouseEnter() und .OnMouseLeave() machen. Aber mit dem Unterschied das dieser Weg allgemeingültig für die komplette Anwendung funktoniert.

3.) da sich das aktuelle Control unter dem Mauszeiger verändert hat, sprich der Anwender hat die Maus bewegt wird als allererstes das letzte Control in seiner Darstellung zurückgesetzt. Dies darf natürlich nur ein TLabel des eigenen Formulares sein. Deshalb fragen wird dies auch ab. Nebenbei bemerkt wird man wenn man die VCL Sourcen rückwärts beginnend bei .OnMouseEnter(), .OnMouseLeave() über die Messages cm_MouseEnter, cm_MouseLeave bis hin zur innersten Routine der VCL zurückverfolgt exakt das Gleiche finden was im obigen Source steht !! Die VCL Sourcen verwalten also intern ebenfalls ein CurrentMouseControl und fragen bei Mausbewegungen ebenfalls über FindDragTarget() das Control ab, bei Änderung setzen sie einfach die Messages cm_MouseLeave/cm_MouseEnter ab, und rufen somit die Events .OnMouseLeave() und .OnMouseEnter() auf. Nichts Neues also

4.) das Control unter dem Mauszeiger wird zum aktuellen Control, wir speichern also den Zeiger im Form als privates Feld zwischen.

5.) das neue Control muß natürlich noch die Darstellung ändern, sprich wenn es ein TLabel auf dem eigenen Form ist soll der Text rot dargestellt werden.

fertig.

Gruß Hagen
  Mit Zitat antworten Zitat