RAD Studio |  |

Creating events
Collapse All
Topics

Name | Description
Creating Events: Overview | An event is a link between an occurrence in the system (such as a user action or a change in focus) and a piece of code that responds to that occurrence. The responding code is an event handler, and is nearly always written by the application developer. Events let application developers customize the behavior of components without having to change the classes themselves. This is known as delegation. Events for the most common user actions (such as mouse actions) are built into all the standard components, but you can also define new events. To create events in a... more
What Are Events? | An event is a mechanism that links an occurrence to some code. More specifically, an event is a method pointer that points to a method in a specific class instance. From the application developer's perspective, an event is just a name related to a system occurrence, such as OnClick, to which specific code can be attached. For example, a push button called Button1 has an OnClick method. By default, when you assign a value to the OnClick event, the Form Designer generates an event handler called Button1Click in the form that contains the button and assigns it to OnClick... more
Events Are closures (C++) | Closures are used to implement events. A closure is a special pointer type that points to a specific method in a specific class instance. As a component writer, you can treat the closure as a place holder: your code detects that an event occurs, so you call the method (if any) specified by the user for that event. Closures maintain a hidden pointer to a class instance. When the user assigns a handler to a component's event, the assignment is not just to a method with a particular name, but rather to a specific method of a specific class instance.... more
Events Are Method Pointers | Delphi uses method pointers to implement events. A method pointer is a special pointer type that points to a specific method in a specific class instance. As a component writer, you can treat the method pointer as a placeholder: When your code detects that an event occurs, you call the method (if any) specified by the user for that event. Method pointers work just like any other procedural type, but they maintain a hidden pointer to a class instance. When the application developer assigns a handler to a component's event, the assignment is not just to a method with a... more
Calling the Click-event Handler | All controls, for example, inherit a dynamic method called Click for handling click events:
Events Are Properties | Components use properties to implement their events. Unlike most other properties, events do not use methods to implement their read and write parts. Instead, event properties use a private class field of the same type as the property. By convention, the field's name is the name of the property preceded by the letter F. For example, the OnClick method's pointer is stored in a field called FOnClick of type TNotifyEvent, and the declaration of the OnClick event property looks like this:
Event Types Are Method-pointer Types | Because an event is a pointer to an event handler, the type of the event property must be a method-pointer type. Similarly, any code to be used as an event handler must be an appropriately typed method of a class. All event-handler methods are procedures. To be compatible with an event of a given type, an event-handler method must have the same number and type of parameters, in the same order, passed in the same way. Delphi defines method types for all its standard events. When you create your own events, you can use an existing type if that is... more
Event Handler Types Are Procedures | Although the compiler allows you to declare method-pointer types that are functions, you should never do so for handling events. Because an empty function returns an undefined result, an empty event handler that was a function might not always be valid. For this reason, all your events and their associated event handlers should be procedures. Although an event handler cannot be a function, you can still get information from the application developer's code using var parameters. When doing this, make sure you assign a valid value to the parameter before calling the handler so you don't require the user's code... more
Event Handlers Have A Return Type of void (C++) | Event handlers must have a return type of void. Even though the handler can return only void, you can still get information back from the user's code by passing arguments by reference. When you do this, make sure you assign a valid value to the argument before calling the handler so you do not require the user's code to change the value. An example of passing arguments by reference to an event handler is the key-pressed event, of type TKeyPressEvent. TKeyPressEvent defines two arguments: one to indicate which object generated the event, and one to indicate which... more
Event Types Are closure Types (C++) | Because an event is a pointer to an event handler, the type of the event property must be a closure type. Similarly, any code to be used as an event handler must be an appropriately typed method of a class. To be compatible with an event of a given type, an event-handler method must have the same number and type of parameters, in the same order, passed in the same way. C++Builder defines closures for all its standard events. When you create your own events, you can use an existing closure if that is appropriate, or define one of your... more
Event Handlers Are Optional | When creating events, remember that developers using your components may not attach handlers to them. This means that your component should not fail or generate errors simply because there is no handler attached to a particular event. (The mechanics of calling handlers and dealing with events that have no attached handler are explained in Calling the event.) Events happen almost constantly in a GUI application. Just moving the mouse pointer across a visual component sends numerous mouse-move messages, which the component translates into OnMouseMove events. In most cases, developers do not want to handle the mouse-move events, and this... more
Implementing the Standard Events | The controls that come with the component library inherit events for the most common occurrences. These are called the standard events. Although all these events are built into the controls, they are often protected, meaning developers cannot attach handlers to them. When you create a control, you can choose to make events visible to users of your control. There are three things you need to consider when incorporating the standard events into your controls: Identifying standard events Making events visible Changing the standard event handling
Identifying Standard Events | There are two categories of standard events: those defined for all controls and those defined only for the standard windowed controls.
Making Events Visible | The declarations of the standard events in TControl and TWinControl are protected, as are the methods that correspond to them. If you are inheriting from one of these abstract classes and want to make their events accessible at runtime or design time, you need to redeclare the events as either public or published. Redeclaring a property without specifying its implementation keeps the same implementation methods, but changes the protection level. You can, therefore, take an event that is defined in TControl but not made visible, and surface it by declaring it as public or published.
Changing the Standard Event Handling | If you want to change the way your component responds to a certain kind of event, you might be tempted to write some code and assign it to the event. As an application developer, that is exactly what you would do. But when you are creating a component, you must keep the event available for developers who use the component. This is the reason for the protected implementation methods associated with each of the standard events. By overriding the implementation method, you can modify the internal event handling; and by calling the inherited method you can maintain the standard handling,... more
Defining Your Own Events | Defining entirely new events is relatively unusual. There are times, however, when a component introduces behavior that is entirely different from that of any other component, so you will need to define an event for it. There are the issues you will need to consider when defining an event: Triggering the event Defining the handler type Declaring the event Calling the event
Triggering the Event | You need to know what triggers the event. For some events, the answer is obvious. For example, a mouse-down event occurs when the user presses the left button on the mouse and Windows sends a WM_LBUTTONDOWN message to the application. Upon receiving that message, a component calls its MouseDown method, which in turn calls any code the user has attached to the OnMouseDown event. However, some events are less clearly tied to specific external occurrences. For example, a scroll bar has an OnChange event, which is triggered by several kinds of occurrence, including keystrokes, mouse clicks, and changes in other... more
Two Kinds of Events | There are two kinds of occurrence you might need to provide events for: user interactions and state changes. User-interaction events are nearly always triggered by a message from Windows, indicating that the user did something your component may need to respond to. State-change events may also be related to messages from Windows (focus changes or enabling, for example), but they can also occur through changes in properties or other code. You have total control over the triggering of the events you define. Define the events with care so that developers are able to understand and use them.
Defining the Handler Type | Once you determine when the event occurs, you must define how you want the event handled. This means determining the type of the event handler. In most cases, handlers for events you define yourself are either simple notifications or event-specific types. It is also possible to get information back from the handler.
Declaring the Event | Once you have determined the type of your event handler, you are ready to declare the method pointer and the property for the event. Be sure to give the event a meaningful and descriptive name so that users can understand what the event does. Try to be consistent with names of similar properties in other components.
Calling the Event | You should centralize calls to an event. That is, create a virtual method in your component that calls the application's event handler (if it assigns one) and provides any default handling. Putting all the event calls in one place ensures that someone deriving a new component from yours can customize event handling by overriding a single method, rather than searching through your code for places where you call the event. There are two other considerations when calling the event: Empty handlers must be valid. Users can override default handling.
Empty Handlers Must Be Valid | You should never create a situation in which an empty event handler causes an error, nor should the proper functioning of your component depend on a particular response from the application's event-handling code.
Users Can Override Default Handling | For some kinds of events, developers may want to replace the default handling or even suppress all responses. To allow this, you need to pass an argument by reference to the handler and check for a certain value when the handler returns. This is in keeping with the rule that an empty handler should have the same effect as no handler at all. Because an empty handler will not change the values of arguments passed by reference, the default handling always takes place after calling the empty handler.

Copyright(C) 2009 Embarcadero Technologies, Inc. All Rights Reserved.
What do you think about this topic? Send feedback!