Forum > LCL

[SOLVED] Treeview node dara

(1/1)

pcurtis:
I create a simple class


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---type  TNodeType = (ntRoot, ntObject, ntArray, ntBoolean, ntNull, ntNumber, ntString);   TMyNodeInfo= class    fNodeType: TNodeType;  public    property NodeType: TNodeType read fNodeType write fNodeType;  end; 
Each time I add a node I do


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---var  RootNode: TTreeNode;begin  fMyNodeInfo:= TMyNodeInfo.Create;  fMyNodeInfo.fNodeType:= ntObject;  RootNode:= TreeView1.Items.AddFirst(nil, 'root');  RootNode.Data:= fMyNodeInfo; 
and when I close the app I do


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---var  iTemp: Integer;begin  for iTemp:= 0 to TreeView1.Items.Count - 1 do    begin      TMyNodeInfo(TreeView1.Items[iTemp]).Free;    end;end; 
But I get memory leaks.

What's wring?

App attached

egsuh:
Try

TMyNodeInfo(TreeView1.Items[iTemp].Data).Free;


And you may use following at the creation,


  RootNode:= TreeView1.Items.AddObjectFirst(nil, 'root', fMyNodeInfo);

pcurtis:
Ok, thanks that works.

wp:
The "correct" way to destroy the nodes' Data is the OnDeletion event of the tree. This event fires whenever a node is deleted (destroyed).

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure TForm1.TreeView1Deletion(Sender: TObject; Node: TTreeNode);begin  if Node.Data <> nil then  begin    TObject(Node.Data).Free;  // Assuming that the Data element that you added is a class instance (it is a pointer to begin with).    Node.Data := nil;  end;end;  
BTW, I rarely use a for loop when running through the nodes of a tree structure because it makes me think that a tree is a linear structure which is not true. For example, both TTreeView and TTreeNode have an Items property. Are you sure that TreeView.Items refers to ALL nodes and not just to the the items of the top-level node (like in a TMenu)? IMHO, it is much safer (and faster) to think recursively and iterate through the nodes by using the NextSibling, FirstChild/NextChild methods:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure DeleteData(ATreeView: TTreeView; ANode: TTreeNode);begin  if ANode = nil then    exit;   // Destroy the Data.  if (ANode.Data <> nil) then  begin    TObject(ANode.Data).Free;    ANode.Data := nil;  end;   // Now delete Data in the children, grandchildren etc. of the node...  if ANode.HasChildren then    DeleteData(ATreeView, ANode.GetFirstChild);   // ... and delete Data in the siblings of the node.  ANode := ANode.GetNextSibling;  if ANode <> nil then    DeleteData(ATreeView, ANode);end; procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);var  iTemp: Integer;begin  DeleteData(TreeView1,TreeView1.Items.GetFirstNode);end;

Navigation

[0] Message Index

Go to full version