Ich versuch mich mal ein einem Beitrag für die FAQ. Bitte um Ergänzungen und das anschließende Verschieben in den richtigen Bereich.
Was tun, wenn man eine Procedure bei verschiedenen Ereignissen aufgerufen haben will ? Jedes Objekt auf der Oberfläche (Buttons, Label, Edits ....) ruft eine Proceduren auf, wenn bestimmte Ereignisse auftreten (anklicken, ändern ...). Das Objekt kann das nur tun, weil es einen Pointer auf diese Proceduren speichert, der von außen gesetzt wird. Würde das Objekt diesen Pointer nicht besitzen, könnte es selbständig gar keine Proceduren aufrufen, die global oder in anderen Klassen definiert sind.
Diese Pointer sind alle vom Typ
type TNotifyEvent = procedure (Sender: TObject) of object;
Das Objekt übergibt immer self an den Parameter Sender. Wenn man also einen Button auf die Form legt und eine OnClick-procedure dazu schreibt, setzt Delphi intern (in der *dfm-Datei) den dazugehörigen Pointer des Buttons auf diese Procedure.
Wenn man nur eine Procedure schreiben will, für (ich nehme wieder den einfachsten Fall an) zwei Buttons, die ähnliches machen sollen, kann man im Objekt-Inspektor im Register Events einfach bei beiden Buttons die gleiche Procedure angeben. Wichtig ist dabei, dass diese Procedure nur einen Paramter von Typ TObject erwartet, und sonst nichts.
Beispiel:
Delphi-Quelltext
1: 2: 3: 4: 5: 6:
| procedure TForm1.OnClickAnyButton(Sender :TObject); var Button :TButton; begin Button := Sender as TButton; ShowMessage(Button.Caption); end; |
Jeder Button, der im Objekt-Inspektor diese Procedure als OnClick-Methode zugewiesen bekommt, wird beim anklicken seine Caption in einer MessageBox ausgeben.
Man kann diese Zuweisung auch dynamisch im Quellcode ausführen, was besonders intersessatn ist bei dynamisch angelegten Objekten.
Delphi-Quelltext
1: 2: 3: 4: 5:
| Button1.OnClick := OnClickAnyButton; Button1.OnClick := OnClickAnyButton; Edit1.OnChange := OnClickAnyButton; |
Aber was passiert da in der dritten Zeile? Delphi wird nicht meckern, da hier alles syntaktisch korrekt ist, aber wenn OnChange aufgerufen wird, wird es einen Laufzeitfehler geben: Die Konvertierung (bzw. der Versuch derselben) des Sender in einen Button wird fehlschlagen. Und ganz abgesehen davon wäre der Name OnClickAnyButton für das OnChange-Event eines Edits sehr unpassend gewählt
Moderiert von
Tino: Überflüssige Absätze entfernt.