One. How to use tree control in Delphi
We all know that developers mainly use Delphi to develop database management software, because of this,
The use of tree controls is best linked to the database. Delphi provides a tree control
TtreeView can be used to describe complex hierarchical relationships.
1. Storage and loading of tree node information
The common method is to realize the tree with a LoadFromFile and SaveTofile method of tree control.
Interaction between controls and files; or use ASSIGN methods to implement tree controls and dbmemo, that is,
According to the interaction between the library. The advantage of this method is that the programming is relatively simple, and the disadvantage is that the number of actual nodes of tree controls
May be large, for "big trees", each loaded and stored data will increase, will reduce the speed
Increase system overhead, resulting in data redundancy. Another method is that only on the tree "can see
"The node does not specifically record files or database fields of all tree node structures, and the tree node
The structure is dispersed in each record of the database.
The specific method is: Create a database, the field is determined according to the actual business, which must have one
The information of the field will be displayed on the node of the tree control, and another field is to save the node.
The only identification number, the identification number consists of two parts: the length, the front section represents the parent of the current node
Dot number, the later period indicates the node number of the current node, this identification number is equivalent to a "linked list", recorded
The structure of the node on the tree. The advantage of this method: When the user operates "big tree", it generally does not expand all
The node, but only one part of the limited part, and can only be launched from the root layer, the law only
Generate a "visible" node on the tree, so the speed of "big tree" is stored and loaded.
Small size, system overhead and data redundancy are small. Disadvantages: more complicated programming, but can be combined with this method
A new tree control will greatly improve programming efficiency. It is worth noting that the ID number must be unique.
So how to generate IDs reasonably in the programming.
2. Database Structure Example
Create a database for simplified programs, I only create two database fields, defined as follows:
Field name type length
TEXT C 10
Longid C 6
The longID field is actually composed of two sections, each 3 digits, longid can only represent 1000 collections
record. Define LongID as an index field, saving C: ESTTREE Ree.dbf. Edit the DBF text
Parts, new records, Text fields are set to top, the longid field is set to "000" (3 "0"
Before three spaces).
3. Create a demo program
Place TreeView1, Table1, PopupMenu1, Edit1, and Edit2 on Form1.
TreeView1's PopupMenu property is set to PopupMenu1; Table1's DatabaseName Properties
For c: ESTTREE, TABLENAME attribute is set to Tree.dbf, the indexfieldnames property is set to
LONGID; with PopupMenu1, the single add1 and del1, CAPTION is Add and DEL;
Edit1 is used to enter the new node's text attribute value, and edit2 is used to enter the 3-bit ID number of the new node. Save
For C: Esttree ReeUnit.PAS and C: Esttree Esttree.dpr.
Add a line after the Type keyword of TreeUnit.PAS: PSTR: ^ string; {pstr is a character
String pointer}
Add code for Form1 oncreate event: Procedure TFORM1.FormCreate (Sender: TOBJECT); VAR P: PSTR; Node: ttreenode; begin with table1, treeview1 do begin open; first; new (p); {Pointer P assigning memory} p ^: = FieldByName ( 'LongID') AsString; Node:. = Items.AddChildObject (. nil, FieldByName ( 'Text') AsString, p); if HasSubInDbf (Node) then Items.AddChildObject (Node, ''
, NIL); {has a child node plus an empty node} end;
Hassubindbf is a custom function, the argument is Node, checks the node Node has no child node
If you return true, it returns to false and adds a prototype declaration in the class definition of TForm1.
Its custom function is also declared in the class definition of TForm1, and does not interpret it), function code
as follows:
Function TFORM1.HASSUBINDBF (Node: Ttreenode): boolean; begin with table1 do beg, table1.findnearest ([copy (pstr (node.data) ^, 4, 3) '000']); Result: = COPY (Fieldbyname 'Longid'
) .Sstring, 1, 3) = copy (pstr (node.data) ^, 4, 3); {, such as the current record in the database
The last 3 digits of the longid field content is the same, the Node should have subjunction.
End; end;
Add a code to the TreeView1 control overdeeletion event, it is necessary to point out, not only adjust
Use the delete method to trigger an OONELETION event, and it is also true that the tree control itself is released.
Send an OnDeleTion event, so adding dispose (node.data) here will be "secure":
Procedure TFORM1.TREEVIEW1DELETON (Sender: Tobject; Node:
TTREENODE);
Begin Dispose (Node.Data); {Release Node Data Memory} END; Add code to the ADD1 monitable OnClick event as follows: procedure tform1.add1click (sender: TOBJECT); var P: pstr; tmpstr: string; i: integer; Begin try strt (edit2.text); tmpstr: = edit2.text; {Note: In practical, you must use a better way to generate id} ExcePt; showMessage ('re-entering edit2 content'); WITH TREEVIEW1 Do Begin New (P); P ^: = COPY (PSTR (SELECTED.DATA) ^, 4, 3) Tmpstr; items.addchildObject (SELECTED, EDIT1.TEXT, P); End; with table1 do { Database Add Record} Begin Append; FieldByname ('Text'). Asstring: = Edit1.Text; FieldByName ('longid'). Asstring: = p ^; post; end; tmpstr: = INTOSTR (STRTOINT (TMPSTR) 1 ); For i: = length (tmpstr) to 2 do tmpswstr: = '0' tmpstr; edit2.text: = tmpstr; end; adding code for the DEL1 menu item is as follows: Procedure TFORM1.DEL1Click (Sender: Tobject VAR Dellist: tstringlist; longid, nsublongid: string; begin dellist: = TSTRINGLIST.CREATE; Dellist.Sorted: = true; dellist.add (pstr (TreeView1.Selected.Data) ^; while dellist.count> 0 do Begin Longid: = Dellist.Strings [0]; Dellist.delete (0); Table1.SetKey; T able1.FieldByName ( 'LongID') AsString:. = LongID; if Table1.GotoKey then Table1.Delete; if HasSubInDbf (TreeView1.Selected) then begin NSubLongID:. = Table1.FieldByName ( 'LongID') AsString; while (copy ( NSUBLONGID, 1, 3) = COPY (LongID, 4, 3)) AND (NSUBLONGID); table1.next; nsublongID: = Table1.fieldByName ('longid'). Asstring; end; end; End; end; dellist.free; TreeView1.items.delete (TreeView1.selected); end; add code for TreeView1 onExpanding event: Procedure TFORM1.TREEVIEW1EXPANDING (Sender: Tobject; Node:
TTreeNode; var AllowExpansion: Boolean); var TmpNode: TTreeNode; NSubLongID: String; p: Pstr; bm:. TBookMark; begin with Table1, TreeView1 do begin Items.BeginUpdate; SetKey; FieldByName ( 'LongID') AsString: = Pstr ( Node.Data) ^; if not GotoKey then Items.Delete (Node) else begin TmpNode: = Node.GetFirstChild; if (TmpNode.Text = '') and (TmpNode.Data = nil) then begin TmpNode.Delete; if HasSubInDbf (Node) The begin nSUBLONGID: = FIELDBYNAME ('longid'). Asstring; while (copy (nsublongid, 1, 3) = copy (pstr (node.data) ^, 4, 3)) And (Noteof) DO Begin New (p); p ^: = FIELDBYNAME ('longid'). Asstring; bm: = getBookmark; tmpnode: = items.addchildObject (node, fieldbyname ('text'
) .Sstring, p); if Hassubindbf (TmpNode) Then Items.AddchildObject (tmpnode, '
', Nil); FreeBookmark (BM); next; nsublongid: = fieldByName (' longid '). Asstring; end; end; end; end; item; items.Endupdate; end; end;
The above briefly talks about the basic method of the tree display of the database, in addition, editing the node on the tree
The text attribute is modified while the database is used, and the same database is operated at the same time in multiple users.
As well as the consistency of the tree, the copy and replication of the nodes on the tree will not repeat it, readers can improve themselves.
II. IP control
In the network program, we often encounter the case where you need the user to enter the IP address. However, Delphi
There is no control that can be used to enter IP strings so that we have to use TEDIT controls (single
The line text box is to accept the IP string input by the user. However, using TEDIT to enter IP strings is not one
Good idea, because it is very inconvenient to process. In fact, there is a special use to lose
Enter the Windows control of the IP string. IP controls will reject illegal IP strings (only can only be entered each part)
0..255 between the numbers); it allows you to easily get the IP value corresponding to the IP string in the control (32
Bit integers), which saves the trouble between IP strings and IP values; in addition, you can limit IP
The range of IP that can be entered in the control. This section introduces you how to make it in our Delphi program
Use Windows IP controls.
Two very important dynamic linkages in Windows: CommCtrl.dll and
ComctL32.dll, they are Windows Custom Control Libraries (Windows Common Controls)
. The custom control library contains many common Windows controls, such as Statusbar, Coolbar
, HotKey et al; in Delphi, most of these controls have been packaged into visual controls. in
After Microsoft launches Internet Explorer 3, some controls have been added to the custom control library
The IP Address Edit Control is included in this. 1. Initialize Windows Custom Control Library
Windows provides two API functions, initcommoncontrols, and
INITCOMMONCONTROLSEX is used to initialize custom control libraries. From the name, we are not difficult to see this
The relationship between the two API functions: The latter is the enhancement of the former. If you want to use IP controls in the program
You must use INITCOMMONCONTROLSEX to complete the initialization of custom control libraries and classes.
The prototype of the function initcommonControlsex is as follows (Pascal syntax):
...
Create an IP control
...
Use IP controls. In the program, we communicate with it by sending messages to the IP control. IP
There are 6 messages that the control can respond, these messages and their meaning are shown in the table:
...
To get the IP value corresponding to the IP string in the IP control, you should send the IP control
IPM_GetadDress message, and need to put a 32-bit integer as sendMessage
The last parameter.
...
2. Notification message for IP control
When the IP string is changed or the input focus occurs, the IP control will send it to its parent window.
Send a notification message ipn_fieldchanged. In most cases, we can ignore this notice.
interest. The following is an example of the processing notification message IPN_FIELDCHANGED:
Procedure TFORM1.WndProc (var Msg: tMESSAG); VAR P: PNMHDR; begin inherited; if msg.msg = WM_NOTIFY THEN BEGIN P: = POINTER (msg.lparam); if P ^ .code = ipn_fieldchanged the beginning {... Processing IP The IPN_FIELDCHANGED notification message of the control ...} end; end;
3. Method and application of dynamically generated control
1. Two methods of generating controls in Delphi
(1). Form (form) generated control
When designing the Form design, select the desired control directly in the control toolbox, then set its properties and
Response events, this method is more common.
(2). Dynamic generation controls in the program
Sometimes, we need to dynamically generate controls during the program run, so there are two advantages: one
It is possible to increase the flexibility of the program; the second is if the generated control is in the middle of the program
Off, it is clear that the method is unable to implement, and the method must be dynamically generated in the program.
The method of dynamically generating controls in the program is divided into three steps, first, define the type of control generated, and then
Use the CREATE function to generate a control, and finalize the relevant attributes of the control. Take the TBUTTON control as an example
,Proceed as follows:
a. Define the type of control
VAR
Button1: tbutton;
b. Generate controls
Button1: = TButton. Create (Self);
Button1.parent: = Self;
File: // Generally set its parent control to Self, if the value of the Parent is not set,
The control will not be on the screen
File: // Show out
c. Set other properties and definition related event response functions, such as
Caption, Left, Top, Height, Width, Visible, Enabled, Hint, and onclick event
Compact function, etc.
2. Application of Dynamic Generation Control Method
In the development of production scheduling and management systems, it is necessary to dynamically generate an exclusive production plan, with a Gantt chart
Show the SHAPE control to display the machining status of the part (the processing start time and end time of each process) are very suitable. Apply a CHART control to display the processing equipment utilization
It is very intuitive. Now, the process of dynamically generating the Shape control and the Chart control in the program, respectively.
Description.
(1). Dynamic Generate Shape Control Shows Excunization Plan (Gantti)
procedure TCreateMultiCharts.ProcCreateCharts; var i, j, Rows, Columns, RowSpace, ChartsHeight: Integer; ShapeChart: array of array of TShape; begin Rows: = 16; file: // Shape Control Array Rows Columns: = 8; // Shape control array column number rowspace: = 20; // Shape control row spacing chartsheight: = 20; // Shape control height setLength (ShapeChart, rows, columns); file: // Set ShapeChart array size for i: = 0 to rows Do for j: = 0 to color [i] [j]: = tshape.create (self); with shapechart [i, j] do begin parent: = self; file: // This trip is essential, Otherwise, the Shape Control does not display shape: = strectangle; // shape control shape is rectangular TOP: = 45 i * (ROWSPACE ChartsHeight); Left: = Round (180 q [i, j] .starttime); File: // Because q [i, j] .starttime is the real number, it is necessary to make a four-bedding width: = ROUND (q [q [i, j] .value) Height: = chartsheight; brush.color: = randomcolor; file: / / Custom function, after the attached brush.style =bssolid; file: // Set the fill method enabled: = true; end; end; end; Note: AQ is a recorded two-dimensional array, defined as follows: Type Tempdata = Record Value: Real; StartTime: Real; End; Q: Array Of Array of Tempdata and assigns the component of Q in another process. B. For different parts, Shape is displayed in different colors, at this time, the function is called
Randomcolor. This function is: Function Tcreatemulticharts.randomcolor; Var Red, Green, Blue: Byte; Begin Red: = Random (255); Green: = Random (255); Blue: = Random (255); Result: = Rand OR (Green shl 8) or (blue shl 16); end; (2) generates a dynamic control ChartSeries assembly Charts showing utilization procedure TFormMultiMachinesBurthen ShowMachineBurthenCharts; var i:.. Integer; Burthen: Real; SeriesClass: TChartSeriesClass; NewSeries: array of TChartSeries; begin SetLength (NewSeries, CreateMultiCharts.Rows); MachinesBurthenCharts.height: = 200; MachinesBurthenCharts.Width: = 550; for i: = 0 to CreateMultiCharts.Rows do begin SeriesClass: = TBarSeries; file: // set a three-dimensional shape Bar chart newseries [i]: = seriesclass.create (self); newseries [i] .parentchart: = machinesburthenCharts; newseries [i] .clear; burthen: = machineburthen [i]; burthen: = round (burthen * 100) / 100; File: // Take the two digits after the decimal point NEWSERIES [i] .add (Burthen, ', newseries [i] .seriescolor); end; end; Note: (a) .Machineburthen [i] is true Type array, its value is the utilization of the corresponding device,
Calculated in another function;
(b). MachinesburthenCharts is a TCHART control, in the TYPE segment.
3. Program operation results display
(1). Dynamically generate Shape controls, display parts exclusive production plan (omitted)
(2). Dynamically generate ChartSeries components of Chart control, display device utilization (omitted)