Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Ereignis-Name zur Laufzeit zuweisen (https://www.delphipraxis.net/87605-ereignis-name-zur-laufzeit-zuweisen.html)

Hansa 2. Mär 2007 21:12


Ereignis-Name zur Laufzeit zuweisen
 
Hi,

die Frage hat hiermit was zu tun :

http://www.delphipraxis.net/internal...955d5395de32b4

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:
procedure Tfrm.Label2Click(Sender: TObject);
begin
showmessage ('Label2Click');
end;
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 ?

mkinzler 2. Mär 2007 21:26

Re: Ereignis-Name zur Laufzeit zuweisen
 
Ruf die Methode nicht per Namen sondern über die entsprechende Property des Senders auf.

Hansa 5. Mär 2007 01:10

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. :???:

Lannes 5. Mär 2007 06:37

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);

TStringlist 5. Mär 2007 08:18

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);

Hansa 5. Mär 2007 21:31

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:

mkinzler 5. Mär 2007 21:36

Re: Ereignis-Name zur Laufzeit zuweisen
 
Delphi-Quellcode:
(ActiveControl as TLabel).onClick( ActiveControl);

Hansa 5. Mär 2007 23:27

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:
[Fehler]Form1.pas(250): Inkompatible Typen: 'TLabel' und 'TWinControl'
Bitte jetzt Butter bei die Fische, sonst verhungert das Eichhörnchen. :P Das kann nicht mehr viel sein.

Ghostwalker 6. Mär 2007 05:50

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;

Lannes 6. Mär 2007 07:25

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;

Ghostwalker 6. Mär 2007 08:34

Re: Ereignis-Name zur Laufzeit zuweisen
 
@Lannes

Warum so umständlich ? Er hat ja den Label schon. Oder überseh ich da irgendwas ?

TStringlist 6. Mär 2007 08:58

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:
if (Key = 13) and (c <> nil) then TLabel(c).OnClick(c);
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.ä....

Und ist der Focus tatsächlich noch Pflicht dann käme halt +/- dieses "and" noch dazu

Delphi-Quellcode:
and (TObject(ActiveControl) = TObject(c.parent))

Lannes 6. Mär 2007 09:47

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:
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;
Also kein LabelEnter-, LabelLeave-Eventhandler keine zusätzliche Variable, alles in einer Prozedur.
Finde nicht, das es umständlich ist. :wink:

TStringlist 6. Mär 2007 11:24

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.

Lannes 6. Mär 2007 12:48

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 Link und Link
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.

Hansa 6. Mär 2007 19:31

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:
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;
Das c ist übrigens nur eine Hilfsvariable, die hier nicht gebraucht wird. Beim OnClick kracht es. Sehe nicht warum, aber es kracht. :mrgreen:

Lannes 6. Mär 2007 21:26

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);

Ghostwalker 7. Mär 2007 06:35

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 :)

Hansa 8. Mär 2007 01:12

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