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
> 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
Works GREAT!!
Many thanks!
Regards,
Anderson
"Remy Lebeau (TeamB)" <no....@no.spam.com> escreveu na mensagem
news:47df...@newsgroups.borland.com...
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
> 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
> 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
That's exactly what I needed!
=)
Regards,
Anderson
> Rohloff [TeamB]
> 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;