The Grid Control intuitively describes two-dimensional information. Therefore, it has two horizontal and vertical axes and is a two-dimensional table.
1. tcustomgrid is the parent class of all grid controls. It defines the main features of grid controls and the main functions of grid controls. Here, we understand two protection levels (P
Rotected) method:
(1) Procedure paint;
All the child classes of twincontrol can draw their own shapes through painting. In tcustomgrid. Paint, two functions are implemented: Drawing grid lines and filling grid data. Where, the Network
The following figure shows how to fill the grid data. In the following content, I will explain the painting in detail with the source code.
2) Procedure drawcell (ACOl, Arow: longint; arect: trect; astate: tgriddrawstate); Virtual; abstract;
This is a pure virtual method called by painting to fill the grid data. Therefore, all tcustomgrid sub-classes can overwrite this method.
Fill mode is required.
2. tcustomdrawgrid is useless. It mainly completes two tasks:
(1) override the abstract method of tcustomgrid to implement it. Tcustomdrawgrid is no longer an abstract class.
(2) added some events.
For example, it overwrites tcustomgrid. drawcell and triggers the ondrawcell event. Therefore, we can add code to ondrawcell to change
Data and its filling method. However, it should be noted that after tcustomdrawgrid overwrites drawcell, it does not actually implement data filling (because it does not know what the data is ). Simplified draw
The cell source code is as follows:
Procedure tcustomdrawgrid. drawcell (ACOl, Arow: longint; arect: trect;
Astate: tgriddrawstate );
Begin
If assigned (fondrawcell) then
Fondrawcell (self, ACOl, Arow, arect, astate );
End;
3. tdrawgrid and tstringgrid are the classes that you can use during design, or they are all controls. However, tdrawgrid is a simple packaging of tcustomdrawgrid, so
Drawcell still simply triggers the event ondrawcell, but does not actually implement data filling. Because of this, the use of tdrawgrid is quite flexible, and we can use it to draw text
And images.
Tstringgrid is derived from tdrawgrid and is used to describe text information. From the source code below, we can see that it truly achieves data filling:
Procedure tstringgrid. drawcell (ACOl, Arow: longint; arect: trect;
Astate: tgriddrawstate );
Begin
If defadradrawing then
Canvas. textrect (arect, arect. Left + 2, arect. Top + 2, cells [ACOl, Arow]); {This sentence}
Inherited drawcell (ACOl, Arow, arect, astate );
End;
4. TDBGrid is a data-sensitive grid control. It is a simple packaging of tcustomdbgrid, while the implementation principle of tcustomdbgrid is similar to that of common grid controls, the main difference
The data source is different. For example, tstringgrid data comes from tstringgrid. cells, while tcustomdbgrid data comes from tcustomdbgrid. datasource. dataset.
Ii. Main Functions of tcustomgrid
As mentioned above, tcustomgrid defines the main functions of grid controls and has the main features of grid controls. Therefore, to understand the basic principles of grid controls, the focus is on tcustomgrid.
Two Methods: paint and drawcell.
Drawcell is a pure virtual method called in painting (for specific procedures, see the following). Therefore, the emphasis is on two aspects:
(1) What is the use of paint and how it works.
(2) what is done in paint.
1. the operating mechanism of painting.
As mentioned above, paint is used to draw the shape of the control. A specific painting method is defined inside the paint. Therefore, you only need to call the paint method at the appropriate time and place to change
View.
In VCL, the paint method can be simply understood as the tcontrol reaction to the Windows Standard Message wm_paint. Call Win32
The updatewindow, redrawwindow, invalidaterect, and repaint, refresh, and update Methods of tcontrol in VCL in the API will directly or indirectly trigger the corresponding W
M_paint message.
Therefore, the basic operating principle of the grid control is: after the data or data source itself changes, call the paint method in an appropriate way to update the data filling. Take tstringgrid
For example, after the data of cells is changed:
Procedure tstringgrid. setcells (ACOl, Arow: integer; const value: string );
Begin
Tstringgridstrings (ensuredatarow (Arow) [ACOl]: = value;
Ensurecolrow (ACOl, true );
Ensurecolrow (Arow, false );
Update (ACOl, Arow); {invalidaterect mark [ACOl,
Arow] indicates that the region needs to be re-painted. The system then sends a wm_paint message. Finally, the painting is executed .}
End;
2. Paint does the work. Let's take a look at the simplified source code to make it clearer. Take"★"For each function part division mark:
Procedure tcustomgrid. paint;
Procedure drawlines (dohorz, dovert: Boolean; Col, row: longint;
Const cellbounds: array of integer; oncolor, offcolor: tcolor );
Begin
{......}
End;
Procedure drawcells (ACOl, Arow: longint; startx, starty, stopx, stopy: integer; color: tcolor; includedrawstate:
Tgriddrawstate );
Begin
{......}
{The pure virtual method drawcell of tcustomgrid is called.
Therefore, the subclass of tcustomgrid can overwrite this method and customize the data filling mode}
Drawcell (curcol, currow, where, drawstate );
{......}
End;
Begin
{★0: Calculation of network drawing parameters}
Calcdrawinfo (drawinfo );
With drawinfo do
Begin
{★1: Draw grid lines (if the line width is greater than 0 )}
If (horz. effectivelinewidth> 0) or (Vert. effectivelinewidth> 0) then
Begin
{Fixed column in the upper left corner}
Drawlines (gofixedhorzline in options, gofixedvertline in options, 0, 0, [0, 0, horz. fixedboundary,
Vert. fixedboundary], clblack, fixedcolor );
{Horizontal fixed column}
Drawlines (gofixedhorzline in options, gofixedvertline in options, leftcol, 0, [horz. fixedboundary, 0,
Horz. gridboundary, Vert. fixedboundary], clblack, fixedcolor );
{Vertical fixed column}
Drawlines (gofixedhorzline in options, gofixedvertline in options, 0, toprow, [0, Vert. fixedboundary,
Horz. fixedboundary, Vert. gridboundary], clblack, fixedcolor );
{Non-fixed column}
Drawlines (gohorzline in options, govertline in options, leftcol, toprow, [horz. fixedboundary, Vert. fixedboundary,
??? Horz. gridboundary, Vert. gridboundary], linecolor, color );
End;
{★2: Fill in data}
{Fixed column in the upper left corner}
Drawcells (0, 0, 0, 0, horz. fixedboundary, Vert. fixedboundary ,??? Fixedcolor, [gdfixed]);
{Horizontal fixed column}
Drawcells (leftcol, 0, horz. fixedboundary-fcoloffset, 0 ,??? Horz. gridboundary, Vert. fixedboundary, fixedcolor,
[Gdfixed]);
{Vertical fixed column}
Drawcells (0, toprow, 0, Vert. fixedboundary, horz. fixedboundary ,? Vert. gridboundary, fixedcolor, [gdfixed]);
{Non-fixed column}
Drawcells (leftcol, toprow, horz. fixedboundary-fcoloffset, Vert. fixedboundary, horz. gridboundary, Vert. gridboundary,
Color, []);
{★3: draw an external box for the selected grid}
Canvas. drawfocusrect (focrect );
{★4: Fill in areas not occupied by grids in the customer zone}
{Horizontal part}
If horz. gridboundary Begin
Canvas. Brush. Color: = color;
Canvas. fillrect (rect (horz. gridboundary, 0, horz. gridextent ,??? Vert. gridboundary ));
End;
{Vertical part}
If Vert. gridboundary <Vert. gridextent then
Begin
Canvas. Brush. Color: = color;
Canvas. fillrect (rect (0, Vert. gridboundary, horz. gridextent, Vert. gridextent ));
End;
End;
End;
From the code above, tcustomgrid. Paint can be divided into five parts. Where★0 is used to calculate the current drawing parameter, and the result is used for the last four parts. In the next four parts,★1
And★2 is the subject. Therefore, our focus is on★0,★1 and★2.★1 and★2. There are detailed annotations, so I will not explain them on a line-by-line basis. If you are interested but cannot understand them, you can think about them slowly. Last pair★0
.
Drawinfo is of the tgriddrawinfo type and is defined as follows:
Tgriddrawinfo = record {network drawing parameters}
Horz, vert: tgridaxisdrawinfo; {divided into two parts: horizontal and vertical}
End;
The following uses a horizontal method as an example to explain the meaning of tgridaxisdrawinfo:
Tgridaxisdrawinfo = record
Effectivelinewidth: integer; {grid width}
Fixedboundary: integer; {Fixed Grid column width (including grid lines )}
Gridboundary: integer; {total width of each grid column (including gridlines and fixed columns )}
Gridextent: integer; {total width of the mesh customer zone}
Lastfullvisiblecell: longint; {the last column that has not exceeded the customer zone (that is, all can be seen}
Fullvisboundary: integer; {The total width (including grid lines) of all the currently visible columns )}
Fixedcellcount: integer; {number of fixed columns}
Firstgridcell: integer; {The first unfixed column, that is, leftcol (horizontal) or toprow (vertical )}
Gridcellcount: integer; {colcount, total number of columns}
Getextent: tgetextentsfunc; {a function used to obtain the column width, equivalent to colwidths [Index]}
End;