HRESULT CCmdTarget::GetTypeInfoOfGuid(LCID lcid, REFGUID guid, LPTYPEINFO* ppTypeInfo) { USES_CONVERSION; AfxLockGlobals(CRIT_TYPELIBCACHE); HRESULT hr = TYPE_E_CANTLOADLIBRARY; CTypeLibCache* pTypeLibCache = GetTypeLibCache(); LPTYPELIB pTypeLib = NULL; // If type info is already cached, just return it. if (pTypeLibCache->LookupTypeInfo(lcid, guid, ppTypeInfo)) { hr = S_OK; } else { // If type library isn't already cached, try to locate it. if (!pTypeLibCache->Lookup(lcid, &pTypeLib)) { // First, try getting the subclass to load the type library // (normally this goes through LoadRegTypeLib). if (FAILED(GetTypeLib(lcid, &pTypeLib))) { AFX_MANAGE_STATE(m_pModuleState); // If that failed, try loading the type library from our own // resources. TCHAR szPath[_MAX_PATH]; GetModuleFileName(AfxGetInstanceHandle(), szPath, _MAX_PATH); if (FAILED(LoadTypeLib(T2COLE(szPath), &pTypeLib))) pTypeLib = NULL; } pTypeLibCache->Cache(lcid, pTypeLib); } // If we got a type library, extract the requested type info. if (pTypeLib != NULL) { hr = pTypeLib->GetTypeInfoOfGuid(guid, ppTypeInfo); pTypeLib->Release(); pTypeLibCache->CacheTypeInfo(lcid, guid, *ppTypeInfo); } } AfxUnlockGlobals(CRIT_TYPELIBCACHE); return hr; }
BOOL CTreeItem::Expand( HTREEITEM hitem ) { BOOL fExpand = FALSE ; switch(m_Type) { case typeUnknown: case typeUnknown2: break ; case typeTypeLib: fExpand = ExpandTypeLib( hitem ); break ; case typeTypeLib2: { // CTypeLibWnd::m_fGroupByType == TRUE CTreeItem* pItem ; TV_INSERTSTRUCT tvis ; tvis.hParent = hitem ; tvis.hInsertAfter = TVI_LAST ; tvis.item.mask = TVIF_TEXT | TVIF_CHILDREN | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE ; tvis.item.iImage = CTreeItem::typeUnknown ; tvis.item.iSelectedImage = tvis.item.iImage + 1 ; tvis.item.cChildren = 1 ; #pragma warning (suppress: 6211) // Not Leaking. pItem is inserted into m_pTree pItem = new CTreeItem(m_pTree) ; pItem->SetTypeLib( GetTypeLib() ) ; GetTypeLib()->AddRef() ; pItem->m_Type = CTreeItem::typeEnums ; tvis.item.lParam = (LPARAM)pItem ; tvis.item.pszText = _T("Enums") ; m_pTree->InsertItem(&tvis) ; pItem = new CTreeItem(m_pTree) ; pItem->SetTypeLib( GetTypeLib() ) ; GetTypeLib()->AddRef() ; pItem->m_Type = CTreeItem::typeRecords ; tvis.item.lParam = (LPARAM)pItem ; tvis.item.pszText = _T("Structs") ; m_pTree->InsertItem(&tvis) ; pItem = new CTreeItem(m_pTree) ; pItem->SetTypeLib( GetTypeLib() ) ; GetTypeLib()->AddRef() ; pItem->m_Type = CTreeItem::typeModules ; tvis.item.lParam = (LPARAM)pItem ; tvis.item.pszText = _T("Modules") ; m_pTree->InsertItem(&tvis) ; pItem = new CTreeItem(m_pTree) ; pItem->SetTypeLib( GetTypeLib() ) ; GetTypeLib()->AddRef() ; pItem->m_Type = CTreeItem::typeInterfaces ; tvis.item.lParam = (LPARAM)pItem ; tvis.item.pszText = _T("Interfaces") ; m_pTree->InsertItem(&tvis) ; pItem = new CTreeItem(m_pTree) ; pItem->SetTypeLib( GetTypeLib() ) ; GetTypeLib()->AddRef() ; pItem->m_Type = CTreeItem::typeDispinterfaces ; tvis.item.lParam = (LPARAM)pItem ; tvis.item.pszText = _T("Dispinterfaces") ; m_pTree->InsertItem(&tvis) ; pItem = new CTreeItem(m_pTree) ; pItem->SetTypeLib( GetTypeLib() ) ; GetTypeLib()->AddRef() ; pItem->m_Type = CTreeItem::typeCoClasses ; tvis.item.lParam = (LPARAM)pItem ; tvis.item.pszText = _T("CoClasses") ; m_pTree->InsertItem(&tvis) ; pItem = new CTreeItem(m_pTree) ; pItem->SetTypeLib( GetTypeLib() ) ; GetTypeLib()->AddRef() ; pItem->m_Type = CTreeItem::typeAliases ; tvis.item.lParam = (LPARAM)pItem ; tvis.item.pszText = _T("Typedefs") ; m_pTree->InsertItem(&tvis) ; pItem = new CTreeItem(m_pTree) ; pItem->SetTypeLib( GetTypeLib() ) ; GetTypeLib()->AddRef() ; pItem->m_Type = CTreeItem::typeUnions ; tvis.item.lParam = (LPARAM)pItem ; tvis.item.pszText = _T("Unions") ; m_pTree->InsertItem(&tvis) ; fExpand = TRUE ; } break ; case typeEnums: case typeRecords: case typeModules: case typeInterfaces: case typeDispinterfaces: case typeCoClasses: case typeAliases: case typeUnions: fExpand = ExpandTypeLib( hitem ) ; break ; case typeTypeInfo: case typeTypeInfo2: case typeEnum: case typeRecord: case typeModule: case typeInterface: case typeDispinterface: case typeCoClass: case typeAlias: case typeUnion: fExpand = ExpandTypeInfo( hitem ) ; break ; case typeMethods: case typeMethods2: fExpand = ExpandFuncs( hitem ) ; break ; case typeProperties: case typeProperties2: case typeConstants: case typeConstants2: fExpand = ExpandVars( hitem ) ; break ; case typeImplTypes: case typeImplTypes2: fExpand = ExpandImplTypes( hitem ) ; break ; case typeMethod: case typeProperty: case typeConstant: default: break ; } return fExpand ; }
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 ; }