Wie kann ich mehrere Komponeten mit derselben Ereignisroutine bearbeiten?


Ich will z.B. dem OnClick-Ereignis meherer Buttons dieselbe Behandlungs-Routine zuweisen. Dabei soll aber eine unterschiedliche Aktion ausgeführt werden, abhängig vom Button, der angeklickt wurde. Wie kann ich den angeklickten Button in der Ereignisbehandlungs-Routine ermitteln?

Als Antwort sei hier die ausführliche Erklärung von Marian Aldenhövel aus der delphi-NG zitiert:

Der Typ der Ereignismethode steht fest. Im Falle von OnClick eine einfache Benachrichtigung:

  TNotifyEvent=procedure(Sender:TObject) of object;

Das bedeutet, ein Handler für dieses Ereignis muss eine Objektmethode sein ('of object') und genau einen Parameter vom Typ TObject haben. Der Name ist egal, Typ, Anzahl und Reihenfolge müssen passen (siehe 'procedural types' in der Sprachreferenz).

Welchen Wert dieser Parameter hat wenn das Ereignis ausgelöst wird, bestimmst nicht Du bei der Zuweisung, sondern wer auch immer das aufruft. Im Falle eines TNotifyEvent zeigt Sender auf die Instanz, die das Ereignis auslöst. Die allermeisten VCL-Ereignisse bringen einen solchen Parameter mit. Innerhalb der VCL sieht die Auslösung eines OnClick-Ereignisses etwa so aus:

  if Assigned(FOnClick) then
    FOnClick(Self);

Also wird Deine Prozedur mit 'Self' als Parameter aufgerufen, der Knopf liefert also eine Referenz auf sich selbst mit. Du kannst dann im Handler Sender benutzen um festzustellen, welcher Deiner Buttons das war. Du kannst den Wert von Sender mit einer von Dir bei der Erzeugung gespeicherten Referenz auf den Knopf vergleichen:

  for i:=0 to 10 do
    if Sender=FButtons[i] then 
      ShowMessage('Button #'+IntToStr(i)+' geklickt!);

Oder Du kannst die Beschriftung benutzen:

  if Sender is TButton then
    ShowMessage(''''+TButton(Sender).Caption+''' geclickt.');

Oder Du weist bei der Erzeugung der Eigenschaft Tag einen Wert zu und vergleichst den:

  if Sender is TComponent then
    ShowMessage('Komponente mit Tag='+IntToStr(TComponent(Sender).Tag))+' geklickt.');

Oder Du gibst jedem einen Namen:

  if Sender is TComponent then
    ShowMessage('Komponente mit Name='''+TComponent(Sender).Name))+''' geklickt.');
Delphi 1 Delphi 2 Delphi 3 Delphi 4
nicht getestet Version nicht betroffen getestet

siehe auch:

Wie kann ich Komponenten zur Laufzeit über ihren Namen ansprechen?
Woher weiß ich, über welcher Komponente mein PopupMenu aufgerufen wurde?
Wie kann ich ein Array von Komponenten erzeugen?


Delphi FAQ