1

Could someone help me with using VirtualTree in C++Builder?

I have VT1 with records in it:

image

And VT2 with records in it:

image

I copy values from VT1 to VT2:

void __fastcall TForm3::CopyItemsFromVT1ToVT2(TVirtualStringTree *VT_List, PVirtualNode NodeList, TVirtualStringTree *VT_Tree, PVirtualNode NodeTree) {
   ((PTreeData)VT_Tree->GetNodeData(NodeTree))->Id=((TForm1::PTreeData)VT_List->GetNodeData(NodeList))->Id;
   ((PTreeData)VT_Tree->GetNodeData(NodeTree))->Type=((TForm1::PTreeData)VT_List->GetNodeData(NodeList))->Type;
   ((PTreeData)VT_Tree->GetNodeData(NodeTree))->Date=((TForm1::PTreeData)VT_List->GetNodeData(NodeList))->Date;
   ((PTreeData)VT_Tree->GetNodeData(NodeTree))->Time=((TForm1::PTreeData)VT_List->GetNodeData(NodeList))->Time;
   ((PTreeData)VT_Tree->GetNodeData(NodeTree))->Char_Code=((TForm1::PTreeData)VT_List->GetNodeData(NodeList))->Char_Code;
   ((PTreeData)VT_Tree->GetNodeData(NodeTree))->Number_Code=((TForm1::PTreeData)VT_List->GetNodeData(NodeList))->Number_Code;
   ((PTreeData)VT_Tree->GetNodeData(NodeTree))->Message=((TForm1::PTreeData)VT_List->GetNodeData(NodeList))->Message;
}

How can I reference records from VT1 to VT2 instead? Is this correct?

((PTreeData)VT2->GetNodeData(ParentNodeTarget)) = ((PTreeData)VT1->GetNodeData(ParentNodeSource))
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Radomir23
  • 11
  • 1

1 Answers1

0

Instead of copying individual fields manually, you can let the compiler do it for you, assuming TreeData is a struct or class with an operator= implemented (particular a default one generated by the compiler), eg:

struct TreeData
{
    ...
};
typedef TreeData *PTreeData;

...

VT1->NodeDataSize = sizeof(TreeData);
VT2->NodeDataSize = sizeof(TreeData);

...

void __fastcall TForm3::CopyItemsFromVT1ToVT2(TVirtualStringTree *VT_List, PVirtualNode NodeList, TVirtualStringTree *VT_Tree, PVirtualNode NodeTree)
{
    *static_cast<PTreeData>(VT_Tree->GetNodeData(NodeTree)) = *static_cast<PTreeData>(VT_List->GetNodeData(NodeList));
}

But, if you want VT2 nodes to simply point at the same data as VT1 nodes, without making copies, then you need to allocate the TreeData instances outside of any nodes, and then just store TreeData* pointers inside of the nodes, eg:

struct TreeData
{
    ...
};
typedef TreeData *PTreeData, **PPTreeData;

...

VT1->NodeDataSize = sizeof(PTreeData);
VT2->NodeDataSize = sizeof(PTreeData);

...

PTreeData data = new TreeData;
// initialize data as needed ...
*static_cast<PPTreeData>(VT1->GetNodeData(SomeNode)) = data;

...

// OnFreeNode event handler for VT1...
void __fastcall TForm3::VT1FreeNode(TBaseVirtualTree *Sender, PVirtualNode Node)
{
    delete *static_cast<PPTreeData>(Sender->GetNodeData(Node));
}

...

void __fastcall TForm3::CopyItemsFromVT1ToVT2(TVirtualStringTree *VT_List, PVirtualNode NodeList, TVirtualStringTree *VT_Tree, PVirtualNode NodeTree)
{
    *static_cast<PPTreeData>(VT_Tree->GetNodeData(NodeTree)) = *static_cast<PPTreeData>(VT_List->GetNodeData(NodeList));
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Thank's Remy second case is best: less memory and best performance i assume :) question: PTreeData data = new TreeData; will be delete OnFreeNode event handler for VT1 ??? – Radomir23 Jul 24 '18 at 06:17