Mega Code Archive

 
Categories / Delphi / Examples
 

Property names, types and values from an object using RTTI

Title: Property names, types and values from an object using RTTI Question: Have you ever need to know if a property or a method exists whithin an object?... what about listing all the properties contained in the object like the object inspector actually does?... Answer: Introduction ------------ As you should know the RTTI (Run Time Type Information) is designed to access information about a given class or datatype at rutime. Since the documentation about RTTI is nonexistent by Borland, you should look at the undocunented code in the unit TYPINFO.PAS located at the SOURCE\VCL directory. Before you proceed, keep in mind some limitations of the RTTI. Warnings -------- * The TYPINFO unit is undocumented probably because it could be changed in any future versions of Delphi without notice, (although it seems to be stable across all existing Delphi versions). * The funtions will only work with any object that descends from TComponent. ( Remember that the TComponent class implements the methods needed for creating persistent objects ) and ... * The RTTI information is available only in the published properties. Public properties generate no RTTI information. ( Remember that a property is denoted by the Property keyword. See the Delphi help for more details on this) Construction ------------ The first function, only tell us if a property exists within an object. This function receives two parameters: an instance of a TComponent descendant and the name of the property we want to search. Remember to include the TypInfo unit. uses TypInfo, classes; ... { * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * } function HasProperty (AnObject: TComponent; PropertyName: String): Boolean; var PropInfo: PPropInfo; begin PropInfo := GetPropInfo ( AnObject , PropertyName ); result := PropInfo nil; end;{HasProperty} { * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * } The code listed below is a very simple function that obtains the value of a published property or event of an instance. The function receives the same parameters. { * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * } function GetPropertyValueText ( AnObject: TComponent; PropertyName: String ) : String; begin Result := VarToStr ( GetPropValue (AnObject,PropertyName, false) ); end;{GetPropertyValueText} { * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * } This procedure sets the value of an instance based in the property name. It needs three parameters, the instance, the property name and a variant that contains the value that we want to assign to the property. { * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * } procedure SetPropertyValueText ( AnObject: TComponent; PropertyName: String; value: variant); begin SetPropValue (AnObject, PropertyName, Value); end;{SetPropertyValueText} { * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * } The next fragment of code corresponds to a function that list all the properties contained within an instance. It receives as parameters the instance and a TStrings instance to store the names. The GetPropList function gets all the properties and store them into an array. This array contains pointers to packed records that holds the information about the property. You can get more information about this looking at the declaration of the TPropInfo record in the TypInfo unit. { * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * } procedure GetPropertyList ( AnObject: TComponent; List: TStrings); var PropertyIndex, PropertyCount : Integer; PropList : TPropList; begin PropertyCount := GetPropList ( AnObject.ClassInfo, tkAny, @PropList) ; // the second parameter could be also tkProperties for only get the // property names or tkMethods to get the methods names. for PropertyIndex := 0 to PropertyCount -1 do List.Add ( PropList[PropertyIndex].PropType^.Name ); end;{GetPropertyList} { * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * } Conclusions ----------- Knowing how to access to the RTTI data of objects could help us to create more powerful applications. In my case it has been very useful to reproduce the functionality of the Delphi Object Inspector in the Report Authoring Tool that I'm actually working in order to change some personalized object properties. I want to thank Jorge Ayala Marentes and Agustn Elias, members of this community and my develoment team for providing me valuable information to write this article. If you need more information, there is a complete chapter on this topic in the book: Delphi Developers Handbook by Marco Cant. This book has a lot of interesting and undocumented stuff about Delphi. I will be happy to hear any comments and suggestions.