得到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;
                   CComBSTR bstrDocString;
                   
                   CComDispatchDriver dd(pDisp);
                   dd.GetProperty(pfd->memid, &varVal);
                   CProperty* pProp = new CProperty(pDisp, pfd->memid, varVal, vt, bstrDocString, spUserTypeInfo);
                   pProp->GetStringValue(&bstrVal);
                   
                   m_list.AddItem(nItem, 0, OLE2T(bStr));
                   m_list.AddItem(nItem, 1, OLE2T(bstrVal));
                   m_list.SetItemData(nItem, reinterpret_cast<DWORD>(pProp));
                   nItem++;
                 }
               }
               continue;
             }
    */
             COleVariant varVal;
             BSTR bstrVal;
             BSTR bstrName;
             BSTR bstrDocString;         pTypeInfo->GetDocumentation(pfd->memid, &bstrName, &bstrDocString, NULL, NULL);         DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
             pDispatch->Invoke(pfd->memid, IID_NULL,  LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET,
                 &dispparamsNoArgs, &varVal, NULL, NULL);         CProperty* pProp = new CProperty(pDispatch, pfd->memid, varVal, bstrDocString, pUserTypeInfo);
             pProp->GetStringValue((BSTR*)&bstrVal);
             
             CString strName = bstrName;
             CString strVal = bstrVal;         AddItem(nItem, 0, strName);
             AddItem(nItem, 1, strVal);         m_ListCtrl.SetItemData(nItem, reinterpret_cast<DWORD>(pProp));
             nItem++;
           }
         }
       }
       pTypeInfo->ReleaseFuncDesc(pfd);
     }
     pTypeInfo->ReleaseTypeAttr(pta);
     return S_OK;
      

  2.   

    HRESULT hr = pTypeInfo->GetRefTypeOfImplType(-1, &hRef);
    第一参数不是)0~n吗?
      

  3.   

    这里是笔误,应该是HRESULT hr = pTypeInfo->GetRefTypeOfImplType(1, &hRef);
      

  4.   

    获取出接口的ITYPEINFO,是否先取出接口的IID,再要求IPROVIDECLASSINFO接口,再后获取ITYPE接口,对吗?另外一个COCLASS可能有多接口(在IE相关的组件不少是这样的),如何得知是否有多个接口?如何获取?英语差,真是学什么都不容易。谢谢你kingzai,不管是否还有其它贴子都会给足分给你的。
      

  5.   

    你可以看看<<深入解析ATL》关于ITypeInfo的章节。
      

  6.   

    下了两个钟,又用了两个几钟草草看了一遍,结果还是没找到关于ITYPEINFO的章节,虽然没有细读,但里面写的和我想象的一样——主要是怎样实现COM,对于使用别人已写好的组件没有深入讨论。不过也学到不小东西,美中不足的是没不介绍OELDB方面内容。其实早就看下载了,只我这里网络不大好,93M实在是个大数字。