1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
|
unit Main;
{$MODE Delphi}
{.$define DEBUG_VTV}
// Demonstration project for TVirtualStringTree to generally show how to get started.
// Written by Mike Lischke.
interface
uses
{$ifdef DEBUG_VTV}
vtlogger, ipcchannel,
{$endif}
LCLIntf, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
Laz.VirtualTrees, StdCtrls, ExtCtrls, LResources, Buttons;
type
{ TMainForm }
TMainForm = class(TForm)
VST: TLazVirtualStringTree;
ClearButton: TButton;
AddOneButton: TButton;
Edit1: TEdit;
Button1: TButton;
Label1: TLabel;
CloseButton: TButton;
procedure FormCreate(Sender: TObject);
procedure ClearButtonClick(Sender: TObject);
procedure AddButtonClick(Sender: TObject);
procedure VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; {%H-}Column: TColumnIndex; {%H-}TextType: TVSTTextType;
var Text: String);
procedure VSTFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode);
procedure VSTInitNode(Sender: TBaseVirtualTree; {%H-}ParentNode, Node: PVirtualNode;
var {%H-}InitialStates: TVirtualNodeInitStates);
procedure CloseButtonClick(Sender: TObject);
end;
var
MainForm: TMainForm;
//----------------------------------------------------------------------------------------------------------------------
implementation
{$R *.lfm}
type
// This is a very simple record we use to store data in the nodes.
// Since the application is responsible to manage all data including the node's caption
// this record can be considered as minimal requirement in all VT applications.
// Extend it to whatever your application needs.
PMyRec = ^TMyRec;
TMyRec = record
Caption: String;
end;
//----------------------------------------------------------------------------------------------------------------------
procedure TMainForm.FormCreate(Sender: TObject);
begin
{$ifdef DEBUG_VTV}
Logger.ActiveClasses:=[];//[lcScroll,lcPaint];
Logger.Channels.Add(TIPCChannel.Create);
Logger.Clear;
Logger.MaxStackCount:=10;
{$endif}
// Let the tree know how much data space we need.
VST.NodeDataSize := SizeOf(TMyRec);
// Set an initial number of nodes.
VST.RootNodeCount := 20;
end;
//----------------------------------------------------------------------------------------------------------------------
procedure TMainForm.ClearButtonClick(Sender: TObject);
var
Start: Cardinal;
begin
Screen.Cursor := crHourGlass;
try
Start := GetTickCount64;
VST.Clear;
Label1.Caption := Format('Last operation duration: %d ms', [GetTickCount64 - Start]);
finally
Screen.Cursor := crDefault;
end;
end;
//----------------------------------------------------------------------------------------------------------------------
procedure TMainForm.AddButtonClick(Sender: TObject);
var
Count: Cardinal;
Start: Cardinal;
begin
// Add some nodes to the treeview.
Screen.Cursor := crHourGlass;
with VST do
try
Start := GetTickCount64;
case (Sender as TButton).Tag of
0: // add to root
begin
Count := StrToInt(Edit1.Text);
RootNodeCount := RootNodeCount + Count;
end;
1: // add as child
if Assigned(FocusedNode) then
begin
Count := StrToInt(Edit1.Text);
ChildCount[FocusedNode] := ChildCount[FocusedNode] + Count;
Expanded[FocusedNode] := True;
InvalidateToBottom(FocusedNode);
end;
end;
Label1.Caption := Format('Last operation duration: %d ms', [GetTickCount64 - Start]);
finally
Screen.Cursor := crDefault;
end;
end;
//----------------------------------------------------------------------------------------------------------------------
procedure TMainForm.VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType;
var Text: String);
var
Data: PMyRec;
begin
// A handler for the OnGetText event is always needed as it provides the tree with the string data to display.
Data := Sender.GetNodeData(Node);
if Assigned(Data) then
Text := Data.Caption;
end;
//----------------------------------------------------------------------------------------------------------------------
procedure TMainForm.VSTFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode);
var
Data: PMyRec;
begin
Data := Sender.GetNodeData(Node);
// Explicitely free the string, the VCL cannot know that there is one but needs to free
// it nonetheless. For more fields in such a record which must be freed use Finalize(Data^) instead touching
// every member individually.
if Assigned(Data) then
Data.Caption := '';
end;
//----------------------------------------------------------------------------------------------------------------------
procedure TMainForm.VSTInitNode(Sender: TBaseVirtualTree; ParentNode, Node: PVirtualNode;
var InitialStates: TVirtualNodeInitStates);
var
Data: PMyRec;
begin
with Sender do
begin
Data := GetNodeData(Node);
// Construct a node caption. This event is triggered once for each node but
// appears asynchronously, which means when the node is displayed not when it is added.
Data.Caption := Format('Level %d, Index %d', [GetNodeLevel(Node), Node.Index]);
end;
end;
//----------------------------------------------------------------------------------------------------------------------
procedure TMainForm.CloseButtonClick(Sender: TObject);
begin
Close;
end;
//----------------------------------------------------------------------------------------------------------------------
end.
|