Delphi 6 Component Structure
- Types of Properties
Components are Object Pascal classes that encapsulate the functionality and behavior of elements developers use to add visual and behavioral characteristics to their programs. All components have a certain structure. This article discusses the makeup of Delphi components.
Properties give the user an interface to a component's internal storage fields. Using properties, the component user can modify or read storage field values. Typically, the user doesn't have direct access to component storage fields because they're declared in the private section of a component's class definition.
Properties: Storage Field Accessors
Properties provide access to storage fields either by accessing the storage fields directly or through access methods. Take a look at the following property definition:
TCustomEdit = class(TWinControl) private FMaxLength: Integer; protected procedure SetMaxLength(Value: Integer); ... published property MaxLength: Integer read FMaxLength write SetMaxLength default 0; ... end;
The property MaxLength is the access to the storage field FMaxLength. The parts of a property definition consist of the property name, the property type, a read declaration, a write declaration, and an optional default value. The read declaration specifies how the component's storage fields are read. The MaxLength property directly reads the value from the FMaxLength storage field. The write declaration specifies the method by which the storage fields are assigned values. For the property MaxLength, the writer access method SetMaxLength() is used to assign the value to the storage field FMaxLength. A property can also contain a reader access method, in which case the MaxLength property would be declared as follows:
property MaxLength: Integer read GetMaxLength write SetMaxLength default 0;
The reader access method GetMaxLength() would be declared as follows:
function GetMaxLength: Integer;
Property Access Methods
Access methods take a single parameter of the same type as the property. The purpose of the writer access method is to assign the value of the parameter to the internal storage field to which the property refers. The reason for using the method layer to assign values is to protect the storage field from receiving erroneous data as well as to perform various side effects, if required. For example, examine the implementation of the following SetMaxLength() method:
procedure TCustomEdit.SetMaxLength(Value: Integer); begin if FMaxLength <> Value then begin FMaxLength := Value; if HandleAllocated then SendMessage(Handle, EM_LIMITTEXT, Value, 0); end; end;
This method first verifies that the component user isn't attempting to assign the same value as that which the property already holds. If not, it makes the assignment to the internal storage field FMaxLength and then calls the SendMessage() function to pass the EM_LIMITTEXT Windows message to the window that TCustomEdit encapsulates. This message limits the amount of text that a user can enter into an edit control. Calling SendMessage() in the property's writer access method is known as a side effect when assigning property values.
Side effects are any actions affected by the assignment of a value to a property. In assigning a value to the MaxLength property of TCustomEdit, the side effect is that the encapsulated edit control is given an entry limit. Side effects can be much more sophisticated than this.
One key advantage to providing access to a component's internal storage fields through properties is that the component writer can change the implementation of the field access without affecting the behavior for the component user. A reader access method, for example, can change the type of the returned value to something different from the type of the storage field to which the property refers.
Another fundamental reason for the use of properties is to make modifications available to them during design time. When a property appears in the published section of a component's declaration, it also appears in the Object Inspector so that the component user can make modifications to this property.