Hi,
I have have some troubles with the VirtualTreeView component, and need advise from more experienced users.
Using the following definitions.
type
PPayload = ^TPayload;
TPayload = record
ID:Integer;
Name: string[50];
end;
TArrPayload = array of TPayload;
the attached test project is supposed to do the following:
- Create a dynamic array of records and populate it with some test data
- Store a pointer to each rec in a VirtualStringTree
procedure TForm1.FormCreate(Sender: TObject);
const
NumItems = 10;
var
i: integer;
rec: TPayload;
begin
VirtualStringTree1.NodeDataSize := SizeOf(PPayload);
// populate the array
ArrPayload := TArrPayload.Create;
for i := 1 to NumItems do
begin
rec.ID := i;
rec.Name := Format('Node %d', [i]);
Insert(rec,ArrPayload,MaxInt); // append tail
end;
// initalize the nodes
for rec in ArrPayload do
VirtualStringTree1.AddChild(nil,@rec);
end;
- In VirtualStringTree.GetText: retrieve the record, and display the test data
procedure TForm1.VirtualStringTree1GetText(Sender: TBaseVirtualTree;
Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType;
var CellText: String);
var
p:PPayload;
begin
assert(assigned(Node),'VirtualStringTree1GetText: Node not assigned');
p := Sender.GetNodeData(Node);
CellText := p^.Name;
end;
Problems with the enclosed demo code:
The number of nodes displayed is OK, but the node captions are all garbage.
The project crashes on exit, obviously memory corruption. Seems to be caused by FreeAndNil of the dynamic array.
This seems to work, but why? Coincidence?
procedure TForm1.FormDestroy(Sender: TObject);
begin
// FreeAndNil(ArrPayload);
ArrPayload := Nil;
end;
I can't find any obvious error in hours, who can help me out?
Thnx, Armin
P.S. I think I solved the memory corruption problem: though the syntax of dynamic arrays does somewhat mimic object syntax, dynamic arrays are not descendants of TObject, and so using FreeAndNil with a dynamic arry is not valid. Correct? But why, then, doesn't FreeAndNil complain that it hasn't been passed an object reference?
In fact, FreeAndNil seems not to care about anything, because this code compiles, and does also crash on exit:
procedure TForm1.FormDestroy(Sender: TObject);
var
x:integer;
begin
ArrPayload := nil;
FreeAndNil(x);
end;