我坚持这个。
给出三个变量:
IDispatch*
到可连接对象IID
(DIID)如何将名称解析为DISPID?
pDispatch->GetIDsOfNames(...)
返回DISP_E_UNKNOWNNAME
,正如我所料(可连接对象未实现传出接口)GetIDsOfNames
(我甚至不确定这个会工作)ITypeInfo
。我可以从coclass的ITypeInfo
得到这个。但是pDispatch->GetTypeInfo(0, ...)
会返回ITypeInfo
实现的IDispatch
(根据文档),而不是coclass的ITypeInfo
。 (并且此对象的ITypeInfo
实现没有公开其他IDispatch
。)答案 0 :(得分:0)
如果对象是“非常标准”,那么它应该是可能的。
从object / IDispatch接口,您应该能够访问TLB(类型库)。从类型库中,您应该能够浏览所有coclass,并获得这些coclass实现的接口。您需要进入具有IID的界面,浏览该成员并获得您感兴趣的成员。
在许多情况下,这是行不通的。这是我提出的一个控件示例,它与shell对象一起使用。我用C#编写它是因为它更容易,但是对于一个体面的语言来说,没有什么是你无法做到的。我使用了一个旧的TLBINF32.DLL com实用程序库(不幸的是只有x86)我在这里谈到这个问题的答案: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;
}