I have many interfaces as a result of importing a type library. So the interfaces look like this:
ISomeCollection = dispinterface
['{6592E851-3D65-4D04-B5F3-B137667B816A}']
procedure Remove(Identifier: OleVariant); dispid 2;
function Add(Name: OleVariant; DatabaseType_ID: OleVariant): ERSModel; dispid 3;
property _NewEnum: IUnknown readonly dispid -4;
property Item[Identifier: OleVariant]: ERSModel readonly dispid 4;
property _Item[Identifier: OleVariant]: ERSModel readonly dispid 0; default;
property Count: Integer readonly dispid 1;
end;
_NewEnum- This is an idiom for using a Visual Basic loop expression for-each(it's exactly like Delphi for-in) a COM collection of objects - despite the IUnknown declaration, it is really an interface IEnumVARIANT. Since this is the only way to list the elements of the collection, I went around it with:
{This class have just this class function}
class function TVariantUtils.GetAs<T>(pModeloOleVar: OleVariant): T;
begin
Result := (T(IUnknown(pModeloOleVar)));
end;
Using:
var
EnumColecction: IEnumVariant;
ListOfSubObjects: TEnumaretorObjects;
begin
...
EnumCollection := TVariantUtils.GetAs<IEnumVariant>(Object.SomeCollection._NewEnum);
ListOfSubObects := TEnumeratorObjects<ItemofSomeCollection>.Create(EnumCollection);
...
End;
The constructor receives the IEnumVariant parameter. I want to create a constructor that gets an IInterface and determines if the ISomeCollection has the _NewEnum IUnknown property - and execute the above code once. I do not know the name or GUID of the interface at compile time.
: delphi-xe , , Delphi XE
( Starter Edition ).
D2010.
EDIT:
RTTI ( , ):
constructor TEnumeratorVariant<T>.Create(pEnumeraVariante: IInterface);
var
EnumVar: IEnumVariant;
Contexto: TRttiContext;
InfoTipo: TRttiType ;
PropInfo: TRttiProperty;
pTipo: PTypeInfo;
begin
Contexto.Create;
pTipo := TypeInfo(pEnumeraVariante);
InfoTipo := Contexto.GetType(TypInfo(pEnumeraVariante));
PropInfo := InfoTipo.GetProperty('_NewEnum');
if Assigned(PropInfo) then
begin
Supports(PropInfo.GetValue(pEnumeraVariante), IEnumVariant, EnumVar);
Create(EnumVar);
end;
Contexto.Free;
PropInfo.Free;
InfoTipo.Free;
end;