Contents

About Events

An event links an occurrence in the system with the code that responds to that occurrence. The occurrence triggers the execution of a procedure called an event handler. The event handler performs the tasks that are required in response to the occurrence. Events allow the behavior of a component to be customized at design-time or at run time. To change the behavior of the component, replace the event handler with a custom event handler that will have the desired behavior.

Event Properties and Event Handlers

Components that are written in Delphi use properties to indicate the event handler that will be executed when the event occurs. By convention, the name of an event property begins with "On", and the property is implemented with a field rather than read/write methods. The value stored by the property is a method pointer, pointing to the event handler procedure.

In the following example, the TObservedObject class includes an OnPing event, of type TPingEvent. The FOnPing field is used to store the event handler. The event handler in this example, TListener.Ping, prints 'TListener has been pinged!'.

programEventDemo;{$APPTYPE CONSOLE}type{ Define a procedural type }TPingEvent=procedureofobject;{ The observed object }TObservedObject=classprivateFPing:TPingEvent;publicpropertyOnPing:TPingEventreadFPingwriteFPing;{ Triggers the event if anything is registered }procedureTriggerEvent();end;{ The listener }TListener=classprocedurePing;end;procedureTObservedObject.TriggerEvent;begin{ Call the registerd event only if there is a listener }ifAssigned(FPing)thenFPing();end;procedureTListener.Ping;beginWriteln('TListener has been pinged.');end;varObservedObject:TObservedObject;Listener:TListener;begin{ Create object instances }ObservedObject:=TObservedObject.Create();Listener:=TListener.Create();{ Register the event handler }ObservedObject.OnPing:=Listener.Ping;{ Trigger the event }ObservedObject.TriggerEvent();//Should output 'TListener has been pinged'Readln;// Pause console before closingend.

Triggering Multiple Event Handlers

In Delphi, events can be assigned only a single event handler. If multiple event handlers must be executed in response to an event, the event handler assigned to the event must call any other event handlers. In the following code, a subclass of TListener called TListenerSubclass has its own event handler called Ping2. In this example, the Ping2 event handler must explicitly call the TListener.Ping event handler in order to trigger it in response to the OnPing event:

programEventDemo2;{$APPTYPE CONSOLE}type{ Define a procedural type }TPingEvent=procedureofobject;{ The observed object }TObservedObject=classprivateFPing:TPingEvent;publicpropertyOnPing:TPingEventreadFPingwriteFPing;{ Triggers the event if anything is registered }procedureTriggerEvent();end;{ The listener }TListener=classprocedurePing;end;{ The listener sub-class }TListenerSubclass=class(TListener)procedurePing2;end;procedureTObservedObject.TriggerEvent;begin{ Call the registerd event only if there is a listener }ifAssigned(FPing)thenFPing();end;procedureTListener.Ping;beginWriteln('TListener has been pinged.');end;procedureTListenerSubclass.Ping2;begin{ Call the base class ping }Self.Ping();Writeln('TListenerSubclass has been pinged.');end;varObservedObject:TObservedObject;Listener:TListenerSubclass;begin{ Create object instances }ObservedObject:=TObservedObject.Create();Listener:=TListenerSubclass.Create();{ Register the event handler }ObservedObject.OnPing:=Listener.Ping2;{ Trigger the event }ObservedObject.TriggerEvent();//Should output 'TListener has been pinged'//and then 'TListenerSubclass has been pinged'Readln;// Pause console before closingend.