0

Motivation: I got IDispatch pointer as a result of my efforts that I have described in my previous question How to access workbooks from the ExcelApplication Delphi COM reference, currently there is no any? - trying to access all the open Excel instances from Delphi application.

Problem: Now I am guessing that IDispatch point could give access to some very useful interfaces - maybe ActiveX ExcelApplication, maybe Workbook, Worksheet or some other interface.

I am trying to inspect IDispatch pointer with the code:

  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;

So, I am reading TypeInfo from IDisp and get all the implemented interfaces and the reading TypeInfor for each of those interfaces and at last I am getting guid of the them.

What a surprise, but only accessible interface is with GUID {00020400-0000-0000-C000-000000000046} which is IDispatch interface itself as described in https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-oaut/58504586-e4af-44a3-be04-f1dc281b7429 . So, I am getting anything new with my code.

My question is - how can I rewrite my code to read all the interfaces that are accessible by the given pointer to IDisapatch interface?

I am using Delphi 6 and Delphi 2009, but I guess that the situation is similar in more recent Delphi editions as well.

TomR
  • 2,696
  • 6
  • 34
  • 87

1 Answers1

0

Most likely, my code that I have provided in the question is already working.

I added the following check, which I am executing in case GUIDToString(TypeAttr.guid) is equal to {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; 

So, I assumed, that the base type information (TypeInfo, TypeAttr) in my code is IDispatch and the I should get more refined (inherited) interfaces in from RefTypeInfo, RepTypeInfoAttr. My assumption was false, because already TypeInfo attributed returned GUID which was equal to the following:

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

So, most likely the code in my question is correct, but the most shallow TypeInfo refers to the most childish type, not the most base type.

TomR
  • 2,696
  • 6
  • 34
  • 87