Delphi-PRAXiS
Seite 4 von 4   « Erste     234   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Label unter Mausposition (https://www.delphipraxis.net/53293-label-unter-mausposition.html)

Sharky 13. Sep 2005 20:36

Re: Label unter Mausposition
 
Zitat:

Zitat von Lilo
... ich müsste dann ja bei allen 30 labeln mouseenter mouseleave jeweils 1 procedure machen...

Hai Lilo,

Faux hat es in einem Posting schon "angedeutet". Du kannst allen Labels die Selbe Methode für das MouseEnter bzw. MouseLeav zuweisen.
Zum Beispiel so:
Delphi-Quellcode:
procedure TForm1.AllLabelEnter(Sender: TObject);
begin
  (Sender As TLabel).Font.Color := clRed // Sender ist immer das "Label" welches die Methode aufgerufen hat.
end;

procedure TForm1.AllLabelLeave(Sender: TObject);
begin
  (Sender As TLabel).Font.Color := clWindowText;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Label1.OnMouseEnter := AllLabelEnter; // Alle Label haben das selbe MouseEnter
  Label2.OnMouseEnter := AllLabelEnter;
  Label3.OnMouseEnter := AllLabelEnter;

  Label1.OnMouseLeave := AllLabelLeave; // Alle Label haben das selbe MouseLeav
  Label2.OnMouseLeave := AllLabelLeave;
  Label3.OnMouseLeave := AllLabelLeave;
end;
Die Zuweisung kannst Du entweder im ObjectInspector oder zur Laufzeit (OnCreate) machen. In meinem Beispiel habe ich es mal im Code gemacht. Natürlich gibt es auch hierfür wieder verschiedene Wege. Bei 30 Labels würde ich das über eine FOR-DO Schleife machen. (Wenn es wirklich alle Labels der Form sein sollen.

[EDIT]Nachtrag:
Hier noch der Code um allen Labels auf der Form die Methoden zuweisen zu könne:
Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
var
  ndx : integer;
begin
  for ndx := 0 to ComponentCount -1 do // Durchlaufe alle Komponenten.
  begin
    if (Components[ndx] is TLabel) then // Wenn es ein Label ist dann
    begin
      (Components[ndx] as TLabel).OnMouseEnter := AllLabelEnter;
      (Components[ndx] as TLabel).OnMouseLeave := AllLabelLeave;
    end;
  end;
end;

negaH 13. Sep 2005 20:42

Re: Label unter Mausposition
 
Zitat:

Wenn es wirklich alle Labels der Form sein sollen
In diesem Falle würde ich eben meine Methode vorschlagen ;) statt einer Schleife über Self.Components[].

Aber erstmal muß Lilo die grundsätzliche Arbeitsweise verstanden haben, denn mein Lösungsvorschlag kann keine anderen Events für ganz andere Probleme lösen.

Sogesehen hat Marabu schon Recht wenn er meint das Faux intelligent reagiert hat, für meine Begriffe aber schon fast hellseherisch intelligent ;) (wer kann schon ahnen wir der Wissenstand des Fragestellers ist)

Gruß Hagen

Lilo 13. Sep 2005 21:06

Re: Label unter Mausposition
 
danke erstmal für das rege interesse an meiner unfähigkeit :)

@hagen, die arbeitsweise deiner lösung ist mir noch etwas schleierhaft... danke aber erstmal für deine hilfsbereitschaft :) werde mich in zukunft damit noch intensiver beschäftigen

@sharky, ez hab ich erstmal geschnallt was faux genau meinte ^^ sowas reicht ja im prinzip schon obwohl hagens methode wohl felxibler ist, aber das kommt noch

danke

negaH 13. Sep 2005 21:50

Re: Label unter Mausposition
 
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

faux 13. Sep 2005 21:54

Re: Label unter Mausposition
 
Sorry, der erneuten Nachfrage, aber wie kann man FindDragTarget in .NET realisieren?

negaH 13. Sep 2005 22:00

Re: Label unter Mausposition
 
@Faux, da kann ich dir leider auch nicht weiterhelfen. Eventuell Sharky oder Robert ?

Gibts den im .NET Frame die Events .OnMouseEnter() und .OnMouseLeave() ? Falls ja so wird es auch einen globalen Handler geben der diese Events auslösen muß, und dieser wiederum muß ebenfalls das aktuelle MouseControl verwalten und ebenfalls das Control unter der Maus ermitteln können.

Gruß Hagen

Puhbaehr 10. Nov 2005 11:57

Re: Label unter Mausposition
 
Danke Hagen für den Code und die gute Erklärung dazu! Ähnliches habe ich auch gesucht.

Hast du denn dein Beispiel schon der Code-Library vorgeschlagen? Wenn nein dann würde ich das tun. Denn ich bin mir sicher es sind noch mehr Leute auf der Suche nach genau das!

Vielen Dank!

Gruß, Robert
(Nein ich bin nicht der Robert den Hagen meint ;))

negaH 11. Nov 2005 11:05

Re: Label unter Mausposition
 
Hi

dann mach dies bitte ;)

Gruß hagen


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:54 Uhr.
Seite 4 von 4   « Erste     234   

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