使用ATL(VS2008)如何枚举给定IDispatch接口(IDispatch*)上可用的可用方法?我需要搜索一个具有特定名称的方法,一旦我有了DISPID,就调用该方法(我知道方法所采用的参数.)理想情况下,我想使用智能COM指针(CComPtr<>).
这可能吗?
Fra*_*nov 19
您可以IDispatch通过类型信息枚举公开的方法.有两种方法可以获取类型信息:
IDispatch::GetTypeInfo.遗憾的是,IDispatch实现没有义务提供有关其实现的方法和属性的类型信息.
但是,如果确实如此,那么基本枚举包括调用ITypeInfo::GetTypeAttr获取TYPEATTR接口并查看已实现的方法(cFuncs)和变量(cVars)的数量,并循环遍历这些并调用ITypeInfo::GetFuncDesc()或ITypeInfo::GetVarDesc().当然,你可以在这里列出更多细节,但是这应该是你探索的一个很好的起点.
这是一篇很好的文章,用VB.Net中的代码更详细地解释了这个过程.
小智 14
这里有一些代码用于枚举(它在地图中插入[Dispatch ID] - [Method Name]对,但这很容易改变).
///
/// \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;
}
Run Code Online (Sandbox Code Playgroud)
除非对象实现IDispatchEx,否则无法枚举所有可用方法.
但是,如果您知道要调用的方法的名称,则可以使用GetIDsOfNames将名称映射到正确的DISPID.
HRESULT hr;
CComPtr<IDispatch> dispatch;
DISPID dispid;
WCHAR *member = "YOUR-FUNCTION-NAME-HERE";
DISPPARAMS* dispparams;
// Get your pointer to the IDispatch interface on the object here. Also setup your params in dispparams.
hr = dispatch->GetIDsOfNames(IID_NULL, &member, 1, LOCALE_SYSTEM_DEFAULT, &dispid);
if (SUCCEEDED(hr)) {
hr = dispatch->Invoke(1, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, dispparams, &varResult, NULL, NULL);
}
Run Code Online (Sandbox Code Playgroud)
编辑:为了完整性,我怀疑有一种方法来询问ITypeInfo2接口(假设有一个对象的类型库),你可以从IDispatch :: GetTypeInfo获取方法列表,但我还没有这样做.看到另一个答案.
| 归档时间: |
|
| 查看次数: |
9739 次 |
| 最近记录: |