如果对象是“相当标准的”,那么它应该是可能的。
从 object/IDispatch 接口,您应该能够访问 TLB(类型库)。从类型库中,您应该能够浏览所有 coclass,并获得这些 coclass 实现的接口。您需要进入您拥有 IID 的界面,浏览会员并获取您感兴趣的会员。
在很多情况下,这根本行不通。这是我提出的与 shell 对象一起使用的控制台示例。我用 C# 编写了它,因为它更容易,但没有什么是你不能用体面的语言做的。我使用了一个旧的 TLBINF32.DLL com 实用程序库(不幸的是只有 x86)我在我对这个问题的回答中谈到了 SO:How to read COM TypeLib with C# or C++?
static void Main(string[] args)
{
// create a sample object every one has
object o = Activator.CreateInstance(Type.GetTypeFromProgID("shell.application")); // for example
TLIApplication app = new TLIApplication();
// not sure, but I believe in pure COM it's calling IDispatch::GetTypeInfo & ITypeInfo::GetContainingTypeLib
TypeLibInfo tli = app.InterfaceInfoFromObject(o).Parent;
// this is the guid for DShellFolderViewEvents
int dispid = GetDispId(tli, new Guid("{62112AA2-EBE4-11CF-A5FB-0020AFE7292D}"), "SelectionChanged");
Console.WriteLine("dispid:" + dispid); // should display 200
}
public static int GetDispId(TypeLibInfo tlb, Guid diid, string memberName)
{
// browse all coclasses
// in pure COM this is ITypeLib::GetTypeInfo
foreach (CoClassInfo ti in tlb.CoClasses)
{
// browse all interfaces in those coclasses
// in pure COM this is ITypeInfo::GetRefTypeOfImplType
foreach (InterfaceInfo itf in ti.Interfaces)
{
// only select [source] interfaces (events)
// this test is optional since the diid is unique
// in pure COM this is ITypeInfo::GetImplTypeFlags
if (((ImplTypeFlags)itf.AttributeMask & ImplTypeFlags.IMPLTYPEFLAG_FSOURCE) != ImplTypeFlags.IMPLTYPEFLAG_FSOURCE)
continue;
if (new Guid(itf.GUID) == diid)
{
// in pure COM this is ITypeInfo::GetTypeAttr & ITypeInfo::GetFuncDesc
foreach (MemberInfo mi in itf.Members)
{
if (mi.Name == memberName)
return mi.MemberId;
}
}
}
}
return -1;
}