动机:由于我在上一个问题中描述的努力,我得到了 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 版本中情况也类似。
很可能,我在问题中提供的代码已经在运行了。
我添加了以下检查,我正在执行以防
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指的是最幼稚的类型,而不是最基本的类型。