![]() |
Label unter Mausposition
tach...
und zwar hab ich folgendes problem ^^ ich habe eine form und auf dieser befinden sich ca 30 label... ich will auf die label eine art rolloverefekt haben und en bissl was anderes... und hab nicht unbedingt lust für jedes label ne prozedur zu machen ^^ es soll quasi auf der form bei mousemove eine prozedur rein die prüft ob meine maus über einem label ist und wenn ja, dann brauche ich den name des labels. ist das einfach möglich? oder ist das mit anderen componenten einfacher? wie statictext oder so... |
Re: Label unter Mausposition
So müsste es gehen:
Delphi-Quellcode:
Einfach jedes Label mit dieser Procedure im OnMouseMove verlinken.
procedure TFormname.OnLabelMouseMove(Sender: TObject......);
var LabelName: String; begin LabelName := (Sender as TLabel).Name; end; Grüße Faux |
Re: Label unter Mausposition
Hi Lilo,
alternativ kannst du bei den TLabel-Komponenten auch mit OnMouseEnter() und OnMouseLeave() arbeiten - je nachdem was du vorhast. Grüße vom marabu |
Re: Label unter Mausposition
Mir ist noch eingefallen, du du mit dem namen nicht viel machen kannst (außer mit der API-FUnktion FindComponent weiter arbeiten). Es wäre sinnvoller wenn du gleich auf die Eigenschaft die du verändern willst (oder auf die Procedure, etc.) zugreifst. Also zB
Delphi-Quellcode:
(Sender as TLabel).Color := clGreen;
|
Re: Label unter Mausposition
Delphi-Quellcode:
Gruß Hagen
procedure TForm1.MouseMove();
var C: TControl; begin C := Controls.FindDragTarget(ClientToScreen(Point(X, Y)), True); if C is TLabel then begin end; end; |
Re: Label unter Mausposition
Zitat:
die varianten von oben sind nicht gut da ich dann wieder auf jedes label ne prozedur machen muss ^^ ich will quasi über eine prozedure das verhalten von 30 labels koordinieren ^^ |
Re: Label unter Mausposition
@Lilo
die methode von faux ist aber genau das, was du suchst. diese EINE procedure wird jedem Label zugeordnet und fertig. über den Sender kannste dann den namen bekommen. wie oben beschrieben
Delphi-Quellcode:
wobei ich es immer so mache (geschmackssache):
(Sender as TLabel).Name
Delphi-Quellcode:
TLabel(Sender).Name;
MfG |
Re: Label unter Mausposition
wieso "QControls" ? davon war nie die rede das du unter Kylix entwickelst, hast du mal die Hilfe bemüht ??
Wichtig ist noch eines: FindDragTarget() findet ALLE Controls der gesamten Anwendung, also auch diejenigen die sich in anderen Forms befinden. Du solltest also mit
Delphi-Quellcode:
sicherstellen das du nur die Labels des Forms ansprichst.
if (C is TLabel) and (C.Owner = Self) then
Gruß Hagen |
Re: Label unter Mausposition
Wo liegt eigentlich der Unterschied zwischen Hagens und meiner Methode?
|
Re: Label unter Mausposition
@faux.
also ich denke mal, Hagen sucht über die MouseMove Funktion des Formulars, oder? :? |
Re: Label unter Mausposition
Zitat:
|
Re: Label unter Mausposition
naja also was nun schneller ist kann ich auch nicht sagen. aber die methode von dir würd ich klar bevorzugen!!
so ein umstand von hagen (sry ;)) |
Re: Label unter Mausposition
IMHO ist Hagens Methode auch nicht so ohne weiteres ins .NET übertragbar.... Aber egal...
Zum Problem: Du weist jedem Labelüber den Objektinspektor einfach ein und die selbe Procedure zu, dann ist das ok so. Die Procedure unterscheidet dann, von welchem Label der Aufruf kommt. Sender ist immer das Objekt, von dem der Aufruf kommt (nicht nur bei MouseMove)... Grüße Faux |
Re: Label unter Mausposition
Ich möchte mich da anschließen:
Delphi-Quellcode:
Diese Methode könnte man dann den entsprechenden Labels zuweisen.
procedure TForm1.OnLabelMouseMove();
begin if Sender is TLabel then begin (Sender as TLabel).Color := clGreen; end; end; @ Hagen: Deine Lösung ist zwar recht simpel aber ein Problem hast du denke ich nicht bedacht: Was ist mit den Labels die diesen Effekt nicht erhalten sollen da sie z.B. nur als Beschriftung dienen sollen? Denn die bekommen den Effekt auch verpasst ... |
Re: Label unter Mausposition
Zitat:
Hagens Lösung ist die einzige die exact der geforderte Aufgabenstellung entspricht. ;-) |
Re: Label unter Mausposition
@negaH
ich entwickel net unter kylix ^^ ich hab nur mal in der hilfe nach dem begriff gesucht weil das net ging ... und dann husch pfusch bei uses reingeschrieben ^^
Delphi-Quellcode:
da bekomm ich den fehler "inkombatible Typen - tlabel und tcontrol"
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer); var C: TControl; begin C := Controls.FindDragTarget(ClientToScreen(Point(X, Y)), True); if C is TLabel then begin end; end; vielleicht bin ich auch nur zu dumm ^^ |
Re: Label unter Mausposition
Uff, danke Sharky.
Aber prinzipiell stimme ich den Argumenten der Anderen absolut zu, besonders wenn die Frage von einem Anfänger kommt. Ein Komponentenentwickler wird aber eher auf meinen Vorschlag basierend arbeiten da sie OHNE die Verwendung von Events auskommt. Die Art & Weise der Programmierung ist also eine komplett unterschiedliche. Während meine Funktion universell auch für andere kompliziertere Probleme benutzt werden kann, muß bei den anderen Vorschlägen der Programmierer gezielt die Events der schon zur Designzeit existierenden Kompoenten gesetzt werden. Mein Beispiel soll als eine mögliche Alternative zu den anderen Vorschlägen dienen. Man kann sich dann selber das rausziehen was man benötigt. Es hat also reingarnichts damit zu tuen das ich alles verkompliziere ! das ist schon indirekt eine Beleidigung ;) Gruß Hagen |
Re: Label unter Mausposition
Zitat:
Ich vermute mal das du C als TLabel deklariert hast und nicht wie im obigen Post als TControl ! Gruß hagen |
Re: Label unter Mausposition
@Lilo: Verstehst du überhaupt den Unterschied der dir vorgeschlagenen Lösungswege? Hast du auch gelsen, das bei Hagens Code alle Labels betroffen sind?
@Hagen: Ich hab ja nix gegen komplexen Code :roll: Aber wenns einfacher geht, und das selbe bewirkt, dann bevorzuge ich das einfachere. ;) Dein Code "kann" zwar mehr, in diesem Fall, ist es aber (du hast es selbst gesagt), egal, welchen Code man verwendet... :) Gruß Faux NACGTRAG: Zitat:
|
Re: Label unter Mausposition
Hi Leute,
es ist schon ein Kreuz. Manchmal legt man jedes Wort eines Fragestellers auf die Goldwaage, nur um später zu erfahren: "das hatte ich ganz anders gemeint". Andererseits besteht aber auch jederzeit die Gefahr, dass der Helfer für intelligentes Mitdenken abgewatscht wird. In diesem Fall denke ich hat Faux vorbildlich mitgedacht, denn aus der wenig vorbildlichen dafür aber um so mehr typischen Problembeschreibung hat er eine common misconception zu eliminieren versucht: das Delphi framework (vcl) ist objektorientiert und kaum ein Ereignis muss zentral (Form) behandelt werden - fast alles wird an die controls delegiert, wenn es Sinn macht. Wenn Lilo hier gelernt hat, dass man einen einzigen event handler für beliebig viele controls einsetzen kann, dann ist das ein Verdienst von Faux. Alle sonstigen Lösungsansätze sind in der Mächtigkeit ebenbürtig und unterscheiden sich nur im Kodieraufwand. Freundliche Grüße vom marabu |
Re: Label unter Mausposition
@ Hagen:
Du hast dich nur leicht verrannt wenn du mich fragst. FindDragTarget ist nämlich imho gar nicht nötig da du doch als Parameter den Sender bekommst! Außerdem würde ich die Funktion schon rein vom Namen her in die Sparte Drag & Drop einsortieren. Außerdem versuchst du das gefundene Element in eine Variable vom Typ TControl zu zwengen... Nach meiner Meinung (korregiert mich wenn ich falsch liege) kann das gar nicht gehen, denn Falls du ein Label übergeben bekommst ist es eben vom Typ TLabel und da hilfts auch nicht wenn es von einem TControl abstammt. P.S.: Ich schließ mich voll und ganz Marabu an: Ich denke wir wollen/sollen helfen die beste Lösung für ein Problem zu finden. |
Re: Label unter Mausposition
Zitat:
Unintelligent ist es von vornherein, ohne die Lösungsvorschläge der anderen zu diskretitieren geschweige denn sie zu verstehen ein Flamwar vom Zaun zu brechen. Faux, wurde in keinsterweise abgewascht, nicht von mir und auch nicht von Sharky. @Faux: Zitat:
Ich habe klipp und klar gesagt das es zum besseren Verständnisses des Fragestellers es besser ist deinen offensichtlichen und allgemein sinnvollen Vorschlag zu befolgen. Dies tat ich nur aus einem Grunde: dein Vorschlag ist wensentlich einfacher umzusetzen und schneller für einen Anfänger zu begreifen. Deinen Vorschlag ansich halte ich aus meiner Erfahrung aber für viel weniger Supportfreundlich, besonders wenn die Aufgabenstellung es verlangt das ALLE TLabels eines TForms angesprochen werden sollen. Dies beinhaltet auch die TLabels die erst viel später durch zb. einen anderen Programierer auf das TForm platziert werden. In diesem Moment bezahlt sich mein Vorschlag, denn man muß keinerlei Events mehr setzen, geschweige denn darüber überhaupt nachdenken ob man was setzen muß ! Egal: es nervt mich das man in letzter Zeit für eine gutgemeinte Hilfe immer wieder angezählt wird, statt sie einfach als sinnvollen Hinweis zu akzeptieren. Nochwas: was hat .NET mit der Sache zu tuen ?? Gruß Hagen |
Re: Label unter Mausposition
@M_Gr:
Zitat:
Sie heist einfach nunmal so, sie zu ignorieren um ein Problem zu lösen nur weil sie SO heist ist doch noch dümmer. Bitte schau dir die Objekthierarchie der VCL genauer an und überlege mal wer die Mutter aller Controls IST ! Gruß Hagen |
Re: Label unter Mausposition
Zitat:
Zitat:
@Lilo: Und hast du das Problem gelöst? |
Re: Label unter Mausposition
HiHo,
Ich wollte mir gar nicht groß in die Diskussion von euch einmischen, sondern nur zum Besten geben, dass ich die Lösungsvariante von Hagen supergut in einem Projekt von mir verwenden kann! Ich muss zwar noch daran rumdocktor'n, aber mit dynamisch erstellten Labels hat der Code echt was für sich! viele Grüße, hanselmansel P.S.: Und bzgl. der Komplexität des Codes: Man kann nun wirklich nicht behaupten, dass ich kein Newbie wäre! |
Re: Label unter Mausposition
hagens idee ist vom prinzip er genau das was ich brauche ^^
das problem, mal ein kleines bsp.:,
Delphi-Quellcode:
ich müsste dann ja bei allen 30 labeln mouseenter mouseleave jeweils 1 procedure machen... wenn ich aber den name bekommen kann wenn ich mit der maus über dem label in kann ich mir das alles sparen... und hab im endeffekt nur 3 proceduren ^^ kann sein das man sowas ganz elegant lösen kann aber diese lösung habe ich nicht gefunden deswegen mein weg hier her :) ^^
procedure TForm1.MausEnter(lbl:tlabel);
begin lbl.Font.Color:=clRed; end; procedure TForm1.MausLeave(lbl:tlabel); begin lbl.Font.Color:=clBlack; end; procedure TForm1.Label1MouseEnter(Sender: TObject); begin MausEnter(label1); end; procedure TForm1.Label1MouseLeave(Sender: TObject); begin MausLeave(label1); end; procedure TForm1.Label2MouseEnter(Sender: TObject); begin MausEnter(label2); end; |
Re: Label unter Mausposition
Hast du es nun geschafft, oder war dein letzer post ein "Bitte Helft mir" Post? :gruebel:
|
Re: Label unter Mausposition
Hi Lilo,
Zitat:
Ich nenne das jetzt mal eine wohldurchdachte Entscheidung, die auch Hagen versöhnen sollte... marabu |
Re: Label unter Mausposition
Passt zwar net ganz hier rein, aber einen neuen Thread braucht ma auch net:
Kann mir wer eine .NET kompatible Lösung zu Hangens Lösung geben/sagen/zu ihr verhelfen? Denn das ist manchmal sicherlich nützlich... ;) Danke schon mal. |
Re: Label unter Mausposition
Zitat:
1.) du hast 30 labels auf deinem TForm. 2.) klicke in das OnMouseEnter im OI von Label1 und schreibe im Quelltext folgendes
Delphi-Quellcode:
3.) nun wieder in de OI vom Label1 in OnMouseLeave() und doppelklick in der Methode schreibst du folgendes
procedure TForm1.Label1MouseEnter(Sender: TObject);
begin (Sender as TLabel).Font.Color := clRed; end;
Delphi-Quellcode:
4.) jetzt arbeitet das Label1 auf deinem Form schon wie gewünscht.
procedure TForm1.Label1MouseLeave(Sender: TObject);
begin (Sender as TLabel).Font.Color := clBlack; end; 5.) markiere alle anderen Labels von Label2 bis Label30 per Shift Taste 6.) gehe in den OI in OoMouseEnter() und wähle dort in der DropDown Liste die Methode .Label1OnMouseEnter() aus 7.) mache das gleiche mit OnMouseLeave() Nun haben alle 30 Labels die gleichen beiden Methoden, wie oben codiert in ihren Events zugewiesen. Du benötigst also KEINE 30*2 eigene Events um diese dann auf 2 Basismethoden umzudiregieren. Das Problem mit meiner Funktion ist das du nicht erkennen kannst ob die Mausbewegung ein neues Label selektiert bzw. das alte selektierte Label verlassen hat. Benötigst du diese Funktionalität so müsstest du meine Methode umbauen, inetwaso
Delphi-Quellcode:
Wichtig ist nur eines, egal welche Lösung du benutzt, du musst sie verstanden haben.
type
TForm1 = class(TForm) ...blabla private FCurrentLabel: TControl; ...blabla end. procedure TForm1.MouseMove(); var C: TControl; begin C := FindDragTarget(ClientToScreen(Point(X, Y)), False); if C <> FCurrentLabel then begin if (FCurrentLabel is TLabel) and (FCurrentLabel.Owner = Self) then TLabel(FCurrentLabel).Font.Color := clBlack; FCurrentLabel := C; if (FCurrentLabel is TLabel) and (FCurrentLabel.Owner = Self) then TLabel(FCurrentLabel).Font.Color := clRed; end; end; Ich empfehle also erstmal den Vorschlag von Faux genau zu verstehen, denn sein Vorschlag ist die Standardvorgehensweise, die man begriffen haben sollte. Also arbeite obige Punkte einfach mal ab. Gruß Hagen |
Re: Label unter Mausposition
Zitat:
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:
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.
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; [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; |
Re: Label unter Mausposition
Zitat:
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 |
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 |
Re: Label unter Mausposition
super.
Zitat:
Delphi-Quellcode:
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.
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; 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 |
Re: Label unter Mausposition
Sorry, der erneuten Nachfrage, aber wie kann man FindDragTarget in .NET realisieren?
|
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 |
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 ;)) |
Re: Label unter Mausposition
Hi
dann mach dies bitte ;) Gruß hagen |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:58 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 by Thomas Breitkreuz