如何获取可从 IDispatch 访问的 Delphi 实例支持的所有接口?

问题描述 投票:0回答:1

动机:由于我在上一个问题中描述的努力,我得到了 IDispatch 指针 如何从 ExcelApplication Delphi COM 参考访问工作簿,目前没有任何? - 尝试访问所有打开的 Excel来自 Delphi 应用程序的实例。

问题:现在我猜测 IDispatch 点可以访问一些非常有用的接口——可能是 ActiveX ExcelApplication,可能是 Workbook、Worksheet 或其他一些接口。

我正在尝试使用代码检查 IDispatch 指针:

  IDisp: IDispatch;
  Report: TStringList;
  TypeInfo: ITypeInfo;
  TypeAttr: PTypeAttr;
  ii: Integer;
  RefTypeInfoCard: Cardinal;
  RefTypeInfo: ITypeInfo;
  RefTypeInfoAttr: PTypeAttr;
begin

  //...
  if Succeeded(IDisp.GetTypeInfo(0, 0, TypeInfo)) then begin
        // Get the TYPEATTR structure for the interface
        if Succeeded(TypeInfo.GetTypeAttr(TypeAttr)) then
        begin
          try
            // Loop through all of the supported interfaces and print their GUIDs
            for ii := 0 to TypeAttr.cImplTypes - 1 do
            begin
              if Succeeded(TypeInfo.GetRefTypeOfImplType(ii, RefTypeInfoCard)) then
              begin
                if Succeeded(TypeInfo.GetRefTypeInfo(RefTypeInfoCard, RefTypeInfo)) then
                begin
                  if Succeeded(RefTypeInfo.GetTypeAttr(RefTypeInfoAttr)) then
                  begin
                    Report.Add('     '+GUIDToString(RefTypeInfoAttr.guid));
                  end;
                end;
              end;
            end;
          finally
            TypeInfo.ReleaseTypeAttr(TypeAttr);
          end;
        end;
      end; 
end;

所以,我正在从 IDisp 读取 TypeInfo 并获取所有已实现的接口和每个接口的读取 TypeInfo,最后我得到了它们的 guid。

多么令人惊讶,但唯一可访问的界面是 GUID

{00020400-0000-0000-C000-000000000046}
这是 IDispatch 界面本身,如 https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-oaut/58504586-e4af- 44a3-be04-f1dc281b7429。所以,我的代码有了新的东西。

我的问题是 - 我如何重写我的代码以读取给定的指向 IDisapatch 接口的指针可访问的所有接口?

我使用的是 Delphi 6 和 Delphi 2009,但我想在最近的 Delphi 版本中情况也类似。

delphi com activex idispatch
1个回答
0
投票

很可能,我在问题中提供的代码已经在运行了。

我添加了以下检查,我正在执行以防

GUIDToString(TypeAttr.guid)
等于
{000208DA-0000-0000-C000-000000000046}

  IIWB: _Workbook;
begin
  //...
  IIWB:=nil;
  try
    Moniker.BindToObject(BindCtx, nil, IID__Workbook, IIWB);
    if IIWB=nil then begin
      //...
    end else begin
      //Do something important with Workbook, like IIWB.Close etc.
    end;
  except
    on E: Exception do begin
      //just in case...
    end;
  end;
  //...
end; 

所以,我假设,我的代码中的基本类型信息(

TypeInfo
TypeAttr
)是 IDispatch,我应该从
RefTypeInfo
RepTypeInfoAttr
中获得更精细(继承)的接口。我的假设是错误的,因为已经
TypeInfo
归因于返回的 GUID 等于以下内容:

Excel_TLB
IID__Workbook: TGUID = '{000208DA-0000-0000-C000-000000000046}';

所以,很可能我问题中的代码是正确的,但最浅层的TypeInfo指的是最幼稚的类型,而不是最基本的类型。

© www.soinside.com 2019 - 2024. All rights reserved.