Chapter 39
Modifying an existing component

The easiest way to create a component is to derive it from a component that does nearly everything you want, then make whatever changes you need. What follows is a simple example that modifies the standard memo component to create a memo that does not wrap words by default.

The value of the memo component's WordWrap property is initialized to True. If you frequently use non-wrapping memos, you can create a new memo component that does not wrap words by default.

Note: To modify published properties or save specific event handlers for an existing component, it is often easier to use a component template rather than create a new class.

Modifying an existing component takes only two steps:

Creating and registering the component

Creation of every component begins the same way: you create a unit, derive a component class, register it, and install it on the Component palette. This process is outlined in "Creating a new component".

For this example, follow the general procedure for creating a component, with these specifics:

If you compile and install the new component now, it behaves exactly like its ancestor, TMemo. In the next section, you will make a simple change to your component.

Modifying the component class

Once you have created a new component class, you can modify it in almost any way. In this case, you will change only the initial value of one property in the memo component. This involves two small changes to the component class:

The constructor actually sets the value of the property. The default tells Delphi what values to store in the form (.DFM) file. Delphi stores only values that differ from the default, so it is important to perform both steps.

Overriding the constructor

When a component is placed on a form at design time, or when an application constructs a component at runtime, the component's constructor sets the property values. When a component is loaded from a form file, the application sets any properties changed at design time.

Note: When you override a constructor, the new constructor must call the inherited constructor before doing anything else. For more information, see "Overriding methods".

For this example, your new component needs to override the constructor inherited from TMemo to set the WordWrap property to False. To achieve this, add the constructor override to the forward declaration, then write the new constructor in the implementation part of the unit:

type
  TWrapMemo = class(TMemo)
  public                                              { constructors are always public }
    constructor Create(AOwner: TComponent); override; { this syntax is always the same }
  end;
...
constructor TWrapMemo.Create(AOwner: TComponent);     { this goes after implementation }
begin
  inherited Create(AOwner);                           { ALWAYS do this first! }
  WordWrap := False;                                  { set the new desired value }
end;

Now you can install the new component on the Component palette and add it to a form. Note that the WordWrap property is now initialized to False.

If you change an initial property value, you should also designate that value as the default. If you fail to match the value set by the constructor to the specified default value, Delphi cannot store and restore the proper value.

Specifying the new default property value

When Delphi stores a description of a form in a form file, it stores the values only of properties that differ from their defaults. Storing only the differing values keeps the form files small and makes loading the form faster. If you create a property or change the default value, it is a good idea to update the property declaration to include the new default. Form files, loading, and default values are explained in more detail in "Making components available at design time."

To change the default value of a property, redeclare the property name, followed by the directive default and the new default value. You don't need to redeclare the entire property, just the name and the default value.

For the word-wrapping memo component, you redeclare the WordWrap property in the published part of the object declaration, with a default value of False:

type
  TWrapMemo = class(TMemo)
  ...
  published
    property WordWrap default False;
  end;

Specifying the default property value does not affect the workings of the component. You must still initialize the value in the component's constructor. Redeclaring the default ensures that Delphi knows when to write WordWrap to the form file.