About the writing of VCL (1) How to write your own VCL control

xiaoxiao2021-03-06  56

How to write your own VCL control

Friends who have used Delphi, probably to Delphi's favorite Delphi is not his strong type of Pascal syntax, but a powerful VCL control, I am a fan of a VCL control.

The Open Source of the VCL control has brought us an endless benefit. Unlike the previous OLE controls and ActiveX, you can override the Delphhi standard control, and there are many resources on the Internet.

About how to write VCL controls, and more Delphi books, in this simple explanation.

In Delphi, Tcomponent is the basis of all VCL components. Write a non-visible component to derive from Tcomponent. Delphi provides a number of basic component types specifically for making controls (visual components), which are derived from TControl and TwinControl. Its derived relationship is as follows:

Tcontrol --- TgraphicControl --- TcustomLabel

TwinControl - TCUSTOMCONTROL --- TCUSTOMGRID

--- TButtonControl - TCUSTOMGROUPBOX

--- TscrollingWinControl - TCUSTompanel

--- TCustomComboBox

--- tcustomedit

--- TCUSTOMLISTBOX

TControl's subtype is used for non-window controls, and the Subtype of TwinControl is used for window controls. Unless special needs, new controls are generally not derived from TControl and TwinControl, but derive from their subtypes. This makes it possible to reduce the original attributes, events, and methods to reduce a lot of workload.

Write controls, first select the appropriate VCL object type as a parent object to derive new objects.

A specific example is given below to implement a enhanced Edit input box, which is that he can effectively determine the input character based on the input data type, adding a left alignment similar to TLABEL, aligned, right alignment.

Inheriting from TEDIT to generate its own control from TEDIT through Delphi's component wizard:

TeditDataType = (DTPSTRING, DTPINTEGER, DTPFLOAT); // Input Data Type

TMYEDIT = Class (TEDIT)

Private

FALIGNMENT: TALIGNMENT;

FDATYPE: TEDITDATATYPE;

FPRECISION: Integer;

Procedure setAlignment (const value: talignment); ?? // to set alignment methods

Procedure setPrecision (const value: integer); ????????????

Procedure setDataType (Const Value: TeditDataType);

Function getasfloat: Double;

Function Getasinteger: Integer;

Procedure setAsfloat (Const value: double);

Procedure setasinteger (Const value: integer);

Function Getastext: string;

Procedure setastext (const value: string);

ProtectedProcedure CMEXIT (VAR Message: Tcmexit); Message Cm_exit; // Rewind message, the next article will detail the message

Procedure KeyPress (VAR Key: Char); override; // Rewrive the keyboard button event, used to control the keyboard input

public

Constructor Create (Aowner: Tcomponent); OVERRIDE;

Procedure createparams (var params: tcreateparams); override; // rewrite, implementation

Property Alignment: Talignment Read Falignment Write setAlignment Default

TaleftJustify; // Alignment

Property DataType: TeditDataType Read FDATYPE WRITETDATATYPE DEFAULT

DTPSTRING; // Set the input data type

Published

Property Precision: Integer Read FPRISION WRITETPRECISION; // Decimal point Active Bits Property Asfloat: Double Read GetAsfloat Write SetAsfloat; //? Increase the same type of conversion function similar to C , do not have to call function conversion each time

Property Asinteger: Integer Read Getasinteger Write Setasinteger;

Property Asstring: String Read atkext Write Setastext;

END;

// Let's take a function of implementing what we want to implement.

The first implementation left pair must rewrite the createParams function, and the implementation is as follows:

Procedure Tmyedit.createParams (Var params: tcreateparams);

Const

Alignments: Array [Boolean, TALIGNMENT] OF DWORD =

((SS_LEFT, SS_RIGHT, SS_CENTER), (SS_RIGHT, SS_LEFT, SS_CENTER);

Begin

Inherited Createparams (params);

CreateSubclass (params, 'edit');

With params do

Begin

STYLE: = Style or ss_notify or

Alignments [UserightToleftalignment, Falignment];

END;

END;

// Set alignment

Procedure TMYDIT.SETALIGNMENT (Const value: TALIGNMENT);

Begin

IF falignment <> Value Then

Begin

FALIGNMENT: = Value;

RereateWnd; // Heavy painting control

END;

END;

Rewote the keypress event based on the set data type

Procedure tlscustomedit.KeyPress (VAR Key: char);

Begin

Case fdattype of

DTPINTEGER: // If it is an integer

Begin

IF not (key in ['0' .. '9', '-', # 8, # 13, # 35, # 39]) THEN

Key: = # 0;

IF (key = '-') and ((POS ('-', text)> 0) or (SELSTART <> 0)) THENKEY: = # 0;

END;

DTPFLOAT: // If it is a bit number

Begin

IF not (key in ['0' .. '9', '.', '-', # 8, # 13, # 35, # 36, # 37, # 39]) THEN

Key: = # 0;

IF (Key = '.') and (POS ('.', text)> 0) THEN

Key: = # 0;

IF (key = '-') and (('-', text)> 0) or (SELSTART <> 0)) THEN

Key: = # 0;

end

END;

Inherited KeyPress (key); // Call the keypress method of the parent class

END;

No. now, this control is almost.

About the writing of simple controls, generally only need to inherit from Delphi for your basic component type, then rewrite some methods of the parent class, add some methods, and attributes, you can also write Delphi Out of some abstract components, such as the above TMYEDIT, you can write a basic TCUSTOMMYEDIT then, from him, guide out more controls. It is abstract. Here, the idea of ​​the OOP you can have a big show. Habular, basic component type, no Published.

When making a component, there is a lot of classes and many properties and methods, where there are some important and relatively common class and its properties and methods.

Tcomponent

The ComponentState property, the status of the flag component, such as editing, transfer, reading, etc. It can be based on the status to determine what the current components should do;

Notification method: When a component is deleted, this method is notified of all components (in addition to the one of the deleted or added). This method has two parameters: Acomponent, Operation. Which component is now operated in which a component is made now. When using, override the Notification method in the new component, you can write the code to receive the notification in the Notification method; do some container controls, controls, such as the DB component is useful. Otherwise, you will delete it There is an address error.

Loaded method: This method is called when a component is loaded. Like the Notification method, in use, cover the loaded method in the new component, and then write the code to be loaded on the loaded method;

Updating method: When a component is being changed, it is called;

Updated method: When the component changes, it is called.

TGRAPHICCONTROL

Canvas Attributes: Canvas, the properties of the graphics components;

Left, Top, Width, Height Attribute: The size displayed in the parent component;

ControlState attribute: Control status, such as the mouse button, whether to accept the palette change information, whether the focus is accepted;

ControlStyle Attribute: Control type, if it is transparent, there is a 3D frame, etc.; Paint method: This method is called after accepting the WM_PAINT message, drawing yourself;

The preliminary study of VCL is generally easier, like any computer language, when you need more deeper, progress is slower, and what you need is more and more. Write some difficulties in the Writing of VCLs One 2: One is a system message a few Windows APIs. You need to write a complicated control, you need to be familiar with the system message. The other is the attribute editor and the writing of the component editor. Don't look at the VCL in Delphi, but not all, you want to find some reference value, it is difficult to find some reference value. I will discuss slowly, readers in the next chapter.

转载请注明原文地址:https://www.9cbs.com/read-116735.html

New Post(0)