Если объект "вполне стандартный", то это должно быть возможно.
Из интерфейса object/IDispatch вы сможете получить доступ к TLB (библиотеке типов). В библиотеке типов вы должны иметь возможность просматривать все составные классы и получать интерфейсы, реализуемые этими составными классами. Вам нужно перейти к интерфейсу, для которого у вас есть IID, просмотреть члена и получить интересующий вас.
Есть много случаев, когда это просто не сработает. Вот созданный мной пример консоли, который работает с объектом оболочки. Я написал это на C#, потому что это проще, но нет ничего, что вы не могли бы сделать с приличным языком. Я использовал старую служебную библиотеку TLBINF32.DLL com (к сожалению, только x86), о которой я говорю в своем ответе на этот вопрос здесь, на SO: Как читать COM TypeLib с C# или 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;
}
20.11.2014