TREE.CPP
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:28k
源码类别:

Windows编程

开发平台:

Visual C++

  1. // tree.cpp
  2. //
  3. // This is a part of the Microsoft Foundation Classes C++ library.
  4. // Copyright (C) 1992-1998 Microsoft Corporation
  5. // All rights reserved.
  6. //
  7. // This source code is only intended as a supplement to the
  8. // Microsoft Foundation Classes Reference and related
  9. // electronic documentation provided with the library.
  10. // See these sources for detailed information regarding the
  11. // Microsoft Foundation Classes product.
  12. #include "stdafx.h"
  13. #include "tree.h"
  14. #include "util.h"
  15. #define MAX_NAMES   64
  16. IMPLEMENT_DYNCREATE(CTreeItem, CObject)
  17. CTreeItem::CTreeItem(CTreeCtrl* pTree )
  18. {
  19. ASSERT(pTree) ;
  20. m_pTree = pTree ;
  21. m_punk = NULL ;
  22. m_Type = typeUnknown ;
  23. m_uiMemid = 0 ;
  24. }
  25. CTreeItem::~CTreeItem()
  26. {
  27. if (m_punk )
  28. m_punk->Release()  ;
  29. }
  30. BOOL CTreeItem::Expand( HTREEITEM hitem )
  31. {
  32. BOOL fExpand = FALSE ;
  33. switch(m_Type)
  34. {
  35. case typeUnknown:
  36. case typeUnknown2:
  37. break ;
  38. case typeTypeLib:
  39. fExpand = ExpandTypeLib( hitem );
  40. break ;
  41. case typeTypeLib2:
  42. {
  43. // CTypeLibWnd::m_fGroupByType == TRUE
  44. CTreeItem* pItem ;
  45. TV_INSERTSTRUCT tvis ;
  46. tvis.hParent = hitem ;
  47. tvis.hInsertAfter = TVI_LAST ;
  48. tvis.item.mask = TVIF_TEXT | TVIF_CHILDREN | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE ;
  49. tvis.item.iImage = CTreeItem::typeUnknown ;
  50. tvis.item.iSelectedImage = tvis.item.iImage + 1 ;
  51. tvis.item.cChildren = 1 ;
  52. pItem = new CTreeItem(m_pTree) ;
  53. pItem->SetTypeLib( GetTypeLib() ) ;
  54. GetTypeLib()->AddRef() ;
  55. pItem->m_Type = CTreeItem::typeEnums ;
  56. tvis.item.lParam = (LPARAM)pItem ;
  57. tvis.item.pszText = _T("Enums") ;
  58. m_pTree->InsertItem(&tvis) ;
  59. pItem = new CTreeItem(m_pTree) ;
  60. pItem->SetTypeLib( GetTypeLib() ) ;
  61. GetTypeLib()->AddRef() ;
  62. pItem->m_Type = CTreeItem::typeRecords ;
  63. tvis.item.lParam = (LPARAM)pItem ;
  64. tvis.item.pszText = _T("Structs") ;
  65. m_pTree->InsertItem(&tvis) ;
  66. pItem = new CTreeItem(m_pTree) ;
  67. pItem->SetTypeLib( GetTypeLib() ) ;
  68. GetTypeLib()->AddRef() ;
  69. pItem->m_Type = CTreeItem::typeModules ;
  70. tvis.item.lParam = (LPARAM)pItem ;
  71. tvis.item.pszText = _T("Modules") ;
  72. m_pTree->InsertItem(&tvis) ;
  73. pItem = new CTreeItem(m_pTree) ;
  74. pItem->SetTypeLib( GetTypeLib() ) ;
  75. GetTypeLib()->AddRef() ;
  76. pItem->m_Type = CTreeItem::typeInterfaces ;
  77. tvis.item.lParam = (LPARAM)pItem ;
  78. tvis.item.pszText = _T("Interfaces") ;
  79. m_pTree->InsertItem(&tvis) ;
  80. pItem = new CTreeItem(m_pTree) ;
  81. pItem->SetTypeLib( GetTypeLib() ) ;
  82. GetTypeLib()->AddRef() ;
  83. pItem->m_Type = CTreeItem::typeDispinterfaces ;
  84. tvis.item.lParam = (LPARAM)pItem ;
  85. tvis.item.pszText = _T("Dispinterfaces") ;
  86. m_pTree->InsertItem(&tvis) ;
  87. pItem = new CTreeItem(m_pTree) ;
  88. pItem->SetTypeLib( GetTypeLib() ) ;
  89. GetTypeLib()->AddRef() ;
  90. pItem->m_Type = CTreeItem::typeCoClasses ;
  91. tvis.item.lParam = (LPARAM)pItem ;
  92. tvis.item.pszText = _T("CoClasses") ;
  93. m_pTree->InsertItem(&tvis) ;
  94. pItem = new CTreeItem(m_pTree) ;
  95. pItem->SetTypeLib( GetTypeLib() ) ;
  96. GetTypeLib()->AddRef() ;
  97. pItem->m_Type = CTreeItem::typeAliases ;
  98. tvis.item.lParam = (LPARAM)pItem ;
  99. tvis.item.pszText = _T("Typedefs") ;
  100. m_pTree->InsertItem(&tvis) ;
  101. pItem = new CTreeItem(m_pTree) ;
  102. pItem->SetTypeLib( GetTypeLib() ) ;
  103. GetTypeLib()->AddRef() ;
  104. pItem->m_Type = CTreeItem::typeUnions ;
  105. tvis.item.lParam = (LPARAM)pItem ;
  106. tvis.item.pszText = _T("Unions") ;
  107. m_pTree->InsertItem(&tvis) ;
  108. fExpand = TRUE ;
  109. }
  110. break ;
  111. case typeEnums:
  112. case typeRecords:
  113. case typeModules:
  114. case typeInterfaces:
  115. case typeDispinterfaces:
  116. case typeCoClasses:
  117. case typeAliases:
  118. case typeUnions:
  119. fExpand = ExpandTypeLib( hitem ) ;
  120. break ;
  121. case typeTypeInfo:
  122. case typeTypeInfo2:
  123. case typeEnum:
  124. case typeRecord:
  125. case typeModule:
  126. case typeInterface:
  127. case typeDispinterface:
  128. case typeCoClass:
  129. case typeAlias:
  130. case typeUnion:
  131. fExpand = ExpandTypeInfo( hitem ) ;
  132. break ;
  133. case typeMethods:
  134. case typeMethods2:
  135. fExpand = ExpandFuncs( hitem ) ;
  136. break ;
  137. case typeProperties:
  138. case typeProperties2:
  139. case typeConstants:
  140. case typeConstants2:
  141. fExpand = ExpandVars( hitem ) ;
  142. break ;
  143. case typeImplTypes:
  144. case typeImplTypes2:
  145. fExpand = ExpandImplTypes( hitem ) ;
  146. break ;
  147. case typeMethod:
  148. case typeProperty:
  149. case typeConstant:
  150. default:
  151. break ;
  152. }
  153. return fExpand ;
  154. }
  155. BOOL CTreeItem::ExpandTypeLib( HTREEITEM hitem )
  156. {
  157. ASSERT(hitem) ;
  158. CTreeItem*  pNewItem = NULL ;
  159. UINT            uiTypeInfoCount = GetTypeLib()->GetTypeInfoCount() ;
  160. HRESULT         hr = S_OK ;
  161. TV_INSERTSTRUCT tvis ;
  162. CString         strError = "Enumerating typeinfos";
  163. TYPEATTR*       pattr = NULL ;
  164. BOOL            fExpand = FALSE ;
  165. tvis.hParent = hitem  ;
  166. tvis.hInsertAfter = TVI_LAST ;
  167. tvis.item.mask = TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_CHILDREN ;
  168. tvis.item.cChildren = 1 ;
  169. TRY
  170. {
  171. for (UINT n = 0 ; n < uiTypeInfoCount ; n++)
  172. {
  173. pNewItem = new CTreeItem( m_pTree ) ;
  174. pNewItem->m_Type = typeTypeInfo ;
  175. ASSERT(pNewItem) ;
  176. tvis.item.lParam = (LPARAM)pNewItem ;
  177. hr = GetTypeLib()->GetTypeInfo( n, (ITypeInfo**)&pNewItem->m_punk ) ;
  178. if (FAILED(hr))
  179. {
  180. strError.Format(_T("Could not get TypeInfo #%u"), n ) ;
  181. AfxThrowOleException(hr) ;
  182. }
  183. ASSERT(pNewItem->m_punk) ;
  184. hr = pNewItem->GetTypeInfo()->GetTypeAttr(&pattr) ;
  185. if FAILED(hr)
  186. {
  187. strError.Format(_T("ITypeInfo::GetTypeAttr() failed") ) ;
  188. AfxThrowOleException(hr) ;
  189. }
  190. if ((m_Type == typeTypeLib) ||
  191. (m_Type == (TypeKindToItemType(pattr->typekind) + 8)))
  192. {
  193. tvis.item.iImage = pattr->typekind + typeEnum ;
  194. tvis.item.iSelectedImage = tvis.item.iImage ;
  195. CString sName;
  196. pNewItem->GetName(sName, TRUE );
  197. tvis.item.pszText = sName.GetBuffer(0);
  198. m_pTree->InsertItem( &tvis ) ;
  199. sName.ReleaseBuffer();
  200. pNewItem->GetTypeInfo()->ReleaseTypeAttr( pattr ) ;
  201. fExpand = TRUE ;
  202. }
  203. else
  204. {
  205. pNewItem->GetTypeInfo()->ReleaseTypeAttr( pattr ) ;
  206. delete pNewItem ;
  207. }
  208.    }
  209. }
  210. CATCH(CException, pException)
  211. {
  212. if (pException->IsKindOf(RUNTIME_CLASS(COleException)))
  213. ErrorMessage( strError, ((COleException*)pException)->m_sc ) ;
  214. else
  215. ErrorMessage( strError, hr ) ;
  216. if (pNewItem)
  217. delete pNewItem ;
  218. return FALSE ;
  219. }
  220. END_CATCH
  221. return fExpand ;
  222. }
  223. BOOL CTreeItem::ExpandTypeInfo( HTREEITEM hitem )
  224. {
  225. ASSERT(m_pTree) ;
  226. ASSERT(hitem) ;
  227. CTreeItem*  pNewItem = NULL ;
  228. HRESULT         hr = S_OK ;
  229. TV_INSERTSTRUCT tvis ;
  230. CString         strError = "Enumerating TypeInfo" ;
  231. TYPEATTR*       pattr = NULL ;
  232. ITypeInfo*      pti = GetTypeInfo() ;
  233. ASSERT(pti) ;
  234. BOOL            fExpand = FALSE ;
  235. tvis.hParent = hitem  ;
  236. tvis.hInsertAfter = TVI_LAST ;
  237. tvis.item.mask = TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_CHILDREN ;
  238. tvis.item.iImage = typeUnknown ;
  239. tvis.item.iSelectedImage = tvis.item.iImage + 1 ;
  240. TRY
  241. {
  242. hr = pti->GetTypeAttr(&pattr) ;
  243. if FAILED(hr)
  244. {
  245. strError.Format(_T("ITypeInfo::GetTypeAttr() failed"), hr ) ;
  246. AfxThrowMemoryException() ;
  247. }
  248. switch(pattr->typekind)
  249. {
  250. // typedef [attributes] enum [tag] {
  251. //      enumlist
  252. // } enumname;
  253. //
  254. // "typedef enum enumname"
  255. case TKIND_ENUM:
  256. fExpand = ExpandVars( hitem ) ;
  257. break ;
  258. // typedef [attributes]
  259. //  struct [tag] {
  260. //      memberlist
  261. //  } structname;
  262. //
  263. // "typedef struct structname"
  264. case TKIND_RECORD:
  265. fExpand = ExpandVars( hitem ) ;
  266. break ;
  267. // [attributes]
  268. //  module modulename {
  269. //      elementlist
  270. // };
  271. case TKIND_MODULE:
  272. if (pattr->cVars)
  273. {
  274. // Add "Constants" folder
  275. //
  276. pNewItem = new CTreeItem(m_pTree) ;
  277. pNewItem->m_Type = typeProperties ;
  278. pNewItem->SetTypeInfo(pti) ;
  279. pti->AddRef() ;
  280. tvis.item.cChildren = pattr->cVars ;
  281. tvis.item.lParam = (LPARAM)pNewItem ;
  282. tvis.item.pszText = _T("Constants") ;
  283. tvis.item.iImage = typeConstants ;
  284. tvis.item.iSelectedImage = tvis.item.iImage + 1 ;
  285. m_pTree->InsertItem( &tvis ) ;
  286. fExpand = TRUE ;
  287. }
  288. if (pattr->cFuncs)
  289. {
  290. pNewItem = new CTreeItem(m_pTree) ;
  291. pNewItem->m_Type = typeMethods ;
  292. pNewItem->SetTypeInfo(pti) ;
  293. pti->AddRef() ;
  294. tvis.item.cChildren = pattr->cFuncs ;
  295. tvis.item.lParam = (LPARAM)pNewItem ;
  296. tvis.item.pszText = _T("Functions") ;
  297. tvis.item.iImage = typeMethods ;
  298. tvis.item.iSelectedImage = tvis.item.iImage + 1 ;
  299. m_pTree->InsertItem( &tvis ) ;
  300. fExpand = TRUE ;
  301. }
  302. break ;
  303. // [attributes]
  304. //  interface interfacename  [:baseinterface] {
  305. //      functionlist
  306. // };
  307. case TKIND_INTERFACE:
  308. fExpand = ExpandFuncs( hitem) ;
  309. if (pattr->cImplTypes)
  310. {
  311. pNewItem = new CTreeItem(m_pTree) ;
  312. pNewItem->m_Type = typeImplTypes ;
  313. pNewItem->SetTypeInfo(pti) ;
  314. pti->AddRef() ;
  315. tvis.item.pszText = _T("Inherited Interfaces") ;
  316. tvis.item.iImage = typeInterface ;
  317. tvis.item.cChildren = pattr->cImplTypes ;
  318. tvis.item.lParam = (LPARAM)pNewItem ;
  319. tvis.item.iSelectedImage = tvis.item.iImage ;
  320. m_pTree->InsertItem( &tvis ) ;
  321. fExpand = TRUE ;
  322. }
  323. break ;
  324. // [attributes]
  325. //  dispinterface intfname {
  326. //      interface interfacename
  327. // };
  328. case TKIND_DISPATCH :
  329. if (pattr->cVars)
  330. {
  331. // Add "Constants" folder
  332. //
  333. pNewItem = new CTreeItem(m_pTree) ;
  334. pNewItem->m_Type = typeConstants ;
  335. pNewItem->SetTypeInfo(pti) ;
  336. pti->AddRef() ;
  337. tvis.item.cChildren = pattr->cVars ;
  338. tvis.item.lParam = (LPARAM)pNewItem ;
  339. tvis.item.pszText = _T("Constants") ;
  340. tvis.item.iImage = typeConstants ;
  341. tvis.item.iSelectedImage = tvis.item.iImage + 1 ;
  342. m_pTree->InsertItem( &tvis ) ;
  343. // Add "Properties" folder
  344. //
  345. pNewItem = new CTreeItem(m_pTree) ;
  346. pNewItem->m_Type = typeProperties ;
  347. pNewItem->SetTypeInfo(pti) ;
  348. pti->AddRef() ;
  349. tvis.item.cChildren = pattr->cVars ;
  350. tvis.item.lParam = (LPARAM)pNewItem ;
  351. tvis.item.pszText = _T("Properties") ;
  352. tvis.item.iImage = typeProperties ;
  353. tvis.item.iSelectedImage = tvis.item.iImage + 1 ;
  354. m_pTree->InsertItem( &tvis ) ;
  355. fExpand = TRUE ;
  356.  }
  357. if (pattr->cFuncs)
  358. {
  359. pNewItem = new CTreeItem(m_pTree) ;
  360. pNewItem->m_Type = typeMethods ;
  361. pNewItem->SetTypeInfo(pti) ;
  362. pti->AddRef() ;
  363. tvis.item.cChildren = pattr->cFuncs ;
  364. tvis.item.lParam = (LPARAM)pNewItem ;
  365. tvis.item.pszText = _T("Methods") ;
  366. tvis.item.iImage = typeMethods ;
  367. tvis.item.iSelectedImage = tvis.item.iImage + 1 ;
  368. m_pTree->InsertItem( &tvis ) ;
  369. fExpand = TRUE ;
  370. }
  371. if (pattr->cImplTypes)
  372. {
  373. pNewItem = new CTreeItem(m_pTree) ;
  374. pNewItem->m_Type = typeImplTypes ;
  375. pNewItem->SetTypeInfo(pti) ;
  376. pti->AddRef() ;
  377. tvis.item.pszText = _T("Inherited Interfaces") ;
  378. tvis.item.iImage = typeInterface ;
  379. tvis.item.cChildren = pattr->cImplTypes ;
  380. tvis.item.lParam = (LPARAM)pNewItem ;
  381. tvis.item.iSelectedImage = tvis.item.iImage ;
  382. m_pTree->InsertItem( &tvis ) ;
  383. fExpand = TRUE ;
  384. }
  385. break ;
  386. // [attributes]
  387. //  coclass classname {
  388. //      [attributes2] [interface | dispinterface] interfacename;
  389. //      ...
  390. // };
  391. case TKIND_COCLASS:
  392. fExpand = ExpandImplTypes( hitem ) ;
  393. break ;
  394. // typedef [attributes] basetype aliasname;
  395. case TKIND_ALIAS:
  396. if (pattr->tdescAlias.vt == VT_USERDEFINED)
  397. {
  398. ITypeInfo* ptiRefType = NULL ;
  399. HRESULT hr = pti->GetRefTypeInfo( pattr->tdescAlias.hreftype, &ptiRefType ) ;
  400. if (FAILED(hr))
  401. AfxThrowOleException( hr ) ;
  402. CTreeItem* pNewItem = new CTreeItem(m_pTree) ;
  403. pNewItem->SetTypeInfo( ptiRefType ) ;
  404. pNewItem->m_Type = TypeKindToItemType( pNewItem->GetTypeKind() ) ;
  405. tvis.item.iImage = TypeKindToItemType( pNewItem->GetTypeKind() ) ;
  406. tvis.item.cChildren = 1 ;
  407. tvis.item.lParam = (LPARAM)pNewItem ;
  408. tvis.item.iSelectedImage = tvis.item.iImage ;
  409. CString sName;
  410. pNewItem->GetName(sName, TRUE );
  411. tvis.item.pszText = sName.GetBuffer(0) ;
  412. m_pTree->InsertItem( &tvis ) ;
  413. sName.ReleaseBuffer();
  414. fExpand = TRUE ;
  415. }
  416. break ;
  417. // typedef [attributes] union [tag] {
  418. //      memberlist
  419. // } unionname;
  420. case TKIND_UNION:
  421. fExpand = ExpandVars( hitem ) ;
  422. break ;
  423. default:
  424. break ;
  425. }
  426. if (pattr)
  427. pti->ReleaseTypeAttr( pattr ) ;
  428. }
  429. CATCH(CException, pException)
  430. {
  431. ErrorMessage( strError, hr ) ;
  432. if (pNewItem)
  433. delete pNewItem ;
  434. if (pattr)
  435. pti->ReleaseTypeAttr( pattr ) ;
  436. return FALSE ;
  437. }
  438. END_CATCH
  439. return fExpand ;
  440. }
  441. BOOL CTreeItem::ExpandFuncs( HTREEITEM hitem )
  442. {
  443. ASSERT(hitem) ;
  444. CTreeItem*  pNewItem = NULL ;
  445. HRESULT         hr = S_OK ;
  446. TV_INSERTSTRUCT tvis ;
  447. CString         strError ;
  448. TYPEATTR*       pattr = NULL ;
  449. ITypeInfo*      pti = GetTypeInfo() ;
  450. ASSERT(pti) ;
  451. FUNCDESC*       pfuncdesc = NULL ;
  452. BSTR            bstrParams = NULL ;
  453. BOOL            fExpand = FALSE ;
  454. tvis.hParent = hitem  ;
  455. tvis.hInsertAfter = TVI_LAST ;
  456. tvis.item.mask = TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_CHILDREN ;
  457. TRY
  458. {
  459. hr = pti->GetTypeAttr(&pattr) ;
  460. if FAILED(hr)
  461. {
  462. strError.Format(_T("ITypeInfo::GetTypeAttr() failed: %x"), hr);
  463. AfxThrowMemoryException() ;
  464. }
  465. BSTR  rgbstrNames[MAX_NAMES] ;
  466. int   cNames ;
  467. //
  468. // Enumerate through all FUNCDESCS
  469. for ( int iIndex = 0 ; iIndex < pattr->cFuncs ; iIndex++)
  470. {
  471. hr = pti->GetFuncDesc( iIndex, &pfuncdesc ) ;
  472. if (FAILED(hr))
  473. {
  474. strError.Format(_T("GetVarDesc failed for function #%u"), iIndex) ;
  475. AfxThrowMemoryException() ;
  476. }
  477. //int cParams = pfuncdesc->cParams ;
  478. //int cParamsOpt = abs(pfuncdesc->cParamsOpt) ;
  479. // Get the names of the function and it's parameters into rgbstrNames.
  480. // cNames gets the number of parameters + 1.
  481. //
  482. hr = pti->GetNames( pfuncdesc->memid, rgbstrNames, 1, (UINT*)&cNames) ; //MAX_NAMES, (UINT FAR*)&cNames );
  483. if (FAILED(hr))
  484. {
  485. strError.Format(_T("GetNames failed for function #%u"), iIndex) ;
  486. AfxThrowMemoryException() ;
  487. }
  488. // rgbstrNames[0] is the name of the function
  489. if (cNames > 0)
  490. {
  491. USES_CONVERSION;
  492. pNewItem = new CTreeItem(m_pTree) ;
  493. pNewItem->SetTypeInfo(pti) ;
  494. pti->AddRef() ;
  495. pNewItem->m_Type = typeMethod ;
  496. pNewItem->m_uiMemid = iIndex ;
  497. tvis.item.lParam = (LPARAM)pNewItem ;
  498. tvis.item.iImage = typeMethod ;
  499. tvis.item.iSelectedImage = tvis.item.iImage ;
  500. tvis.item.cChildren = 0 ;
  501. LPTSTR lpszText = OLE2T(rgbstrNames[0]);
  502. tvis.item.pszText = lpszText;
  503. m_pTree->InsertItem( &tvis ) ;
  504. SysFreeString( rgbstrNames[0] ) ;
  505. }
  506. SysFreeString( bstrParams ) ;
  507. pti->ReleaseFuncDesc( pfuncdesc ) ;
  508. fExpand = TRUE ;
  509. }
  510. if (pattr)
  511. pti->ReleaseTypeAttr( pattr ) ;
  512. }
  513. CATCH(CException, pException)
  514. {
  515. ErrorMessage( strError, hr ) ;
  516. if (pNewItem)
  517. delete pNewItem ;
  518. if (pattr)
  519. pti->ReleaseTypeAttr( pattr ) ;
  520. if (pfuncdesc)
  521. pti->ReleaseFuncDesc( pfuncdesc ) ;
  522. if (bstrParams)
  523. SysFreeString(bstrParams) ;
  524. return FALSE ;
  525. }
  526. END_CATCH
  527. return fExpand ;
  528. }
  529. BOOL CTreeItem::ExpandVars( HTREEITEM hitem )
  530. {
  531. USES_CONVERSION;
  532. ASSERT(hitem) ;
  533. CTreeItem*  pNewItem = NULL ;
  534. HRESULT         hr = S_OK ;
  535. TV_INSERTSTRUCT tvis ;
  536. CString         strError ;
  537. TYPEATTR*       pattr = NULL ;
  538. ITypeInfo*      pti = GetTypeInfo() ;
  539. ASSERT(pti) ;
  540. LPVARDESC pvardesc = NULL ;
  541. BSTR            rgbstrNames[MAX_NAMES] ;
  542. int             cNames ;
  543. BOOL            fProperties = FALSE ;
  544. BOOL            fExpand = FALSE ;
  545. tvis.hParent = hitem  ;
  546. tvis.item.mask = TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_CHILDREN ;
  547. tvis.item.cChildren = 0 ;
  548. TRY
  549. {
  550. hr = pti->GetTypeAttr(&pattr) ;
  551. if FAILED(hr)
  552. {
  553. strError.Format(_T("ITypeInfo::GetTypeAttr() failed"), hr ) ;
  554. AfxThrowMemoryException() ;
  555. }
  556. // if it's a struct or an enum, order is important
  557. //
  558. if (pattr->typekind == TKIND_RECORD || pattr->typekind == TKIND_ENUM || pattr->typekind == TKIND_UNION)
  559. tvis.hInsertAfter = TVI_LAST ;
  560. else
  561. {
  562. tvis.hInsertAfter = TVI_LAST ;
  563. // are we doing constants or properties?
  564. TV_ITEM tvi ;
  565. TCHAR szBuf[80] ;
  566. tvi.hItem = hitem ;
  567. tvi.mask = TVIF_TEXT ;
  568. tvi.cchTextMax = 80 ;
  569. tvi.pszText = szBuf ;
  570. m_pTree->GetItem(&tvi) ;
  571. if (lstrcmpi(tvi.pszText, _T("Properties")) == 0)
  572. fProperties = TRUE ;
  573. }
  574. for (int iIndex = 0 ; iIndex < pattr->cVars ; iIndex++)
  575. {
  576. hr = pti->GetVarDesc( iIndex, &pvardesc ) ;
  577. if (FAILED(hr))
  578. {
  579. strError.Format(_T("GetVarDesc failed for variable #%u"), iIndex) ;
  580. AfxThrowMemoryException() ;
  581. }
  582. hr = pti->GetNames( pvardesc->memid, rgbstrNames, 1, (UINT FAR*)&cNames );
  583. if (FAILED(hr))
  584. {
  585. strError.Format(_T("GetNames failed for variable #%u"), iIndex) ;
  586. AfxThrowMemoryException() ;
  587. }
  588. if (pvardesc->varkind == VAR_CONST && fProperties == FALSE)
  589. {
  590. CString str = TYPEDESCtoString( &pvardesc->elemdescVar.tdesc ) ;
  591. VARIANT varValue ;
  592. VariantInit( &varValue ) ;
  593. if (FAILED(hr = VariantChangeType( &varValue, pvardesc->lpvarValue, 0, VT_BSTR )))
  594. {
  595. if (pvardesc->lpvarValue->vt == VT_ERROR || pvardesc->lpvarValue->vt == VT_HRESULT)
  596. {
  597. varValue.vt = VT_BSTR ;
  598. varValue.bstrVal = SysAllocString(T2OLE(_GetScodeString(pvardesc->lpvarValue->scode))) ;
  599. hr = S_OK ;
  600. }
  601. else
  602. AfxThrowOleException( hr ) ;
  603. }
  604. // const type name = expression
  605. UINT len = SysStringLen( varValue.bstrVal ) ;
  606. LPTSTR lpszSource = OLE2T(varValue.bstrVal);
  607. TCHAR* pstrExpand = new TCHAR[(len+1) * sizeof(TCHAR) * 2] ;
  608. LPTSTR lpD, lpS = lpszSource ;
  609. lpD = pstrExpand;
  610. for (UINT n = 0 ; n < len ; n++)
  611. {
  612. if (!isprint(*lpS) || (*lpS) == '"' || (*lpS) == '\')
  613. {
  614. // "  \ a  b  f  n  r  t  v
  615. *lpD++ = '\' ;
  616. switch(*lpS)
  617. {
  618. case '"':
  619. *lpD++ = '"' ;
  620. break ;
  621. case '\':
  622. *lpD++ = '\' ;
  623. break ;
  624. case 'a':
  625. *lpD++ = 'a' ;
  626. break ;
  627. case 'b':
  628. *lpD++ = 'b' ;
  629. break ;
  630. case 'f':
  631. *lpD++ = 'f' ;
  632. break ;
  633. case 'n':
  634. *lpD++ = 'n' ;
  635. break ;
  636. case 'r':
  637. *lpD++ = 'r' ;
  638. break ;
  639. case 't':
  640. *lpD++ = 't' ;
  641. break ;
  642. case 'v':
  643. *lpD++ = 'v' ;
  644. break ;
  645. case '':
  646. *lpD++ = '0' ;
  647. break ;
  648. default:
  649. lpD += wsprintf( lpD, _T("x%02X"), (UINT)*lpS );
  650. break ;
  651. }
  652. lpS++;
  653. }
  654. else
  655. *lpD++ = *lpS++;
  656. }
  657. *lpD = '';
  658. if (pvardesc->lpvarValue->vt == VT_BSTR)
  659. strError.Format(_T("const %s %s = "%s""), (LPCTSTR)str, OLE2CT(rgbstrNames[0]), pstrExpand) ;
  660. else
  661. strError.Format(_T("const %s %s = %s"), (LPCTSTR)str, OLE2CT(rgbstrNames[0]), pstrExpand);
  662. delete []pstrExpand ;
  663. VariantClear( &varValue ) ;
  664. tvis.item.iImage = typeConstant ;
  665. tvis.item.iSelectedImage = tvis.item.iImage ;
  666. pNewItem = new CTreeItem(m_pTree) ;
  667. pNewItem->SetTypeInfo(pti) ;
  668. pti->AddRef() ;
  669. pNewItem->m_Type = typeConstant ;
  670. pNewItem->m_uiMemid = iIndex ;
  671. tvis.item.lParam = (LPARAM)pNewItem ;
  672. tvis.item.pszText = strError.GetBuffer(0) ;
  673. m_pTree->InsertItem( &tvis ) ;
  674. strError.ReleaseBuffer(-1) ;
  675. fExpand = TRUE ;
  676. }
  677. else if (fProperties == TRUE ||
  678. (pattr->typekind == TKIND_RECORD ||
  679.  pattr->typekind == TKIND_UNION  ))
  680. {
  681. CString str ;
  682. static TCHAR szNameless[] = _T("(nameless)");
  683. if ((pvardesc->elemdescVar.tdesc.vt & 0x0FFF) == VT_CARRAY)
  684. {
  685. // type name[n]
  686. strError.Format(_T("%s "), TYPEDESCtoString( &pvardesc->elemdescVar.tdesc.lpadesc->tdescElem) );
  687. if (rgbstrNames[0])
  688. strError += OLE2CT(rgbstrNames[0]);
  689. else
  690. strError += szNameless;
  691. // Allocate cDims * lstrlen("[123456]")
  692. for (USHORT n = 0 ; n < pvardesc->elemdescVar.tdesc.lpadesc->cDims ; n++)
  693. {
  694. str.Format( _T("[%d]"), pvardesc->elemdescVar.tdesc.lpadesc->rgbounds[n].cElements ) ;
  695. strError += str ;
  696. }
  697. }
  698. else
  699. {
  700. // type name
  701. strError.Format(_T("%s "),strError = TYPEDESCtoString( &pvardesc->elemdescVar.tdesc ));
  702. if (rgbstrNames[0])
  703. strError += OLE2CT(rgbstrNames[0]);
  704. else
  705. strError += szNameless;
  706. }
  707. tvis.item.iImage = typeProperty ;
  708. tvis.item.iSelectedImage = tvis.item.iImage ;
  709. pNewItem = new CTreeItem(m_pTree) ;
  710. pNewItem->SetTypeInfo(pti) ;
  711. pti->AddRef() ;
  712. pNewItem->m_Type = typeProperty ;
  713. pNewItem->m_uiMemid = iIndex ;
  714. tvis.item.lParam = (LPARAM)pNewItem ;
  715. tvis.item.pszText = strError.GetBuffer(0) ;
  716. m_pTree->InsertItem( &tvis ) ;
  717. strError.ReleaseBuffer(-1) ;
  718. fExpand = TRUE ;
  719. }
  720. SysFreeString( rgbstrNames[0] ) ;
  721. pti->ReleaseVarDesc( pvardesc ) ;
  722. }
  723. if (pattr)
  724. pti->ReleaseTypeAttr( pattr ) ;
  725. }
  726. CATCH(CException, pException)
  727. {
  728. ErrorMessage( strError, hr ) ;
  729. if (pNewItem)
  730. delete pNewItem ;
  731. if (pattr)
  732. pti->ReleaseTypeAttr( pattr ) ;
  733. if (pvardesc)
  734. pti->ReleaseVarDesc( pvardesc ) ;
  735. return FALSE ;
  736. }
  737. END_CATCH
  738. return fExpand ;
  739. }
  740. BOOL CTreeItem::ExpandImplTypes( HTREEITEM hitem )
  741. {
  742. ASSERT(hitem) ;
  743. USES_CONVERSION;
  744. BOOL fExpand = FALSE ;
  745. CTreeItem*  pNewItem = NULL ;
  746. HRESULT         hr = S_OK ;
  747. BSTR            bstrName = NULL ;
  748. BSTR            bstrDoc = NULL ;
  749. BSTR            bstrHelp = NULL ;
  750. DWORD           dwHelpID ;
  751. TV_INSERTSTRUCT tvis ;
  752. CString         strError ;
  753. TYPEATTR*       pattr = NULL ;
  754. ITypeInfo*      pti = GetTypeInfo() ;
  755. tvis.hParent = hitem  ;
  756. tvis.hInsertAfter = TVI_LAST ;
  757. tvis.item.mask = TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_CHILDREN ;
  758. tvis.item.cChildren = 1 ;
  759. TRY
  760. {
  761. hr = pti->GetTypeAttr(&pattr) ;
  762. if FAILED(hr)
  763. {
  764. strError.Format(_T("ITypeInfo::GetTypeAttr() failed"), hr ) ;
  765. AfxThrowMemoryException() ;
  766. }
  767. for (UINT n = 0 ; n <  pattr->cImplTypes; n++)
  768. {
  769. pNewItem = new CTreeItem( m_pTree ) ;
  770. pNewItem->m_uiMemid = n ;
  771. ASSERT(pNewItem) ;
  772. tvis.item.lParam = (LPARAM)pNewItem ;
  773. HREFTYPE href = NULL ;
  774. hr = pti->GetRefTypeOfImplType(n, &href) ;
  775. if (FAILED(hr))
  776. {
  777. strError.Format(_T("Could not get RefTypeOfImplType #%u"), n ) ;
  778. AfxThrowMemoryException() ;
  779. }
  780. hr = pti->GetRefTypeInfo( href, (ITypeInfo**)&pNewItem->m_punk ) ;
  781. if (FAILED(hr))
  782. {
  783. strError.Format(_T("Could not get RefTypeInfo") ) ;
  784. AfxThrowMemoryException() ;
  785. }
  786. ASSERT(pNewItem->m_punk) ;
  787. TYPEATTR* pattrNew ;
  788. hr = pNewItem->GetTypeInfo()->GetTypeAttr(&pattrNew) ;
  789. if FAILED(hr)
  790. {
  791. strError.Format(_T("ITypeInfo::GetTypeAttr() failed") ) ;
  792. AfxThrowMemoryException() ;
  793. }
  794. pNewItem->m_Type = TypeKindToItemType( pNewItem->GetTypeKind() ) ;
  795. tvis.item.iImage = TypeKindToItemType( pNewItem->GetTypeKind() ) ;
  796. tvis.item.iSelectedImage = tvis.item.iImage ;
  797. pNewItem->GetTypeInfo()->ReleaseTypeAttr( pattrNew ) ;
  798. hr = pNewItem->GetTypeInfo()->GetDocumentation( MEMBERID_NIL, &bstrName, &bstrDoc, &dwHelpID, &bstrHelp ) ;
  799. if (FAILED(hr))
  800. {
  801. strError.Format(_T("ITypeInfo::GetDocumentation() failed")) ;
  802. AfxThrowMemoryException() ;
  803. }
  804. LPTSTR lpszName = OLE2T(bstrName);
  805. tvis.item.pszText = lpszName  ;
  806. m_pTree->InsertItem( &tvis ) ;
  807. SysFreeString( bstrName ) ;
  808. bstrName = NULL ;
  809. SysFreeString( bstrDoc ) ;
  810. bstrDoc = NULL ;
  811. SysFreeString( bstrHelp ) ;
  812. bstrHelp = NULL ;
  813. fExpand = TRUE ;
  814. }
  815. }
  816. CATCH(CException, pException)
  817. {
  818. ErrorMessage( strError, hr ) ;
  819. if (pNewItem)
  820. delete pNewItem ;
  821. if (bstrName)
  822. SysFreeString( bstrName ) ;
  823. if (bstrDoc)
  824. SysFreeString( bstrDoc ) ;
  825. if (bstrHelp)
  826. SysFreeString( bstrHelp ) ;
  827. return FALSE ;
  828. }
  829. END_CATCH
  830. if (pti && pattr)
  831. pti->ReleaseTypeAttr( pattr );
  832. return fExpand ;
  833. }
  834. CString CTreeItem::TYPEDESCtoString( TYPEDESC* ptdesc )
  835. {
  836. ASSERT(GetTypeInfo()) ;
  837. return ::TYPEDESCtoString( GetTypeInfo(), ptdesc ) ;
  838. }
  839. void CTreeItem::GetName(CString& szReturn, BOOL fIDLStyle /*= FALSE*/)
  840. {
  841. BSTR    bstrName = NULL ;
  842. BSTR    bstrDoc = NULL ;
  843. BSTR    bstrHelp = NULL ;
  844. DWORD   dwHelpID ;
  845. HRESULT hr ;
  846. TRY
  847. {
  848. hr = GetTypeInfo()->GetDocumentation( MEMBERID_NIL, &bstrName, &bstrDoc, &dwHelpID, &bstrHelp ) ;
  849. if (FAILED(hr))
  850. AfxThrowOleException( hr ) ;
  851. SysFreeString( bstrDoc ) ;
  852. bstrDoc = NULL ;
  853. SysFreeString( bstrHelp ) ;
  854. bstrHelp = NULL ;
  855. USES_CONVERSION;
  856. LPCTSTR lpszName = OLE2CT(bstrName);
  857. ::SysFreeString(bstrName);
  858. bstrName = NULL;
  859. if (fIDLStyle)
  860. {
  861. TYPEATTR* pattr ;
  862. hr = GetTypeInfo()->GetTypeAttr(&pattr) ;
  863. if FAILED(hr)
  864. AfxThrowOleException(hr) ;
  865. switch(pattr->typekind)
  866. {
  867. // typedef [attributes] enum [tag] {
  868. //      enumlist
  869. // } enumname;
  870. //
  871. // "typedef enum enumname"
  872. case TKIND_ENUM:
  873. szReturn.Format(_T("typedef enum %s"), lpszName ) ;
  874. break ;
  875. // typedef [attributes]
  876. //  struct [tag] {
  877. //      memberlist
  878. //  } structname;
  879. //
  880. // "typedef struct structname"
  881. case TKIND_RECORD:
  882. szReturn.Format(_T("typedef struct %s"), lpszName ) ;
  883. break ;
  884. // [attributes]
  885. //  module modulename {
  886. //      elementlist
  887. // };
  888. case TKIND_MODULE:
  889. szReturn.Format(_T("module %s"), lpszName ) ;
  890. break ;
  891. // [attributes]
  892. //  interface interfacename  [:baseinterface] {
  893. //      functionlist
  894. // };
  895. case TKIND_INTERFACE:
  896. // TODO:  enum base interfaces and append
  897. szReturn.Format(_T("interface %s"), lpszName ) ;
  898. break ;
  899. // [attributes]
  900. //  dispinterface intfname {
  901. //      interface interfacename
  902. // };
  903. case TKIND_DISPATCH :
  904. szReturn.Format(_T("dispinterface %s"), lpszName ) ;
  905. break ;
  906. // [attributes]
  907. //  coclass classname {
  908. //      [attributes2] [interface | dispinterface] interfacename;
  909. //      ...
  910. // };
  911. case TKIND_COCLASS:
  912. szReturn.Format(_T("coclass %s"), lpszName ) ;
  913. break ;
  914. // typedef [attributes] basetype aliasname;
  915. case TKIND_ALIAS:
  916. szReturn.Format(_T("typedef %s %s"),
  917. ::TYPEDESCtoString(GetTypeInfo(), &pattr->tdescAlias), lpszName);
  918. break ;
  919. // typedef [attributes] union [tag] {
  920. //      memberlist
  921. // } unionname;
  922. case TKIND_UNION:
  923. szReturn.Format(_T("typedef union %s"), lpszName ) ;
  924. break ;
  925. default:
  926. break ;
  927. }
  928. GetTypeInfo()->ReleaseTypeAttr( pattr ) ;
  929. }
  930. }
  931. CATCH(CException, pException)
  932. {
  933. if (bstrName)
  934. SysFreeString( bstrName ) ;
  935. if (bstrDoc)
  936. SysFreeString( bstrDoc ) ;
  937. if (bstrHelp)
  938. SysFreeString( bstrHelp ) ;
  939. THROW_LAST();
  940. }
  941. END_CATCH
  942. }
  943. TYPEKIND CTreeItem::GetTypeKind()
  944. {
  945. TYPEATTR* pattr ;
  946. TYPEKIND kind ;
  947. HRESULT hr = GetTypeInfo()->GetTypeAttr(&pattr) ;
  948. if FAILED(hr)
  949. AfxThrowOleException(hr) ;
  950. kind = pattr->typekind ;
  951. GetTypeInfo()->ReleaseTypeAttr(pattr) ;
  952. return kind ;
  953. }
  954. CTreeItem::ITEM_TYPE CTreeItem::TypeKindToItemType( TYPEKIND tkind )
  955. {
  956. ITEM_TYPE t ;
  957. switch(tkind)
  958. {
  959. case TKIND_ENUM:        t = typeEnum ; break ;
  960. case TKIND_RECORD:      t = typeRecord ; break ;
  961. case TKIND_MODULE:      t = typeModule ;break ;
  962. case TKIND_INTERFACE:   t = typeInterface ;break ;
  963. case TKIND_DISPATCH :   t = typeDispinterface ; break ;
  964. case TKIND_COCLASS:     t = typeCoClass ; break ;
  965. case TKIND_ALIAS:       t = typeAlias ; break ;
  966. case TKIND_UNION:       t = typeUnion ; break ;
  967. default:                t = typeUnknown ; break ;
  968. }
  969. return t ;
  970. }