BOOL CTreeItem::ExpandTypeInfo( HTREEITEM hitem ) { ASSERT(m_pTree) ; ASSERT(hitem) ; CTreeItem* pNewItem = NULL ; HRESULT hr = S_OK ; TV_INSERTSTRUCT tvis ; CString strError = "Enumerating TypeInfo" ; TYPEATTR* pattr = NULL ; ITypeInfo* pti = GetTypeInfo() ; ASSERT(pti) ; BOOL fExpand = FALSE ; tvis.hParent = hitem ; tvis.hInsertAfter = TVI_LAST ; tvis.item.mask = TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_CHILDREN ; tvis.item.iImage = typeUnknown ; tvis.item.iSelectedImage = tvis.item.iImage + 1 ; TRY { ENSURE(pti); hr = pti->GetTypeAttr(&pattr) ; if FAILED(hr) { strError.Format(_T("ITypeInfo::GetTypeAttr() failed"), hr ) ; AfxThrowMemoryException() ; } switch(pattr->typekind) { // typedef [attributes] enum [tag] { // enumlist // } enumname; // // "typedef enum enumname" case TKIND_ENUM: fExpand = ExpandVars( hitem ) ; break ; // typedef [attributes] // struct [tag] { // memberlist // } structname; // // "typedef struct structname" case TKIND_RECORD: fExpand = ExpandVars( hitem ) ; break ; // [attributes] // module modulename { // elementlist // }; case TKIND_MODULE: if (pattr->cVars) { // Add "Constants" folder // #pragma warning (suppress: 6211) #pragma warning (suppress: 6014) pNewItem = new CTreeItem(m_pTree) ; pNewItem->m_Type = typeProperties ; pNewItem->SetTypeInfo(pti) ; pti->AddRef() ; tvis.item.cChildren = pattr->cVars ; tvis.item.lParam = (LPARAM)pNewItem ; tvis.item.pszText = _T("Constants") ; tvis.item.iImage = typeConstants ; tvis.item.iSelectedImage = tvis.item.iImage + 1 ; m_pTree->InsertItem( &tvis ) ; fExpand = TRUE ; } if (pattr->cFuncs) { pNewItem = new CTreeItem(m_pTree) ; pNewItem->m_Type = typeMethods ; pNewItem->SetTypeInfo(pti) ; pti->AddRef() ; tvis.item.cChildren = pattr->cFuncs ; tvis.item.lParam = (LPARAM)pNewItem ; tvis.item.pszText = _T("Functions") ; tvis.item.iImage = typeMethods ; tvis.item.iSelectedImage = tvis.item.iImage + 1 ; m_pTree->InsertItem( &tvis ) ; fExpand = TRUE ; } break ; // [attributes] // interface interfacename [:baseinterface] { // functionlist // }; case TKIND_INTERFACE: fExpand = ExpandFuncs( hitem) ; if (pattr->cImplTypes) { pNewItem = new CTreeItem(m_pTree) ; pNewItem->m_Type = typeImplTypes ; pNewItem->SetTypeInfo(pti) ; pti->AddRef() ; tvis.item.pszText = _T("Inherited Interfaces") ; tvis.item.iImage = typeInterface ; tvis.item.cChildren = pattr->cImplTypes ; tvis.item.lParam = (LPARAM)pNewItem ; tvis.item.iSelectedImage = tvis.item.iImage ; m_pTree->InsertItem( &tvis ) ; fExpand = TRUE ; } break ; // [attributes] // dispinterface intfname { // interface interfacename // }; case TKIND_DISPATCH : if (pattr->cVars) { // Add "Constants" folder // pNewItem = new CTreeItem(m_pTree) ; pNewItem->m_Type = typeConstants ; pNewItem->SetTypeInfo(pti) ; pti->AddRef() ; tvis.item.cChildren = pattr->cVars ; tvis.item.lParam = (LPARAM)pNewItem ; tvis.item.pszText = _T("Constants") ; tvis.item.iImage = typeConstants ; tvis.item.iSelectedImage = tvis.item.iImage + 1 ; m_pTree->InsertItem( &tvis ) ; // Add "Properties" folder // pNewItem = new CTreeItem(m_pTree) ; pNewItem->m_Type = typeProperties ; pNewItem->SetTypeInfo(pti) ; pti->AddRef() ; tvis.item.cChildren = pattr->cVars ; tvis.item.lParam = (LPARAM)pNewItem ; tvis.item.pszText = _T("Properties") ; tvis.item.iImage = typeProperties ; tvis.item.iSelectedImage = tvis.item.iImage + 1 ; m_pTree->InsertItem( &tvis ) ; fExpand = TRUE ; } if (pattr->cFuncs) { pNewItem = new CTreeItem(m_pTree) ; pNewItem->m_Type = typeMethods ; pNewItem->SetTypeInfo(pti) ; pti->AddRef() ; tvis.item.cChildren = pattr->cFuncs ; tvis.item.lParam = (LPARAM)pNewItem ; tvis.item.pszText = _T("Methods") ; tvis.item.iImage = typeMethods ; tvis.item.iSelectedImage = tvis.item.iImage + 1 ; m_pTree->InsertItem( &tvis ) ; fExpand = TRUE ; } if (pattr->cImplTypes) { pNewItem = new CTreeItem(m_pTree) ; pNewItem->m_Type = typeImplTypes ; pNewItem->SetTypeInfo(pti) ; pti->AddRef() ; tvis.item.pszText = _T("Inherited Interfaces") ; tvis.item.iImage = typeInterface ; tvis.item.cChildren = pattr->cImplTypes ; tvis.item.lParam = (LPARAM)pNewItem ; tvis.item.iSelectedImage = tvis.item.iImage ; m_pTree->InsertItem( &tvis ) ; fExpand = TRUE ; } break ; // [attributes] // coclass classname { // [attributes2] [interface | dispinterface] interfacename; // ... // }; case TKIND_COCLASS: fExpand = ExpandImplTypes( hitem ) ; break ; // typedef [attributes] basetype aliasname; case TKIND_ALIAS: if (pattr->tdescAlias.vt == VT_USERDEFINED) { ITypeInfo* ptiRefType = NULL ; #pragma warning (suppress: 6246) HRESULT hr = pti->GetRefTypeInfo( pattr->tdescAlias.hreftype, &ptiRefType ) ; if (FAILED(hr)) AfxThrowOleException( hr ) ; pNewItem = new CTreeItem(m_pTree) ; pNewItem->SetTypeInfo( ptiRefType ) ; pNewItem->m_Type = TypeKindToItemType( pNewItem->GetTypeKind() ) ; tvis.item.iImage = TypeKindToItemType( pNewItem->GetTypeKind() ) ; tvis.item.cChildren = 1 ; tvis.item.lParam = (LPARAM)pNewItem ; tvis.item.iSelectedImage = tvis.item.iImage ; CString sName; pNewItem->GetName(sName, TRUE ); tvis.item.pszText = sName.GetBuffer(0) ; m_pTree->InsertItem( &tvis ) ; sName.ReleaseBuffer(); fExpand = TRUE ; } break ; // typedef [attributes] union [tag] { // memberlist // } unionname; case TKIND_UNION: fExpand = ExpandVars( hitem ) ; break ; default: break ; } if (pattr) pti->ReleaseTypeAttr( pattr ) ; } CATCH(CException, pException) { ErrorMessage( strError, hr ) ; if (pNewItem) delete pNewItem ; if (pattr) pti->ReleaseTypeAttr( pattr ) ; return FALSE ; }
BOOL CTreeItem::ExpandTypeLib( HTREEITEM hitem ) { ASSERT(hitem) ; CTreeItem* pNewItem = NULL ; UINT uiTypeInfoCount = GetTypeLib()->GetTypeInfoCount() ; HRESULT hr = S_OK ; TV_INSERTSTRUCT tvis ; CString strError = "Enumerating typeinfos"; TYPEATTR* pattr = NULL ; BOOL fExpand = FALSE ; tvis.hParent = hitem ; tvis.hInsertAfter = TVI_LAST ; tvis.item.mask = TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_CHILDREN ; tvis.item.cChildren = 1 ; TRY { for (UINT n = 0 ; n < uiTypeInfoCount ; n++) { #pragma warning (suppress: 6014) pNewItem = new CTreeItem( m_pTree ) ; pNewItem->m_Type = typeTypeInfo ; ASSERT(pNewItem) ; tvis.item.lParam = (LPARAM)pNewItem ; hr = GetTypeLib()->GetTypeInfo( n, (ITypeInfo**)&pNewItem->m_punk ) ; if (FAILED(hr)) { strError.Format(_T("Could not get TypeInfo #%u"), n ) ; AfxThrowOleException(hr) ; } ASSERT(pNewItem->m_punk) ; hr = pNewItem->GetTypeInfo()->GetTypeAttr(&pattr) ; if FAILED(hr) { strError.Format(_T("ITypeInfo::GetTypeAttr() failed") ) ; AfxThrowOleException(hr) ; } if ((m_Type == typeTypeLib) || (m_Type == (TypeKindToItemType(pattr->typekind) + 8))) { tvis.item.iImage = pattr->typekind + typeEnum ; tvis.item.iSelectedImage = tvis.item.iImage ; CString sName; pNewItem->GetName(sName, TRUE ); tvis.item.pszText = sName.GetBuffer(0); m_pTree->InsertItem( &tvis ) ; sName.ReleaseBuffer(); pNewItem->GetTypeInfo()->ReleaseTypeAttr( pattr ) ; fExpand = TRUE ; } else { pNewItem->GetTypeInfo()->ReleaseTypeAttr( pattr ) ; delete pNewItem ; } } } CATCH(CException, pException) { if (pException->IsKindOf(RUNTIME_CLASS(COleException))) ErrorMessage( strError, ((COleException*)pException)->m_sc ) ; else ErrorMessage( strError, hr ) ; if (pNewItem) delete pNewItem ; return FALSE ; } END_CATCH return fExpand ; }