Using ATL (VS2008) how can I enumerate the available methods available on a given IDispatch interface (IDispatch*
)? I need to search for a method with a specific name and, once I have the DISPID
, invoke the method (I know the parameters the method takes.) Ideally I would like to do this using smart COM pointers (CComPtr<>
).
Is this possible?
You can enumerate the methods an IDispatch
exposes through the type info. There are two ways to get the type info:
IDispatch::GetTypeInfo
.Unfortunately, an IDispatch
implementation is not obligated to provide type info about the methods and properties it implements.
If it does, however, the basic enumerating involves calling ITypeInfo::GetTypeAttr
to get the TYPEATTR
for the interface and looking at the number of implemented methods (cFuncs
) and variables (cVars
) and looping over these and calling ITypeInfo::GetFuncDesc()
or ITypeInfo::GetVarDesc()
. Of course, there are lot more details you will have to deal with as I can list here, but this should be a good starting point for your exploration.
Here's a nice article explaining the process in more details with code in VB.Net.
Here's some code that does the enumeration (it inserts the [Dispatch ID]-[Method Name] pairs in a map, but that's easy to change).
///
/// \brief Returns a map of [DispId, Method Name] for the passed-in IDispatch object
///
HRESULT COMTools::GetIDispatchMethods(_In_ IDispatch * pDisp,
_Out_ std::map<long, std::wstring> & methodsMap)
{
HRESULT hr = S_OK;
CComPtr<IDispatch> spDisp(pDisp);
if(!spDisp)
return E_INVALIDARG;
CComPtr<ITypeInfo> spTypeInfo;
hr = spDisp->GetTypeInfo(0, 0, &spTypeInfo);
if(SUCCEEDED(hr) && spTypeInfo)
{
TYPEATTR *pTatt = nullptr;
hr = spTypeInfo->GetTypeAttr(&pTatt);
if(SUCCEEDED(hr) && pTatt)
{
FUNCDESC * fd = nullptr;
for(int i = 0; i < pTatt->cFuncs; ++i)
{
hr = spTypeInfo->GetFuncDesc(i, &fd);
if(SUCCEEDED(hr) && fd)
{
CComBSTR funcName;
spTypeInfo->GetDocumentation(fd->memid, &funcName, nullptr, nullptr, nullptr);
if(funcName.Length()>0)
{
methodsMap[fd->memid] = funcName;
}
spTypeInfo->ReleaseFuncDesc(fd);
}
}
spTypeInfo->ReleaseTypeAttr(pTatt);
}
}
return hr;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With