描述:
得到ITYPEINFO指针后,如何获得像VB中的对象浏览器的对象列表、方法列表、事件列表、属性列表及其参数?代码、接口函数说明都可以。thank you
解决方案1:
控件的属性列表则通过控件的TypeInfo接口可以得到,得到Dispatch接口指针后,调用
GetTypeInfoCount,往往返回1,或2,第一个接口就是属性和方法的描述,第2个ITypeInfo
接口可能是事件描述的接口,然后调用GetTypeInfo?(可能是吧)得到ITypeInfo接口,
调用ITypeInfo的函数,然后获得函数的数量,根据每一个函数的描述来判断是属性(还分get和put)
还是方法,然后取得该属性的名称,DISPID(Dispatch ID,或称MemberID)
BOOL CPropertyWnd::AddDispatch(IUnknown* pIUnknown)
{
IDispatch *pDispatch;
pIUnknown->QueryInterface(IID_IDispatch, (void **)&pDispatch);
ITypeInfo *pTypeInfo;
if (pDispatch == NULL)
return FALSE;
pDispatch->GetTypeInfo(0, LOCALE_SYSTEM_DEFAULT, &pTypeInfo);
if (pTypeInfo == NULL)
return FALSE;
TYPEATTR* pta;
pTypeInfo->GetTypeAttr(&pta);
if (pta->typekind == TKIND_INTERFACE)
{
// 取得第二个接口
ITypeInfo *pInfoTemp;
HREFTYPE hRef;
HRESULT hr = pTypeInfo->GetRefTypeOfImplType(-1, &hRef);
if (FAILED(hr))
return FALSE;
hr = pTypeInfo->GetRefTypeInfo(hRef, &pInfoTemp);
if (FAILED(hr))
return FALSE;
pTypeInfo->ReleaseTypeAttr(pta);
pTypeInfo = pInfoTemp;
pTypeInfo->GetTypeAttr(&pta);
}
int nItem = m_ListCtrl.GetItemCount();
for (int i = 0; i < pta->cFuncs; i++)
{
FUNCDESC* pfd;
pTypeInfo->GetFuncDesc(i, &pfd);
if (pfd->invkind & DISPATCH_PROPERTYGET
&& (pfd->wFuncFlags & (FUNCFLAG_FRESTRICTED | FUNCFLAG_FHIDDEN)) == 0)
{
switch (pfd->elemdescFunc.tdesc.vt)
{
case VT_USERDEFINED:
case VT_EMPTY:
case VT_NULL:
case VT_I2:
case VT_I4:
case VT_R4:
case VT_R8:
case VT_CY:
case VT_DATE:
case VT_BSTR:
case VT_ERROR:
case VT_BOOL:
case VT_VARIANT:
case VT_DECIMAL:
case VT_I1:
case VT_UI1:
case VT_UI2:
case VT_UI4:
case VT_INT:
case VT_UINT:
case VT_PTR:
{
ITypeInfo* pUserTypeInfo = NULL;
VARTYPE vt;
vt = pfd->elemdescFunc.tdesc.vt;
if (pfd->elemdescFunc.tdesc.vt == VT_USERDEFINED)
{
HREFTYPE hrt = pfd->elemdescFunc.tdesc.hreftype;
vt = VT_USERDEFINED;
HRESULT hr = E_FAIL;
hr = GetEnumTypeInfo(pTypeInfo, hrt, &pUserTypeInfo);
if(FAILED(hr))
vt = GetUserDefinedType(pTypeInfo, hrt);
}
/* if (pfd->elemdescFunc.tdesc.vt == VT_PTR)
{
HREFTYPE hrt = pfd->elemdescFunc.tdesc.lptdesc->hreftype;
VARTYPE vt = pfd->elemdescFunc.tdesc.lptdesc->vt;
if (SUCCEEDED(pTypeInfo->GetRefTypeInfo(hrt, &pUserTypeInfo)))
{
ITypeLib *pITypeLib;
UINT nIndex = NULL;
if (SUCCEEDED(pUserTypeInfo.p->GetContainingTypeLib(&pITypeLib, &nIndex)))
{
CComBSTR bStr = NULL;
pITypeLib.p->GetDocumentation(nIndex, &bStr, NULL, NULL, NULL);
if (bStr == "IFontDisp")
bStr = "Font";
else if (bStr == "IPictureDisp")
bStr = "Picture";
else
continue;
CComVariant varVal;
CComBSTR bstrVal;
&