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 -> [email protected]
http://www.elists.org/mailman/listinfo/delphi-talk