Hi Andrew<br><br><div class="gmail_quote">On Thu, Nov 26, 2009 at 4:48 AM, Andrew Hall <span dir="ltr"><<a href="mailto:andrew.hall@shaw.ca">andrew.hall@shaw.ca</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
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.<br>
</blockquote><div><br></div><div>Yes. At first of this too.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<br>
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"<br>

<br></blockquote><div><br></div><div>And that's my current solution for some classes :)</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
PS - normally your host class would not support the interface you are using "implements" to achieve... </blockquote><div><br></div><div>Normally yes. Unfortunately it's not my case.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
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...<br>
<br>
Regards,<br>
<font color="#888888"><br>
Andrew Hall.</font></blockquote><div><br></div><div>But I think I found a better solution. The only way that needed to be changed is the way of QueryInterface works.</div><div>I just took the idea with Owner and redefined QueryInterface method to use it. Like following:</div>
<div><div><br></div><div>  { TInterfacedObj }</div><div><br></div><div>  TInterfacedObj = class(TObject, IUnknown)</div><div>    private</div><div>      FOwner:TInterfacedObj;</div><div><br></div><div>      function GetInterface(const iid : tguid;out obj):longint;</div>
<div>    public</div><div>      function QueryInterface(const iid : tguid;out obj) : longint;virtual;stdcall;</div><div>      function _AddRef : longint;stdcall;</div><div>      function _Release : longint;stdcall;</div><div>
<br></div><div>      constructor Create(Owner:TInterfacedObj);</div><div>  end;</div><div>  { TInterfacedObj }</div><div><br></div><div>  const Err = HResult($80004002);</div><div>  function TInterfacedObj.GetInterface(const iid: tguid; out obj): longint;</div>
<div>  begin</div><div>    if inherited GetInterface(IID, Obj) then</div><div>      Result:=0</div><div>    else</div><div>      Result:=Err;</div><div>  end;</div><div><br></div><div>  function TInterfacedObj.QueryInterface(const iid: tguid; out obj): longint;stdcall;</div>
<div>  begin</div><div>    WriteLn('QueryInterface ', ClassName);</div><div><br></div><div>    if FOwner = nil then</div><div>      Result:=GetInterface(iid, obj)</div><div>      else</div><div>      begin</div><div>
        Result:=FOwner.QueryInterface(iid, obj);</div><div><br></div><div>        //try to find interface in itself</div><div>        if Result = Err then</div><div>           Result:=GetInterface(iid, obj);</div><div>      end;</div>
<div>  end;</div><div><br></div><div>  constructor TInterfacedObj.Create(Owner: TInterfacedObj);</div><div>  begin</div><div>    FOwner:=Owner;</div><div>  end;</div><div><br></div></div><div>Now it is possible to start interface search from the owner and only if owner has no appropriate interface, it queries itself.</div>
<div>That's seems pretty nice solution. </div></div><br clear="all"><br>-- <br>Best regards,<br>Denis Golovan<br>