Hello Wilfried, Before you typecast a variant to an interface, you must typecast it to Iunknown or Idispatch:
Loc := IDispatch(Vertex) as Location; FYI, Below is a unit that allows you to create a 'for each' statement in Delphi. You'd use it as follows: with ForEach(shape.Vertices) do while Next(Location, Loc) do begin //Process Loc end; Here the unit: unit uForEach; {$WEAKPACKAGEUNIT ON} interface uses ActiveX, ComObj, Variants; type { The IEnumVariant definition in the ActiveX unit erroneously declares the Next method as function Next(celt: LongWord; var rgvar : OleVariant; out pceltFetched: LongWord): HResult; stdcall; According to Microsoft documentation, it should be: function Next(celt: LongWord; pvar : POleVariant; pceltFetched: PLongWord): HResult; stdcall; See Borland case in http://qc.borland.com/wc/qcmain.aspx?d=4512 } IEnumVariant = interface(IUnknown) ['{00020404-0000-0000-C000-000000000046}'] function Next(celt: LongWord; pvar : PVariantArgList; pceltFetched: PLongWord): HResult; stdcall; function Skip(celt: LongWord): HResult; stdcall; function Reset: HResult; stdcall; function Clone(out Enum: IEnumVariant): HResult; stdcall; end; {!~IForEach implemented a 'For Each' feature, similar to Visual Basic, in Delphi. Obtain the interface by calling the ForEach function. Typical use (Excel workbooks): with ForEach(Workbooks) do while Next(_Workbook, WB) do ... } IForEach = interface(IUnknown) ['{33531233-B908-459E-8F05-09B7758052DA}'] function Next(const IID: TGUID; out Obj): Boolean; function NextVar(out Obj: OleVariant): Boolean; end; function ForEach(const ACollection: IDispatch): IForEach; implementation type TForEach = class(TInterfacedObject, IForEach) private FEnum: IEnumVariant; protected //IForEach function Next(const IID: TGUID; out Obj): Boolean; function NextVar(out Obj: OleVariant): Boolean; public constructor Create(const ACollection: IDispatch); reintroduce; end; function ForEach(const ACollection: IDispatch): IForEach; begin Result := TForEach.Create(ACollection); end; { TForEach } constructor TForEach.Create(const ACollection: IDispatch); var EnumUnk: OleVariant; DispParamNoArgs: TDispParams; ArgErr: Cardinal; begin inherited Create; { We must obtain an interface to the enumerator, which is returned by the NewEnum method, which must be called by DispID } FillChar(DispParamNoArgs, SizeOf(DispParamNoArgs), 0); OleCheck(ACollection.Invoke(DISPID_NEWENUM, GUID_NULL, 0, DISPATCH_METHOD or DISPATCH_PROPERTYGET, DispParamNoArgs, @EnumUnk, nil, @ArgErr)); FEnum := IUnknown(EnumUnk) as IEnumVariant; end; function TForEach.Next(const IID: TGUID; out Obj): Boolean; var Fetched: Cardinal; Element: OleVariant; Sts: HRESULT; begin Sts := FEnum.Next(1, PVariantArgList(@Element), @Fetched); Result := (Sts = S_OK); OleCheck(Sts); if Result then OleCheck(IUnknown(Element).QueryInterface(IID, Obj)); end; function TForEach.NextVar(out Obj: OleVariant): Boolean; var Disp: IDispatch; begin Result := Next(IDispatch, Disp); if Result then Obj := Disp else Obj := Unassigned; end; end. __________________________________________________ Delphi-Talk mailing list -> Delphi-Talk@elists.org http://www.elists.org/mailman/listinfo/delphi-talk