How to reference VirtualTree records from one VT to another VT in C++Builder?

67 views Asked by At

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))
1

There are 1 answers

1
Remy Lebeau On

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));
}