RAD Studio
ContentsIndex
PreviousUpNext
Creating a graphic component
Name 
Description 
Once you have declared your graphic component and published any inherited properties you want to make available, you can add the graphic capabilities that distinguish your component. You have two tasks to perform when creating a graphic control:
  1. Determining what to draw.
  2. Drawing the component image.
In addition, for the shape control example, you will add some properties that enable application developers to customize the appearance of the shape at design time. 
A graphic control is a simple kind of component. Because a purely graphic control never receives focus, it does not have or need its own window handle. Users can still manipulate the control with the mouse, but there is no keyboard interface.
The graphic control presented in the following topics is TShape, the shape component on the Additional page of the Tool palette. Although the component created is identical to the standard shape component, you need to call it something different to avoid duplicate identifiers. The following topics use the name TSampleShape and show you all the steps involved... more 
You create every component in the same way: create a unit, derive a component class, register it, compile it, and install it on the Tool palette. This process is outlined in Creating a new component. 
You can provide access to the owned objects of a component by declaring properties of the type of the objects. That gives developers a way to access the objects at design time or runtime. Usually, the read part of the property just references the class field, but the write part calls a method that enables the component to react to changes in the owned object.
To the shape control, add properties that provide access to the pen and brush fields. You will also declare methods for reacting to changes to the pen or brush.  
Each class a component owns must have a class field declared for it in the component. The class field ensures that the component always has a pointer to the owned object so that it can destroy the class before destroying itself. In general, a component initializes owned objects in its constructor and destroys them in its destructor.
Fields for owned objects are nearly always declared as private. If applications (or other components) need access to the owned objects, you can declare published or public properties for this purpose.
Add fields for a pen and brush to the shape control:  
When you declare a property, you usually need to declare a private field to store the data for the property, then specify methods for reading and writing the property value. Often, you don't need to use a method to read the value, but can just point to the stored data instead.
For the shape control, you will declare a field that holds the current shape, then declare a property that reads that field and writes to it through a method call.
Add the following declarations to TSampleShape:  
When you declare a property of a user-defined type, you must declare the type first, before the class that includes the property. The most common sort of user-defined type for properties is enumerated.
For the shape control, you need an enumerated type with an element for each kind of shape the control can draw.
Add the following type definition above the shape control class's declaration.  
A graphic control can change its appearance to reflect a dynamic condition, including user input. A graphic control that always looks the same should probably not be a component at all. If you want a static image, you can import the image instead of using a control.
In general, the appearance of a graphic control depends on some combination of its properties. The gauge control, for example, has properties that determine its shape and orientation and whether it shows its progress numerically as well as graphically. Similarly, the shape control has a property that determines what kind of shape it... more 
The essential element of a graphic control is the way it paints its image on the screen. The abstract type TGraphicControl defines a method called Paint that you override to paint the image you want on your control.
The Paint method for the shape control needs to do several things:
  • Use the pen and brush selected by the user.
  • Use the selected shape.
  • Adjust coordinates so that squares and circles use the same width and height.
 
If you add classes to your component, the component's constructor must initialize them so that the user can interact with the objects at runtime. Similarly, the component's destructor must also destroy the owned objects before destroying the component itself. 
To change default property values and initialize owned classes for your component, you must override the inherited constructor and destructor. In both cases, remember always to call the inherited method in your new constructor or destructor. 
Once you derive a component type, you can decide which of the properties and events declared in the protected parts of the ancestor class you want to surface in the new component. TGraphicControl already publishes all the properties that enable the component to function as a control, so all you need to publish is the ability to respond to mouse events and handle drag-and-drop.
Publishing inherited properties and events is explained in Publishing inherited properties and Making events visible. Both processes involve redeclaring just the name of the properties in the published part of the class declaration.
For the shape... more 
By default, a canvas has a thin black pen and a solid white brush. To let developers change the pen and brush, you must provide classes for them to manipulate at design time, then copy the classes into the canvas during painting. Classes such as an auxiliary pen or brush are called owned classes because the component owns them and is responsible for creating and destroying them.
Managing owned classes requires:
  1. Declaring the class fields.
  2. Declaring the access properties.
  3. Initializing owned classes.
  4. Setting owned classes' properties.
 
The standard shape control does one more thing that your sample shape control does not yet do: it handles squares and circles as well as rectangles and ellipses. To do that, you need to write code that finds the shortest side and centers the image.
Here is a refined Paint method that adjusts for squares and ellipses:  
As the final step in handling the pen and brush classes, you need to make sure that changes in the pen and brush cause the shape control to repaint itself. Both pen and brush classes have OnChange events, so you can create a method in the shape control and point both OnChange events to it.
Add the following method to the shape control, and update the component's constructor to set the pen and brush events to the new method:  
When the read or write part of a property definition uses a method instead of directly accessing the stored property data, you need to implement the method.
Add the implementation of the SetShape method to the implementation part of the unit:  
Copyright(C) 2009 Embarcadero Technologies, Inc. All Rights Reserved.
What do you think about this topic? Send feedback!