Hi Andrew On Thu, Nov 26, 2009 at 4:48 AM, Andrew Hall <andrew.h...@shaw.ca> wrote:
> 1) Always reference your host class through an interface you know will be > implemented by the host class, therefore calling "as" from this interface > will always find any of the interfaces your class may support. The easiest > would be to declare "I1: IUnknown" in the code below - I haven't tried it > but that should work. > Yes. At first of this too. > > 2) Store the host class reference in the other classes that implement the > host and provide an "Owner: IUnknown" property in your "child" implementing > classes to allow you to cast to any interface supported by the host class: > "I2 := I1.Owner as IIntf2" > > And that's my current solution for some classes :) > PS - normally your host class would not support the interface you are using > "implements" to achieve... Normally yes. Unfortunately it's not my case. > therefore the confusing circumstances of your first example would not > normally happen - you'd be more likely to see this second example which is a > little easier to decipher... > > Regards, > > Andrew Hall. But I think I found a better solution. The only way that needed to be changed is the way of QueryInterface works. I just took the idea with Owner and redefined QueryInterface method to use it. Like following: { TInterfacedObj } TInterfacedObj = class(TObject, IUnknown) private FOwner:TInterfacedObj; function GetInterface(const iid : tguid;out obj):longint; public function QueryInterface(const iid : tguid;out obj) : longint;virtual;stdcall; function _AddRef : longint;stdcall; function _Release : longint;stdcall; constructor Create(Owner:TInterfacedObj); end; { TInterfacedObj } const Err = HResult($80004002); function TInterfacedObj.GetInterface(const iid: tguid; out obj): longint; begin if inherited GetInterface(IID, Obj) then Result:=0 else Result:=Err; end; function TInterfacedObj.QueryInterface(const iid: tguid; out obj): longint;stdcall; begin WriteLn('QueryInterface ', ClassName); if FOwner = nil then Result:=GetInterface(iid, obj) else begin Result:=FOwner.QueryInterface(iid, obj); //try to find interface in itself if Result = Err then Result:=GetInterface(iid, obj); end; end; constructor TInterfacedObj.Create(Owner: TInterfacedObj); begin FOwner:=Owner; end; Now it is possible to start interface search from the owner and only if owner has no appropriate interface, it queries itself. That's seems pretty nice solution. -- Best regards, Denis Golovan
_______________________________________________ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal