Watch, Follow, &
Connect with Us

Please visit our new home
community.embarcadero.com.


Welcome, Guest
Guest Settings
Help

Thread: trying to use TVirtualStringTree and its userdata



Permlink Replies: 3 - Last Post: Mar 18, 2017 10:39 AM Last Post By: Antonio Estevez Threads: [ Previous | Next ]
Asger Joergensen

Posts: 367
Registered: 11/18/08
trying to use TVirtualStringTree and its userdata
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 17, 2017 8:05 PM
Hi

I'm trying to use TVirtualStringTree and its node userdata, but I don't get
get the same date back that I added.

My test code look like this

void __fastcall TForm1::Button3Click(TObject *Sender)
{
   TVirtualNode *newNode = LvGroups->AddChild( 0, this );
   void* data = newNode->GetData();
   if( data == this )
      Beep(400,200); // ********   I get no beep
 
}


I get the same result when using newNode->SetData( (void*)this );

Am I missing something ?

I using Berlin

Thanks in advance
Best regards
Asger
Antonio Estevez

Posts: 599
Registered: 4/12/00
Re: trying to use TVirtualStringTree and its userdata
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 18, 2017 4:05 AM   in response to: Asger Joergensen in response to: Asger Joergensen
El 18/03/2017 a las 4:05, Asger Joergensen escribió:
Hi

I'm trying to use TVirtualStringTree and its node userdata, but I don't get
get the same date back that I added.

My test code look like this

void __fastcall TForm1::Button3Click(TObject *Sender)
{
   TVirtualNode *newNode = LvGroups->AddChild( 0, this );
   void* data = newNode->GetData();
   if( data == this )
      Beep(400,200); // ********   I get no beep
 
}


I get the same result when using newNode->SetData( (void*)this );

Am I missing something ?

GetData() returns the address of the Data field from the TVirtualNode record.
The userdata is stored as a pointer at the begin of the Data buffer.

Try this:

void __fastcall TForm1::Button3Click(TObject *Sender)
{
    TVirtualNode *newNode = LvGroups->AddChild( 0, this );
    void** data = (void**)newNode->GetData();
    if( *data == this )
       Beep(400,200);
}


or

void __fastcall TForm1::Button3Click(TObject *Sender)
{
    TVirtualNode *newNode = LvGroups->AddChild( 0, this );
    void* data = *(void**)newNode->GetData();
    if( data == this )
       Beep(400,200);
}
Asger Joergensen

Posts: 367
Registered: 11/18/08
Re: trying to use TVirtualStringTree and its userdata
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 18, 2017 6:16 AM   in response to: Antonio Estevez in response to: Antonio Estevez
Hi Antonio

Antonio Estevez wrote:

Am I missing something ?

GetData() returns the address of the Data field from the TVirtualNode record.
The userdata is stored as a pointer at the begin of the Data buffer.

Thank you very much, that works like a charm.

Do you know if I have to free anything in the VirtualTreeView ?
I do manage my own objects and I only assign a object pointer to
the user data, Size of userdata is set to sizeof(MyObject*).

Thanks again
Best regards
Asger
Antonio Estevez

Posts: 599
Registered: 4/12/00
Re: trying to use TVirtualStringTree and its userdata
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 18, 2017 10:39 AM   in response to: Asger Joergensen in response to: Asger Joergensen
El 18/03/2017 a las 14:16, Asger Joergensen escribió:
Hi Antonio

Antonio Estevez wrote:

Am I missing something ?

GetData() returns the address of the Data field from the TVirtualNode record.
The userdata is stored as a pointer at the begin of the Data buffer.

Thank you very much, that works like a charm.

Do you know if I have to free anything in the VirtualTreeView ?
I do manage my own objects and I only assign a object pointer to
the user data, Size of userdata is set to sizeof(MyObject*).

I think that you are mixing two modes to save information on a TVirtualNode:
- Using the UserData pointer
- Using the NodeDataSize property to add extra memory at the end of the TVirtualNode struct (record in Delphi).

If you are assigning an object to the UserData pointer you don't need to set the NodeDataSize. In this case you are
wasting a lot of memory if you assign a value to NodeDataSize.

To free MyObject you must add an OnFreeNode event to the TVirtualStringTree component:

void __fastcall TForm1::LvGroupsFreeNode(TBaseVirtualTree *Sender, PVirtualNode Node)
{
    TMyObject *MyObject = *(TMyObject**)Node->GetData();
    delete MyObject;
}

Alternatively, if you want to use the NodeDataSize property then:

typedef struct
{
    int Value1;
    float Value2;
    Char *Text;
} TMyVirtualNodeData;
 
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
    LvGroups->NodeDataSize= sizeof(TMyVirtualNodeData);
}
 
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    TVirtualNode *newNode = LvGroups->AddChild( 0 );
    TMyVirtualNodeData* data = (TMyVirtualNodeData*)newNode->GetData();
 
    data->Value1 = 10;
    data->Value2 = 5.0f;
    data->Text   = new Char[256];
    data->Text[0]= 0;
}
 
void __fastcall TForm1::LvGroupsFreeNode(TBaseVirtualTree *Sender, PVirtualNode Node)
{
    TMyVirtualNodeData* data = (TMyVirtualNodeData*)Node->GetData();
    delete[] data->Text;
}
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02