![]() |
Ereignis-Name zur Laufzeit zuweisen
Hi,
die Frage hat hiermit was zu tun : ![]() Es geht um ein Panel und ein Label darauf. Nun kommt hinzu, dass bei Drücken von Enter etwas gemacht werden muss. Und zwar, sofern das Label oder das entsprechende Panel den Focus hat. Leider hat das Label kein KeyPress usw. und das Panel hat kein MouseEnter usw. Ich habe deshalb (vorläufig) den Weg gewählt, im PanelEnter/Mouseenter die entsprechhenden Komponentennamen zu speichern und das FormKeyDown auszuwerten :
Delphi-Quellcode:
procedure Tfrm.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState); var c : TComponent; begin if key = 13 then begin c := FindComponent(AltKompName); ShowMessage ('****** '+c.Name); Label2Click (Sender); //c.Name+'OnKeyDown'; end; end;
Delphi-Quellcode:
Das Label2Click geht auch soweit (momentan eben nur showmessage), aber der ganaue Name ist zum Zeitpunkt des auslösens ja gar nicht bekannt. Das könnte auch Label12345Click heißen. ShowMessage ('****** '+c.Name); liefert den Namen des Controls. Wie baue ich daraus jetzt einen Prozedurnamen zusammen oder führe die Procedure aus ?
procedure Tfrm.Label2Click(Sender: TObject);
begin showmessage ('Label2Click'); end; |
Re: Ereignis-Name zur Laufzeit zuweisen
Ruf die Methode nicht per Namen sondern über die entsprechende Property des Senders auf.
|
Re: Ereignis-Name zur Laufzeit zuweisen
Der Sender ist aber das Formular (FormKeyDown). Woher soll dieses denn wissen, um was es genau geht ? Ohne Bsp. oder einen längeren Satz kann ich nichts mit der Antwort anfangen. :???:
|
Re: Ereignis-Name zur Laufzeit zuweisen
Hallo Hansa,
immer noch mit den Panel-Labels beschäftigt? :wink: ActiveControl könnte da helfen:
Delphi-Quellcode:
if Key = 13 then
if (assigned(ActiveControl)) and (ActiveControl.ClassType = TPanel) then showmessage('Label: '+ActiveControl.Controls[0].Name+#13#10+ ' auf Panel: '+ActiveControl.Name); |
Re: Ereignis-Name zur Laufzeit zuweisen
mkinzler meinte wahrscheinlich: Wenn Du mit c sowieso schon die Komponente hast, warum benutzt Du dann die On-Properties nicht gleich zum Methodenaufruf, ala:
Delphi-Quellcode:
with (c as TLabel) do
if assigned(OnClick) then OnClick(Sender); |
Re: Ereignis-Name zur Laufzeit zuweisen
Mit dem ActiveControl (Lannes) kriege ich tatsächlich das gewünschte Label. Das ist schonn mal gut. Wie bringe ich das nun noch dazu sein eigenes OnClick auszuführen ? Blöd, wenn man nicht am Stück an einer Sache dran bleiben kann. Mühsam ernährt sich das Eichhörnchen. :mrgreen:
|
Re: Ereignis-Name zur Laufzeit zuweisen
Delphi-Quellcode:
(ActiveControl as TLabel).onClick( ActiveControl);
|
Re: Ereignis-Name zur Laufzeit zuweisen
Wo muss denn das jetzt genau hin ? :shock: Ich kann es doch nur im OnKeyDown des Formulars gebrauchen. Delphi meckert schon hier drüber:
Delphi-Quellcode:
(ActiveControl as TLabel)
Delphi-Quellcode:
Bitte jetzt Butter bei die Fische, sonst verhungert das Eichhörnchen. :P Das kann nicht mehr viel sein.
[Fehler]Form1.pas(250): Inkompatible Typen: 'TLabel' und 'TWinControl'
|
Re: Ereignis-Name zur Laufzeit zuweisen
Wie TStringlist schon schrieb, einfach:
Delphi-Quellcode:
with (c as TLabel) do
begin if assigned(onClick) then OnClick(Sender); end; |
Re: Ereignis-Name zur Laufzeit zuweisen
Hallo,
Sender = Form, denn auslösendes Ereignis = FormKeyDown ActiveControl = Panel, denn Pfeiltasten oder Tab setzen das jeweilige Panel activ ActiveControl.Controls[0] = Label, denn das Label ist einziges Control, also Index = 0 @Hansa: damit Dein Eichhörnchen nicht verhungert :Sciurus: :-D
Delphi-Quellcode:
//...
var aLabel : TControl; //... if Key = 13 then if (assigned(ActiveControl)) and (ActiveControl.ClassType = TPanel) then begin showmessage('Label: '+ActiveControl.Controls[0].Name+#13#10+ 'auf Panel: '+ActiveControl.Name+#13#10+ 'Sender ist Form: '+TControl(Sender).Name); aLabel := ActiveControl.Controls[0];//<---------- TLabel(aLabel).OnClick(aLabel); end; |
Re: Ereignis-Name zur Laufzeit zuweisen
@Lannes
Warum so umständlich ? Er hat ja den Label schon. Oder überseh ich da irgendwas ? |
Re: Ereignis-Name zur Laufzeit zuweisen
Genau, das mit dem "c" (in welches das Control im LabelEnter-Eventhandler eingetragen wird) ist doch fast noch einfacher. Verlässt man das Label mit der Maus wieder, dann braucht man "c" im LabelLeave-Eventhandler nur noch auf nil zu setzen und kann es so gleichzeitig auch noch als Flag nutzen, ob es sich überhaupt auch um eine solche Situation handelt:
Delphi-Quellcode:
Ansonsten darf es ja auf der Form auch wirklich keine Vewechslungsmöglichkeiten geben, z.B. irgendein anderes Panel auf das man davor zufälligerweise geklickt hat o.ä....
if (Key = 13) and (c <> nil) then TLabel(c).OnClick(c);
Und ist der Focus tatsächlich noch Pflicht dann käme halt +/- dieses "and" noch dazu
Delphi-Quellcode:
and (TObject(ActiveControl) = TObject(c.parent))
|
Re: Ereignis-Name zur Laufzeit zuweisen
Hallo,
Bei meinen Vorschlag ist es nicht erforderlich (siehe Beitrag #1) im PanelEnter/Mouseenter die entsprechenden Komponentennamen zu speichern und die Labels dann per FindComponent(AltKompName) jedesmal wieder neu zu suchen. Warum erst das ActiveControl in PanelEnter merken, wenn man es direkt in FormKeyDown ermitteln kann? Wobei es schon umständlich ist, das über den Namen zu realisieren, da würde ein Zeiger auf das jeweilige Label ausreichen. Der gesamte benötigte Code, auf das wesentliche reduziert. Bei den Panels die berücksichtigt werden sollen wird die Tag-Eigenschaft auf 1 gesetzt:
Delphi-Quellcode:
Also kein LabelEnter-, LabelLeave-Eventhandler keine zusätzliche Variable, alles in einer Prozedur.
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState); begin if Key = 13 then if assigned(ActiveControl) then with ActiveControl do if ClassType = TPanel then if Tag = 1 then TLabel(Controls[0]).OnClick(Controls[0]); end; Finde nicht, das es umständlich ist. :wink: |
Re: Ereignis-Name zur Laufzeit zuweisen
Wenn Du Hansa's Link in #1 mit einbeziehst, dann siehst Du, dass er diese beiden Eventhandler für ein farbliches Herausheben der Labels ja schon selbst eingeführt hat. Und dieses 'alles in einer Prozedur' gilt hier eh nicht, denn um einem Panel den Focus zu geben, reicht kein einfaches Anklicken. Sondern dann muss man schon auf das Label selbst geclickt und in dessen OnClick-Methode das Label.Parent.setFocus ausgeführt haben. Wenn er also den Focus nur zur späteren Panel-Identifizierung braucht, dann müsste dieser Aufwand natürlich auch noch auf deine Variante dazugerechnet werden.
|
Re: Ereignis-Name zur Laufzeit zuweisen
Hallo,
"eine Prozedur" bezieht sich auf dieses Thema "Ereignis-Name zur Laufzeit zuweisen". :angel2: hmm, der Satz ist etwas falsch ausgedrückt: Also kein LabelEnter-, LabelLeave-Eventhandler keine zusätzliche Variable, alles in einer Prozedur. Also kein zusätzlicher Code im LabelEnter-, LabelLeave-Eventhandler, und keine zusätzliche Variable, die gesamte Ermittlung des Ereignis-Namens in einer Prozedur. Gedanklich war ich nicht nur bei diesem und dem verlinkten Thema, sondern auch dort im DF ![]() ![]() Darin geht es u.a. um das Ansteuern von Panels per Pfeiltasten, die dadurch den Focus bekommen. Da können wir noch lange hin und her Diskutieren, mal schauen was Hansa dazu sagt. |
Re: Ereignis-Name zur Laufzeit zuweisen
Ist wohl doch nicht so einfach wie gedacht, was ? Deshalb verschiebe ich das ja laufend und mache es nicht fertig. :zwinker:
Letzter Stan der Dinge :
Delphi-Quellcode:
Das c ist übrigens nur eine Hilfsvariable, die hier nicht gebraucht wird. Beim OnClick kracht es. Sehe nicht warum, aber es kracht. :mrgreen:
procedure TfrmKey.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState); var c : TComponent; // <--- Überbleibsel aLabel : TControl; begin if Key = 13 then begin if (assigned(ActiveControl)) and (ActiveControl.ClassType = TPanel) then begin showmessage('Label: '+ActiveControl.Controls[0].Name+#13#10+ 'auf Panel: '+ActiveControl.Name+#13#10+ 'Sender ist Form: '+TControl(Sender).Name); aLabel := ActiveControl.Controls[0]; showmessage ('LÄLÄÖLÖÄ'); TLabel(aLabel).OnClick(aLabel); //<----- Zugriffsverletzung end; end; EnterTab(Sender,Key,Shift,[],[],true); end; |
Re: Ereignis-Name zur Laufzeit zuweisen
Hallo,
nee, ist einfach, Du musst nur sicherstellen, das Deine Labels auch einen OnClick-Eventhandler besitzen. Ist das nicht möglich, dann halt noch eine Abfrage hinzufügen:
Delphi-Quellcode:
if assigned(TLabel(aLabel).OnClick) then
TLabel(aLabel).OnClick(aLabel); |
Re: Ereignis-Name zur Laufzeit zuweisen
@Lannes
Ah..ok...das kommt davon wenn der eigen "Scope" a bisserl eng ist. :) Natürlich ist deine Variante im gesamten Kontext betrachtet, einfacher :) |
Re: Ereignis-Name zur Laufzeit zuweisen
Liste der Anhänge anzeigen (Anzahl: 1)
Gut, gut. Aber da war noch einiges an Feinschliff nötig. Jede Zeile ist wichtig. Hänge mal für die Nachwelt ein kleines Projekt an, um zu zeigen, wie so was geht (Kommentare beachten). ABER : es ist noch nicht fertig. Folgendes ist noch offen :
vorab : das Demo-Projekt hat 2 Forms (per Objektablage vererbt). Da das kaum einer benutzt, nur als Hinweis, dass die 2. Form vom Source praktisch leer ist, weil sie alles erbt ! also die Fragen : 1. die Funktionalität soll nur auf der gerade aktivierten Form gültig sein. Wie sperre ich das ganze, sofern sich die Form ändert ? ActiveForm oder wie ? Der Button erzeugt und öffnet übrigens andere Form. 2. Daraus folgt das Nächste : wie kann ich am besten verhindern, dass eine Form 2mal geöffnet wird ? |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:35 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-2025 by Thomas Breitkreuz