Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Getting property getter/setter field with RTTI

124 views
Skip to first unread message

Anderson Farias

unread,
Mar 17, 2008, 11:06:18 PM3/17/08
to
Hi all,


Is it possible to have access to property getter/setter *field* (not
method), eg:

TMyClass = class (TPersistent)
private
fStrings: TStrings;
published
property Strings: TStrings read fStrings;
end;

How to have "access" to fStrings from Strings property TypeInfo??

I can retrieve PPropInfo for 'Strings' property but then, GetProc and
SetProc seems to work only when you have getter/setter methods!

Any tips?!


Regards,
Anderson Farias

Remy Lebeau (TeamB)

unread,
Mar 18, 2008, 2:13:40 AM3/18/08
to

"Anderson Farias" <peixe...@yahoo.com.br> wrote in message
news:47df...@newsgroups.borland.com...

> How to have "access" to fStrings from Strings property TypeInfo??

Use GetOrdProp() or GetObjectProp() to have the TypInfo unit retreive the
object pointer for you. RTTI knows whether a property uses methods or
direct field access for getters and setters, and how to use them properly.
Do not try to do it manually yourself. For example:

Try this:

var
Strings: TStrings;
begin
Strings := TStrings(GetOrdProp(MyObj, 'Strings'));
// or:
// Strings := TStrings(GetObjectProp(MyObj, 'Strings'));
end;


Gambit


Anderson Farias

unread,
Mar 18, 2008, 2:32:30 PM3/18/08
to
Hi Gambit ,

Works GREAT!!


Many thanks!

Regards,
Anderson


"Remy Lebeau (TeamB)" <no....@no.spam.com> escreveu na mensagem
news:47df...@newsgroups.borland.com...

Anderson Farias

unread,
Mar 24, 2008, 6:54:24 PM3/24/08
to
Hi Again,

One more question,

Is it possible (and how) to know if a property has a 'read' (getter) or a
'write' (setter) specifier and if it has, how to determine if it uses a
field or a method??


Regards,
Anderson


Marc Rohloff [TeamB]

unread,
Mar 24, 2008, 8:27:37 PM3/24/08
to
On Mon, 24 Mar 2008 19:54:24 -0300, Anderson Farias wrote:

> Is it possible (and how) to know if a property has a 'read' (getter) or a
> 'write' (setter) specifier and if it has, how to determine if it uses a
> field or a method??

Something like:

var pi:PPropInfo;
begin
pi := GetPropInfo(myobject 'cursor');
if pi.SetProc=nil then
No Setter
else if longint(pi.SetProc) and $FF000000) = $FF000000 then
Direct Field Access
else
Setter Method
end

You need to know more if you actually want to call the method. Your
property could be an Index property or have an index specifier and the
method could be virtual or not. The most you should rely on is
checking the pointer against nil. If it isn't just call SetOrdProp and
let it handle the rest.

--
Marc Rohloff [TeamB]
marc -at- marc rohloff -dot- com

Remy Lebeau (TeamB)

unread,
Mar 24, 2008, 9:35:47 PM3/24/08
to

"Anderson Farias" <peixe...@yahoo.com.br> wrote in message
news:47e83104$1...@newsgroups.borland.com...

> Is it possible (and how) to know if a property has a 'read' (getter)
> or a 'write' (setter) specifier and if it has, how to determine if it
> uses a field or a method??

Marc already told you how, but why do you need that information? The
TypInfo unit handles those details for you when reading/writing values. You
should not have your code directly rely on any particular features of the
RTTI structures. If they change in the future, your code will break.


Gambit


Anderson Farias

unread,
Mar 24, 2008, 9:37:11 PM3/24/08
to
Thanks Marc

That's exactly what I needed!

=)

Regards,
Anderson


> Rohloff [TeamB]

Anderson Farias

unread,
Mar 24, 2008, 9:49:49 PM3/24/08
to
Hi Gambit,

> but why do you need that information? The TypInfo unit handles those
> details for you when reading/writing values.

What I want if to automaticaly 'create' fields for some properties, only if
they write directly to a field, eg:


TMySpecialAttribute = class(TPersistent)
{...}
end;

TMyObject = class(TPersistent)
private
fSomeAttribute: TMySpecialAttribute;
procedure CreateAttributes;
// create all fields of type TMySpecialAttribute used by properties
// code is at end of this message
published
procedure AfterCreation; override; // CreateAttributes;
property SomeAttribute: TMySpecialAttribute read fSomeAttribute write
fSomeAttribute;
end;


> should not have your code directly rely on any particular features of the
> RTTI structures. If they change in the future, your code will break.

That's important to note! Thanks for warning.


Regards,
Anderson

PS: The actual 'CreateAttributes' method looks like:

procedure TMyObject.CreateAttributes;
var
i: Integer;
PropList: TPropList;
PropCount: Integer;
AttrClass: TAttributeClass;
AttrName: string;
TypeData: PTypeData;
begin
PropCount := GetPropList(Self.ClassInfo, [tkClass], @PropList);
for i := 0 to Pred(PropCount) do
begin
TypeData := GetTypeData(PropList[i].PropType^);
if TypeData.ClassType.InheritsFrom(TAttribute) then
begin
AttrName := PropList[i].Name;
AttrClass := TAttributeClass(TypeData.ClassType);
if (PropList[i].GetProc<>nil) and (PropList[i].SetProc<>nil) then
begin
if (GetObjectProp(Self, AttrName)=nil) and
((Longint(PropList[i].SetProc) and $FF000000)=$FF000000) then
SetObjectProp(Self, AttrName, CreateAttribute(AttrName,
AttrClass));
end;
end;
end;
end;


0 new messages