-2

I need an example how to use "virtual treeview" IterateSubtree in C++ Embarcadero Xe1-7.

I have the problem with this code:

void __fastcall TMyForm::BuSearchClick(TObject *)
{
  MyTreeView->IterateSubtree(NULL, SearchDataSomeId, (void*)&PNodeData, TVirtualNodeStates(), false, false);
}

void __fastcall TMyForm::SearchDataSomeId(TBaseVirtualTree*, PVirtualNode Node, void *Data, bool &Abort)
{
}

The compiler gives the following error:

[bcc32 Error] MyFile.cpp(363): E2034 Cannot convert 'void (_fastcall * (_closure )(TBaseVirtualTree *,TVirtualNode *,void *,bool &))(TBaseVirtualTree *,TVirtualNode *,void *,bool &)' to '_di_TVTGetNodeProc'
Rudy Velthuis
  • 28,387
  • 5
  • 46
  • 94
H.K
  • 173
  • 8
  • You should format the code so it's clear what is text, what is code. – Rodrigo Gómez Apr 27 '15 at 16:55
  • "C++ embarcadero Xe1-7" what? – Lightness Races in Orbit Apr 27 '15 at 17:42
  • I am sorry Rodrigo Gómez. Is it now ok? – H.K Apr 28 '15 at 16:10
  • @RodrigoGómez I fixed up the formatting. – kirbyfan64sos Apr 28 '15 at 16:12
  • There's more code here that you're not showing us. In particular, we need to know what `_di_TVTGetNodeProc` is. – kirbyfan64sos Apr 28 '15 at 16:14
  • Also, try changing `MyTreeView->IterateSubtree(NULL, SearchDataSomeId, ...` to `MyTreeView->IterateSubtree(NULL, &TMyForm::SearchDataSomeId` – kirbyfan64sos Apr 28 '15 at 16:16
  • from VirtualTrees.hpp
    __interface TVTGetNodeProc;
    typedef System::DelphiInterface _di_TVTGetNodeProc;
    __interface TVTGetNodeProc : public System::IInterface
    {
    public:
    virtual void __fastcall Invoke(TBaseVirtualTree* Sender, PVirtualNode Node, void * Data, bool &Abort) = 0 ;
    };
    – H.K Apr 28 '15 at 20:36
  • from VirtualTrees.hpp __interface TVTGetNodeProc; typedef System::DelphiInterface _di_TVTGetNodeProc; __interface TVTGetNodeProc : public System::IInterface { public: virtual void __fastcall Invoke(TBaseVirtualTree* Sender, PVirtualNode Node, void * Data, bool &Abort) = 0 ; }; – H.K Apr 28 '15 at 20:42

2 Answers2

0

You're trying to use what Delphi/C++Builder calls a method pointer or __closure. Virtual Treeview expects an anonymous method. See here for more details.

I think that creating an anonymous method in C++Builder involves subclassing from TProc and implementing the Invoke method, but it seems to be very poorly documented.

If subclassing TProc doesn't work or is too hard to figure out, I can think of a couple of options:

  • Hack the Virtual Treeview source to create an IterateSubtree overload taking a method pointer.
  • Ask a new question on Stack Overflow in hopes that someone else knows how to create a Delphi anonymous method in C++Builder.
Community
  • 1
  • 1
Josh Kelley
  • 56,064
  • 19
  • 146
  • 246
  • "*it seems to be very poorly documented*" - Have you read [How to Handle Delphi Anonymous Methods in C++](http://docwiki.embarcadero.com/RADStudio/en/How_to_Handle_Delphi_Anonymous_Methods_in_C%2B%2B) in Embarcadero's documentation? – Remy Lebeau Jan 11 '19 at 09:01
0

thanks very much`

i have found the solution

typedef void (*TIterateSubtreeCallBack)(TBaseVirtualTree*, PVirtualNode Node, void *_Data, bool &Abort);   

class TMyVTGetNodeProcRef : public TCppInterfacedObject<TVTGetNodeProc>    
{
private:   
  TIterateSubtreeCallBack callback;   
public:   
  TMyVTGetNodeProcRef(TIterateSubtreeCallBack _callback) : callback(_callback) {}    
  INTFOBJECT_IMPL_IUNKNOWN(TInterfacedObject);   

  void __fastcall Invoke(TBaseVirtualTree* Sender, TVirtualNode *Node, void *Data, bool &Abort)   
  {   
    return callback(Sender, Node, Data, Abort);   
  }   
};   

void __fastcall TMyForm::BuSearchClick(TObject *)   
{   
  Node= MyTreeView->IterateSubtree(NULL, new TMyVTGetNodeProcRef(SearchDataId), (void*)&PNodeData, TVirtualNodeStates(), false, false);   
}   

void TMyForm::SearchDataId(TBaseVirtualTree*Tr, PVirtualNode Node, void *_Data, bool &Abort)   
{   
 put my code ...   
}   
//---------------------------------------------------------------------------
H.K
  • 173
  • 8