Shape in the VCL is a very good control, you can choose several graphics to meet our needs, but sometimes it feels less than a few pictures, such as we want a triangle, but there is no. So I thought of extending this control, named Shapeex. In fact, there are not many features, just add some graphics. The class is not inherited from TSHAPE, but inherits from TGRAPHICCONTROL, so that we can completely look at the pattern of graphic controls. Tshape is also inherited from TGRAPHICCONTROL. And our extension control function is based on Shape extension, so of course the code inside is almost tshape, just add some code of extended graphics, but what is the relationship, VCL source is the best learning resources, why not take Use it.
Many things we have already said above, not much here, I have to go straight into the focus of the graphic control. The graphic control is not a control of Windows, but Delphi draws himself, then it must have a function of drawing controls. This function is:
Paint;
Look at the VCL source code, you can know that it is defined in TGRAPHICCONTROL. in:
PROCEDURE PAINT; Virtual;
This is a virtual function, then what is its implementation? Click on its implementation as follows:
Procedure TgraphicControl.Paint;
Begin
END;
There is no code inside, this is easy to understand because it is impossible to know what the graphic of his subclass is like. So set to virtual functions, by its subclass to overwrite it.
So who calls this function to cause painting controls. Windows has a WM_Paint; message, when all causes the condition of the heavy painting, this message will be sent, then look at TGRAPHICCONTROL, and there is intercepted this message:
Procedure WmPaint (Var Message: twmPaint); Message WM_Paint;
In the processing function, call the PAINT method to implement the drawing graphic control:
Procedure TgraphicControl.wmpaint (var message: twmpaint);
Begin
IF message.dc <> 0 THEN
Begin
Canvas.lock;
Try
Canvas.handle: = message.dc;
Try
Paint; // Call this function to draw graphics controls
Finally
Canvas.Handle: = 0;
END;
Finally
Canvas.unlock;
END;
END;
END;
And its subclass covers the Paint function, so the message processing function call is actually a Paint method for a subclass. This is a polymorphic application, not much here.
Since the Paint function can draw a graphic control, then what is drawn, VCL has a Canvas class, which is painted in TGRAPHICCONTROL, and it defines this member:
Fcanvas: Tcanvas;
Property Canvas: Tcanvas Read Fcanvas;
It can be seen that this is a read-only member, because it does not want to be external to affect him.
Ok, everything is already there, you can draw it now. The source code is explained in detail, and there is not much to say here.
There are two object properties in Shapeex, which is PEN and BrUSH. Corresponding to his two object members. After setting up these two properties, you can expand them in the object viewer to set their properties. This is also a general usual usage of object properties.
It seems that there is nothing to say, look at the source code, which also have a very detailed description:
Unit shapeexunit;
Interface
Uses
Sysutils, Classes, Graphics, Controls, Extctrls
Type
// Define several shapes: rectangular, square, rounded rectangle, rounded square, oval, circular,
// Added graphics: horizontal line, standing, upper triangle, rhombus
TshapeType = (Strectangle, Stsquare, StroundRect, Stroundsquare,
Stellipse, Stcircle, Sthline, Stvline, Starle, stdiamond;
Tshapeex = Class (TGRAPHICCONTROL)
Private
FPEN: TPEN;
Fbrush: TBRUSH;
Fshape: Tshapety;
Procedure setbrush (Value: TBrush);
Procedure setpen (Value: tpers);
Procedure setshape (value: tshapetype);
protected
// The most important function, one defined in the parent TGRAPHICCONTROL
// virtual functions, when you get a WM_PAINT message, call this function causes heavy painting
// The parent class is an empty function so that the subclass of TGRAPHICCONTROL is covered.
proca;
public
Constructor Create (Aowner: Tcomponent); OVERRIDE;
DESTRUCTOR DESTROY; OVERRIDE;
Published
// This function causes heavy painting when the brush and the painting brush in the graphic, the most obvious in the designer
Procedure StyleChanged (Sender: TOBJECT);
Property Align;
Property anchors;
Property Brush: Tbrush Read Fbrush Write setBrush
Property Dragcursor;
Property Dragkind;
Property Dragmode;
Property enabled;
Property ConsTraints;
Property Parentshowhint;
Property Pen: TPEN Read Fpen Write Setpen;
Property Shape: TshapeType Read Fshape Write Setshape Default StRectangle;
Property Showhint;
Property visible;
Property OnContextPopup;
Property OnDragDrop;
Property OnDragover;
Property OneundDock;
Property Oneenddrag;
Property OnMouseDown;
Property OnMouseMove;
Property OnMouseup;
Property onstartdock;
Property onstartdrag;
END;
IMPLEMentation
// Constructor, ControlStyle determines the characteristics of the control, here is CSReplicatable
/ / Make the control with the Paintto method to draw it into an arbitrary canvas
/ / The method pointer to the onchange event of the PEN and Brush objects is also specified to stop.
Constructor Tshapeex.create (Aowner: Tcomponent); Begin
Inherited Create (Aowner);
ControlStyle: = ControlStyle [csreplicatable];
Width: = 65;
HEIGHT: = 65;
FPEN: = TPEN.CREATE;
Fpen.onChange: = STYLECHANGED;
Fbrush: = TBrush.create;
FBRUSH.ONCHANGE: = STYLECHANGED;
END;
DESTRUCTOR TSHAPEEX.DESTROY;
Begin
FPEN.FREE;
FBRUSH.FREE;
Inherited destroy;
END;
// The most important function, the control is drawn in this function.
Procedure tshapeex.paint;
VAR
// x: Left upper corner X, Y: left upper corner Y, W: Width, Y: High S: Wide high medium value
X, y, w, h, s: integer;
Begin
// canvas is the properties of parent TGRAPHICCONTROL for painting controls
// Before the drawing, some coordinate points should be made,
With Canvas Do
Begin
// If you draw a graphic in four corners of the control, when Pen is too large, the edge of the graphic
// will be small than the PEN's width, so the relocation is required.
Pen: = fput;
Brush: = fbrush;
X: = pen.width Div 2;
Y: = x;
W: = Width - Pen.Width 1;
H: = Height - Pen.width 1;
//Pen.width is 0 and is equal to one pixel
// If the pen.width is equal to 1, the width of the graph is just equal to the aspect of the control.
// If it is 0, the graphic width is greater than a pixel of the control width, so there is the following statement.
IF pen.width = 0 THEN
Begin
Dec (w);
Dec (h);
END;
IF W // When the graph is a graphic graphic, you need to adjust the location of the graphic. IF fshape in [stsquare, stroundsquare, stcircle] THEN Begin INC (X, (W - S) DIV 2); INC (Y, (H - S) DIV 2); W: = S; H: = S; END; Case fshape of STRECTANGLE, STSQUARE: Rectangle (x, y, x w, y h); StroundRect, Stroundsquare: RoundRect (X, Y, X W, Y H, S DIV 4, S DIV 4); Stirci, Stellipse: Ellipse (x, y, x w, y h); // The following is an increased portion. Sthline: Begin MoveTo (X, Height Div 2); LINETO (X W, Height Div 2); END; STVLINE: Begin MoveTo (Width Div 2, Y); LINETO (Width Div 2, Y H); END; Starle: Polygon ([Point (x, y h-1), Point (x W-1, Y H-1), Point (Width Div 2, Y)]); stdiamond: Polygon ([Point (Width Div 2, Y), Point (X, Height Div 2), Point (Width Div 2, Y H-1), Point (x W-1, Height Div 2)]); END; END; END; // invalidate This function will make the system send WM_Paint to TgraphicControl // TGRAPHICCONTROL's handler will call Paint, and its subclasses covers it. // So actually calls ShapeEx's Paint function, thus achieving the effect of heavy painting Procedure tshapeex.styleChanged (Sender: TOBJECT); Begin INVALIDATE; END; Procedure Tshapeex.setbrush (Value: TBRUSH); Begin Fbrush.Assign (Value); END; Procedure Tshapeex.setpen (Value: tpers); Begin Fput.assign (value); END; // Set the graphics, causing heavy draw to achieve graphical changes, / / The most obvious effect is the change seen when changing the Shape property when the designer changes. Procedure Tshapeex.setshape (Value: Tshapety); Begin IF fshape <> value kil Begin Fshape: = value; INVALIDATE; END; END; End. Methods of installations have been said in the previous chapter, not much here. This time I know the probably practicing of the graphic control, but it is nothing more than covering Paint to paint your graphic control, and others, the same as our last chapter. In fact, it is also very simple. The above two controls are relatively simple, but have explained the concepts and techniques of many components production, they can't see you, I have no way. There is a useful tip to see more VCL source code, you will learn more. Next, you should have a difficult one. Want to know what is, and listen to the decomposition.