Hey all, first sorry for my bad english. Consider the following (not actual code):
IMyInterface = Interface(IInterfce)
procedure Go();
end;
MyClass = class(IMyInterface)
procedure Go();
end;
MyOtherClass = class
published
property name: string;
property data: MyClass;
end;
I'm setting "MyOtherClass" properties using RTTI. For the string property it's easy, but my question is:
How can I get a reference to the "data" (MyClass) property so I can call the Go() method?
I want to do something like this (pseudo-code):
for i:= 0 to class.Properties.Count
if (propertyType is IMyInterface) then
IMyInterface(class.properties[i]).Go()
(if only this was C# :( )
PS.: this is in delphi 7 (i know, even worse)
If the string property is easy, as you say, then I assume you're calling GetStrProp and SetStrProp from the TypInfo unit. Class-type properties can be equally easy with GetObjectProp and SetObjectProp.
if Supports(GetObjectProp(Obj, 'data'), IMyInterface, Intf) then
Intf.Go;
If you don't really need the interface, and you know that the data property has type TMyClass, then you can go a little more directly:
(GetObjectProp(Obj, 'data') as TMyClass).Go;
That requires the property to have a non-null value.
If you don't know the name of the property you want, then you can use some other things in TypInfo to search for it. For example, here is a function that will find all the published properties of an object that have values that implement IMyInterface; it calls Go on each of them in no particular order.
procedure GoAllProperties(Other: TObject);
var
Properties: PPropList;
nProperties: Integer;
Info: PPropInfo;
Obj: TObject;
Intf: IMyInterface;
Unk: IUnknown;
begin
// Get a list of all the object's published properties
nProperties := GetPropList(Other.ClassInfo, Properties);
if nProperties > 0 then try
// Optional: sort the list
SortPropList(Properties, nProperties);
for i := 0 to Pred(nProperties) do begin
Info := Properties^[i];
// Skip write-only properties
if not Assigned(Info.GetProc) then
continue;
// Check what type the property holds
case Info.PropType^^.Kind of
tkClass: begin
// Get the object reference from the property
Obj := GetObjectProp(Other, Info);
// Check whether it implements IMyInterface
if Supports(Obj, IMyInterface, Intf) then
Intf.Go;
end;
tkInterface: begin
// Get the interface reference from the property
Unk := GetInterfaceProp(Obj, Info);
// Check whether it implements IMyInterface
if Supports(Unk, IMyInterface, Intf) then
Intf.Go;
end;
end;
end;
finally
FreeMem(Properties);
end;
end;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With