Class properties

This is the forum for miscellaneous technical/programming questions.

Moderator: 2ffat

Class properties

Postby theLizard » Thu Apr 28, 2016 12:49 am

I think I already know the answer but...

I know how to find a property using GetPropInfo with the property name from a component, is there a way to iterate through a classes properties (not a component) to find the property by name i.e.

if propertyinfo == listitem->text

The answer is probably no but you won't know until you ask :}

Cheers
theLizard
BCBJ Master
BCBJ Master
 
Posts: 447
Joined: Wed Mar 18, 2009 2:14 pm

Re: Class properties

Postby rlebeau » Thu Apr 28, 2016 1:04 pm

I'm not sure I quite understand what you are asking for, but I *think* you are looking for the overloaded version of GetPropInfo() that accepts a TClass meta type as input instead of an object instance.

Code: Select all
PPropInfo PropInfo = GetPropInfo(__classid(TSomeClass), "PropName");


If you just want to iterate through all available properties (of either an object or a class type), there are overloaded GetPropList() functions available.

If this is not what you are looking for, then you need to clarify your question.
Remy Lebeau (TeamB)
Lebeau Software
User avatar
rlebeau
BCBJ Author
BCBJ Author
 
Posts: 1457
Joined: Wed Jun 01, 2005 3:21 am
Location: California, USA

Re: Class properties

Postby theLizard » Thu Apr 28, 2016 3:45 pm

Thanks Remy,

rlebeau wrote:If this is not what you are looking for, then you need to clarify your question.


GetPropInfo works fine on a component but not on a non VCL style class everything relating to this in the help files all refer to getting info from a component.

What I was hoping for is an easy way to get property info from a standard class like

Code: Select all
//---------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
class TMyClass
   {
   private:
    UnicodeString   Fname;
      UnicodeString   Fwhatever;

      UnicodeString __fastcall getFname();
      void __fastcall setFname(UnicodeString value);
      UnicodeString __fastcall getFwhatever();
      void __fastcall setFwhatever(UnicodeString value);
   protected:

   public:
      __fastcall TMyClass();
      __fastcall ~TMyClass();

      __property UnicodeString Fname = {read = getFname, write = setFname};
      __property UnicodeString Fwhatever = {read = getFwhatever, write = setFwhatever};
};
#endif


The reason I am asking this question is that I have a number of class's most of which have between 5 and 30 + properties I was hoping that there were a way, at run time to select a property name from a listbox and get info on the property and process user input based on the property type and class that it came from.

Example code I would like to implement
Code: Select all

 PropInfo = GetPropInfo(AClass, b->Items->Strings[b->ItemIndex]);
 if(PropInfo->Name == something)
   do something like open a form for editing all the properties of the class



Hope this helps understanding my question

As I said, there is probably no way to do this but.

btw, Thanks for the direction with the lsitview question

Cheers
theLizard
BCBJ Master
BCBJ Master
 
Posts: 447
Joined: Wed Mar 18, 2009 2:14 pm

Re: Class properties

Postby theLizard » Thu Apr 28, 2016 6:53 pm

I don't think there is a viable solution for this without lots of code so considering that the mountain won't come to me, I will have to go to the mountain.

The simplest way to achieve my goals is to make components from my classes, I have tested this theory and it is working with simple code

Code: Select all

if(dynamic_cast<TChartBase*>(html->GetObjects()[0]) != NULL)
   {
   TChartBase* b = dynamic_cast<TChartBase*>(html->GetObjects()[0]);
        //Do stuff
        }



In the code above, html->GetObjects()[0] is a vector of TObjects

The vector will contain objects of class types, since the vector may contain as many objects as required for the task, I need a way to find an object in the vector based on a property of the class type.

I would like to implement an std::find_if using generic code on the objects using code something similar to below

Code: Select all
struct IsObject
   {
   TObject* _object;
   IsObject(TObject* object) : _object(object) {}
   bool operator()(const IsObject * item)const
      {

      if(dynamic_cast<TChartBase*>(GetObjects()[0]) != NULL)

      return(item->??? == ???);
      }
   };



This code does not work and I think I know why but can someone suggest how I could get this to work.

GetObjects() returns a vector of objects, this is not recognized by the struct

I could get it to work by having a struct for each of my classes but I am sure there is a way to make one struct handle all (i hope)

Cheers

I have posted this as a separate question as well
theLizard
BCBJ Master
BCBJ Master
 
Posts: 447
Joined: Wed Mar 18, 2009 2:14 pm

Re: Class properties

Postby theLizard » Thu Apr 28, 2016 10:57 pm

rlebeau wrote:f you just want to iterate through all available properties (of either an object or a class type), there are overloaded GetPropList() functions available.


I am having success in what I am after, the framework is in place and tested, all that is left to do is to get the property list from the component but I am not clear on how to go about that using GetPropList()

I have looked for info but am not able to find anything that gives an example on how to do this.

How do I code it?

Cheers
theLizard
BCBJ Master
BCBJ Master
 
Posts: 447
Joined: Wed Mar 18, 2009 2:14 pm

Re: Class properties

Postby rlebeau » Mon May 09, 2016 2:09 pm

theLizard wrote:GetPropInfo works fine on a component but not on a non VCL style class everything relating to this in the help files all refer to getting info from a component.


GetPropInfo() only works on Delphi-style RTTI. Any C++ class that is derived from TPersistent (such as components) or TObject directly will have that RTTI automatically, as they are both implemented in Delphi. To use GetPropInfo() with a non-Delphi based C++ class, you have to enable Delphi-style RTTI manually by applying __declspec(delphirtti) to the class.

theLizard wrote:What I was hoping for is an easy way to get property info from a standard class


Without access to Delphi-style RTTI, all you have is pure C++ RTTI, and that does not provide rich enough information to suit your needs.

theLizard wrote:The reason I am asking this question is that I have a number of class's most of which have between 5 and 30 + properties I was hoping that there were a way, at run time to select a property name from a listbox and get info on the property and process user input based on the property type and class that it came from.


That is possible but only with Delphi-style RTTI.

theLizard wrote:Example code I would like to implement
Code: Select all

 PropInfo = GetPropInfo(AClass, b->Items->Strings[b->ItemIndex]);
 if(PropInfo->Name == something)
   do something like open a form for editing all the properties of the class




The second parameter of GetPropInfo() is a property name, so the check for PropInfo->Name is redundant.

As for the AClass value, you can use the ClassType() method of any TObject-derived instance object, or __classid() for any class type that derives from TObject.
Remy Lebeau (TeamB)
Lebeau Software
User avatar
rlebeau
BCBJ Author
BCBJ Author
 
Posts: 1457
Joined: Wed Jun 01, 2005 3:21 am
Location: California, USA

Re: Class properties

Postby rlebeau » Mon May 09, 2016 2:22 pm

theLizard wrote:I am having success in what I am after, the framework is in place and tested, all that is left to do is to get the property list from the component but I am not clear on how to go about that using GetPropList()


Like this:

Code: Select all
PPropList PropList;
int PropCount = GetPropList(ObjectPtr, PropList);
// or:
// int PropCount = GetPropList(static_cast<PTypeInfo>(ObjectPtr->ClassInfo()), PropList);
try
{
    for (int i = 0; i < PropCount; ++i)
    {
        // use (*PropList)[i]->... as needed
    }
}
__finally
{
    FreeMem(PropList);
}


Alternatively:

Code: Select all
TPropList List;

PTypeInfo TypeInfo = static_cast<PTypeInfo>(ObjectPtr->ClassInfo());
int PropCount = GetTypeData(TypeInfo)->PropCount;
GetPropInfos(TypeInfo, &List);
for(int i = 0; i < PropCount; ++i)
{
    // use List[i]->... as needed
}
Remy Lebeau (TeamB)
Lebeau Software
User avatar
rlebeau
BCBJ Author
BCBJ Author
 
Posts: 1457
Joined: Wed Jun 01, 2005 3:21 am
Location: California, USA

Re: Class properties

Postby theLizard » Mon May 09, 2016 3:12 pm

Thanks for your example Remy, looks easier than I thought it would be.

Cheers.
theLizard
BCBJ Master
BCBJ Master
 
Posts: 447
Joined: Wed Mar 18, 2009 2:14 pm


Return to Technical

Who is online

Users browsing this forum: Google [Bot] and 14 guests

cron