就拿MSHTML来说吧,比如说有以下两个接口:
IHTMLElement = interface(IDispatch)
IHTMLImgElement = interface(IDispatch)THtmlImgElement = class(TAutoIntfObject, IHtmlElement, IHtmlImgElement)
// ...
  constructor Create(...);
end;constructor THtmlImgElement.Create(...);
begin
  inherited Create(ComServer.TypeLib, IHTMLImgElement);
  // 实现的时候只能注册一个接口
end;这样的话,脚本语言调用的时候只能使用IHtmlImgElement接口而无法转换到IHtmlElement,因为脚本语言不能QueryInterface。请大家点拨一下,谢谢!

解决方案 »

  1.   

    怎么会
    HTML元素都支持双接口。脚本语言用的是IDispatch接口
      

  2.   

    比如说定义了三个接口
    IApplication = interface(IDispatch)
    //...
    function GetSelection: IDispatch; safecall; // 当前选中的对象,可能是本例中的File/ImageFile
    end;// IFile和IImageFile都继承自IDispatchIFile = interface(IDispatch)
    // ...
    property Created: TDateTime...
    property Modified: TDateTime...
    property Accessed: TDateTime...
    property FileName: WideString...
    end;IImageFile = interface(IDispatch)
    // ...
    property Width: Integer...
    property Height: Integer...
    end;以下是简单实现:
    Unit Application;
    // ...
    TApplication = class(TAutoObject, IApplication)
    // ...
    funciton GetSelection: IDispatch; safecall;
    end;funciton TApplication.GetSelection: IDispatch; safecall;
    begin
      Result := TImageFile.Create(Self, 'C:\Example.jpg'); // 假设选中的是个图片
    end;initialization
    TAutoObjectFactory.Create(ComServer, TApplication, Class_Application,
    ciMultiInstance, tmApartment);
    而File,Image则实现为如下:
    TFile = class(TAutoIntfObject, IFile)
    //...
      constructor Create(const app: IApplication; const fileName: WideString); overload;
    end;constructor TFile.Create(const app: IApplication; const fileName: WideString);
    begin
    inherited Create(ComServer.TypeLib, IFile);
    //...
    end;
    TImageFile = class(TFile, IFolder) // "实现继承",共享了TFile的代码
    //...
      constructor Create(const app: IApplication; const fileName: WideString); overload;
    end;constructor TImageFile.Create(const app: IApplication; const fileName: WideString);
    begin
      inherited Create(ComServer.TypeLib, IImageFile);  // 这里只能注册一个接口
    //...
    end;由于TImageFile只能注册一个接口IImageFile, 那么在调用IFile的属性的时候就会出现错误:
    <script language="javascript">
    var app = new ActiveXObject("Example.Application");
    var obj = app.GetSelection; // return TImageFile instance
    alert(obj.Width);  // OK
    alert(obj.FileName);  // Error
    </script>
      

  3.   

    貌似楼主Create方法里
    混淆Interface的GUID与 对象的GUID....
      

  4.   

    我记得网上有一种方法是声明一个隐藏接口来继承所有的属性,比如:
    _IImageFile = interface(IDispatch) // 保持函数签名及DispID一致
    //...
    property Created: TDateTime...
    property Modified: TDateTime...
    property Accessed: TDateTime...
    property FileName: WideString...
    //...
    property Width: Integer...
    property Height: Integer...
    end;然后更改TImageFile的构造函数为:
    inherited Create(ComServer.TypeLib, _IImageFile);但这样太麻烦了,不知道有没有更好的方法?还是说一般只要声明IImageFile=interface(IFile)就好了?
      

  5.   

    仅就楼主贴出的代码:IFile=interface(IDispatch)
    IImageFile=interface(IFile) //同时记住把类型库对应作修改,一处是继承关系,另一处是方法的ID值....
    Create(ComServer.TypeLib, IImageFile);
    ....这种方式我试过可行.
      

  6.   

    是的,我想这样应该能行。不过这样一来就会有很多接口继承自IIFile了,比如IDocument, IBook, IBook, etc. 要是以后再来个IFile2什么的,维护就很困难。不过目前先就这么着了,边走边看吧。谢谢了!