Date added/modified: 11 Nov 1999
You may not realize it but this is a concept at the core of Delphi technology and makes it truly amazing. You use it all the time without knowing about it. It might be interesting to see what this is all about.
I'll try to explain. Suppose you define a symbol TMyEvent with the following syntax:
type
TMyEvent = 'a function or procedure prototype' of object;
Where, you substitute a desired function prototype in the above statement.
Now, if you declare a variable of the type TMyEvent, it's actually a method pointer. At runtime, it can point to any method of any object as long as its function or procedure prototype exactly matches what you defined above. What does this mean? At run time, some work of an object can be done by a method of another object. This is great! Here is how Delphi uses method pointers all the time to ease your work.
Look at the definition of TNotifyEvent in Delphi's help. It's declared as a method pointer:
type TNotifyEvent = procedure(Sender: TObject) of object;
Now see how the property OnClick is defined for the class TControl:
property OnClick: TNotifyEvent;
Internally, FOnClick is a variable of type TNotifyEvent in TControl. So, it's actually a method pointer. When you double-click on the OnClick event of a TButton in the Object Inspector, here is what Delphi does for you:
- Delphi creates a procedure of the TNotifyEvent type as a method of the form. For example:
procedure MyForm.Button1Click(Sender: TObject);
begin
end;
- Then, it assigns this method to the OnClick property of that button which is internally assigned to the FOnClick method pointer.
- Now, if a click event occurs for the button, its TControl logic simply checks to see if FOnClick has been assigned a value (a method). If it does, it passes control to it.
If you think about it, the click event of the button is actually passed on to a method of the form. You can even change it at run time by assigning the property to any other method of any object as long as the prototype is same.
Once you understand this, you can do some very neat things which the environment doesn't provide for you. For example, visually, there is no way to combine one or more components to form a composite component. In other words, a Form can't become a visual component. But, if you do in code what Delphi does in Object Inspector, you can do it. You can put all those components inside a Panel, then dynamically assign events to the panel's methods. Yes, it's possible but you need to do everything in code.
I have tried this approach to create a RichEdit control which carries its toolbar and ruler along with it.