home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / mfc / ole / oleview / iviewers / tlbtree.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-03-27  |  7.9 KB  |  332 lines

  1. // tlbtree.cpp : implementation file
  2. //
  3.  
  4. // This is a part of the Microsoft Foundation Classes C++ library.
  5. // Copyright (C) 1992-1998 Microsoft Corporation
  6. // All rights reserved.
  7. //
  8. // This source code is only intended as a supplement to the
  9. // Microsoft Foundation Classes Reference and related
  10. // electronic documentation provided with the library.
  11. // See these sources for detailed information regarding the
  12. // Microsoft Foundation Classes product.
  13.  
  14. #include "stdafx.h"
  15. #include "iview.h"
  16. #include "util.h"
  17. #include "iviewers.h"
  18. #include "iviewer.h"
  19. #include "typelib.h"
  20. #include "tlbtree.h"
  21.  
  22. #ifdef _DEBUG
  23. #undef THIS_FILE
  24. static char BASED_CODE THIS_FILE[] = __FILE__;
  25. #endif
  26.  
  27. #define MAX_NAMES   256
  28.  
  29. /////////////////////////////////////////////////////////////////////////////
  30. // CTypeLibTreeView
  31. IMPLEMENT_DYNCREATE(CTypeLibTreeView, CView)
  32.  
  33. CTypeLibTreeView::CTypeLibTreeView( )
  34. {
  35.     m_hTypeInfos = NULL ;
  36.     m_ptlb = NULL ;
  37. }
  38.  
  39. CTypeLibTreeView::~CTypeLibTreeView()
  40. {
  41.     if (m_ptlb)
  42.         m_ptlb->Release() ;
  43. }
  44.  
  45.  
  46. BEGIN_MESSAGE_MAP(CTypeLibTreeView, CView)
  47.     //{{AFX_MSG_MAP(CTypeLibTreeView)
  48.     ON_WM_CREATE()
  49.     ON_WM_DESTROY()
  50.     ON_WM_SIZE()
  51.     //}}AFX_MSG_MAP
  52.     ON_NOTIFY(TVN_SELCHANGED, ID_TREEVIEW, OnTreeSelchanged)
  53.     ON_NOTIFY(TVN_ITEMEXPANDING, ID_TREEVIEW, OnTreeItemExpanding)
  54.     ON_NOTIFY(TVN_ITEMEXPANDED, ID_TREEVIEW, OnTreeItemExpanded)
  55.     ON_NOTIFY(NM_RETURN, ID_TREEVIEW, OnTreeItemReturn)
  56.     ON_NOTIFY(TVN_DELETEITEM, ID_TREEVIEW, OnTreeDeleteItem)
  57. END_MESSAGE_MAP()
  58.  
  59.  
  60. /////////////////////////////////////////////////////////////////////////////
  61. // CTypeLibTreeView drawing
  62.  
  63.  
  64. /////////////////////////////////////////////////////////////////////////////
  65. // CTypeLibTreeView diagnostics
  66.  
  67. #ifdef _DEBUG
  68. void CTypeLibTreeView::AssertValid() const
  69. {
  70.     CView::AssertValid();
  71. }
  72.  
  73. void CTypeLibTreeView::Dump(CDumpContext& dc) const
  74. {
  75.     CView::Dump(dc);
  76. }
  77. #endif //_DEBUG
  78.  
  79. /////////////////////////////////////////////////////////////////////////////
  80. // CTypeLibTreeView message handlers
  81.  
  82. int CTypeLibTreeView::OnCreate(LPCREATESTRUCT lpCreateStruct)
  83. {
  84.     if (CView::OnCreate(lpCreateStruct) == -1)
  85.         return -1;
  86.  
  87.     RECT rect ;
  88.     rect.top = lpCreateStruct->y ;
  89.     rect.left = lpCreateStruct->x ;
  90.     rect.bottom = lpCreateStruct->cy ;
  91.     rect.right = lpCreateStruct->cx ;
  92.  
  93.     if (!m_tree.Create( WS_CHILD | WS_VISIBLE |
  94.                                 WS_BORDER |
  95.                                 TVS_HASLINES |
  96.                                 TVS_LINESATROOT |
  97.                                 TVS_SHOWSELALWAYS |
  98.                                 TVS_HASBUTTONS |
  99.                                 TVS_DISABLEDRAGDROP,
  100.                                 rect, this, ID_TREEVIEW ))
  101.     {
  102.         TRACE( _T("Tree control failed to create!") ) ;
  103.         return -1 ;
  104.     }
  105.  
  106.     m_images.Create( IDB_IMAGELIST, 16, 64, RGBLTGREEN ) ;
  107.     m_tree.SetImageList( &m_images, TVSIL_NORMAL ) ;
  108.  
  109.     return 0;
  110. }
  111.  
  112. void CTypeLibTreeView::OnDestroy()
  113. {
  114.     CView::OnDestroy();
  115.     m_tree.DeleteAllItems() ;
  116. }
  117.  
  118. void CTypeLibTreeView::OnDraw(CDC* pDC)
  119. {
  120.     // TODO: Add your specialized code here and/or call the base class
  121.  
  122. }
  123.  
  124. void CTypeLibTreeView::OnSize(UINT nType, int cx, int cy)
  125. {
  126.     CView::OnSize(nType, cx, cy);
  127.     m_tree.SetWindowPos( NULL, -1, -1, cx+2, cy+2, SWP_NOZORDER ) ;
  128. }
  129.  
  130. void CTypeLibTreeView::OnInitialUpdate()
  131. {
  132.     TRACE(_T("OnInitialUpdate\n")) ;
  133.     CTypeLibWnd* pFrame = (CTypeLibWnd*)GetParent()->GetParent() ;
  134.     ASSERT(pFrame->IsKindOf(RUNTIME_CLASS(CTypeLibWnd)));
  135.  
  136.     ASSERT(pFrame->m_ptlb) ;
  137.     m_ptlb = pFrame->m_ptlb ;
  138.     m_ptlb->AddRef() ;
  139.  
  140.     CView::OnInitialUpdate();
  141. }
  142.  
  143. void CTypeLibTreeView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
  144. {
  145.     USES_CONVERSION;
  146.     if (lHint != NULL || (lHint & UPDF_NOTREEVIEW))
  147.         return ;
  148.  
  149.     TRACE(_T("OnUpdate\n")) ;
  150.     m_tree.SetRedraw( FALSE ) ;
  151.     BeginWaitCursor() ;
  152.  
  153.     m_tree.DeleteAllItems() ;
  154.     m_hTypeInfos = NULL ;
  155.  
  156.     TV_INSERTSTRUCT tvis ;
  157.     tvis.hParent = TVI_ROOT ;
  158.     tvis.hInsertAfter = TVI_FIRST ;
  159.     tvis.item.mask = TVIF_TEXT | TVIF_CHILDREN | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE ;
  160.     tvis.item.iImage = CTreeItem::typeTypeLib ;
  161.     tvis.item.iSelectedImage = tvis.item.iImage + 1 ;
  162.  
  163.     HRESULT hr = S_OK ;
  164.     CString strError ;
  165.     TRY
  166.     {
  167.         CTypeLibWnd* pFrame = (CTypeLibWnd*)GetParent()->GetParent() ;
  168.         if (pFrame == NULL)
  169.         {
  170.             strError = _T("Internal Application error.");
  171.             AfxThrowMemoryException() ;
  172.         }
  173.  
  174.         if (pFrame->m_fGroupByKind)
  175.         {
  176.             tvis.item.cChildren = 1 ;
  177.         }
  178.         else
  179.         {
  180.             tvis.item.cChildren = m_ptlb->GetTypeInfoCount() ;
  181.         }
  182.  
  183.         BSTR    bstrName = NULL ;
  184.         BSTR    bstrDoc = NULL ;
  185.         BSTR    bstrHelp = NULL ;
  186.         DWORD   dwHelpID ;
  187.         hr = m_ptlb->GetDocumentation( MEMBERID_NIL, &bstrName, &bstrDoc, &dwHelpID, &bstrHelp ) ;
  188.         if (FAILED(hr))
  189.         {
  190.             strError = _T("ITypeLib::GetDocumentation failed.") ;
  191.             AfxThrowMemoryException() ;
  192.         }
  193.  
  194.         CTreeItem* pItem = new CTreeItem(&m_tree) ;
  195.         if (pFrame->m_fGroupByKind)
  196.             pItem->m_Type = CTreeItem::typeTypeLib2 ; //hacky
  197.         else
  198.             pItem->m_Type = CTreeItem::typeTypeLib ;
  199.         pItem->SetTypeLib( m_ptlb ) ;
  200.         m_ptlb->AddRef() ;
  201.         tvis.item.lParam = (LPARAM)pItem ;
  202.  
  203.         LPCTSTR lpszName = OLE2CT(bstrName);
  204.         if (::SysStringLen(bstrDoc) != 0)
  205.         {
  206.             LPCTSTR lpszDoc = OLE2CT(bstrDoc);
  207.             CString str;
  208.             str.Format( _T("%s (%s)"), lpszName, lpszDoc);
  209.             tvis.item.pszText = str.GetBuffer(0);
  210.             m_hTypeInfos = m_tree.InsertItem( &tvis ) ;
  211.             str.ReleaseBuffer(-1) ;
  212.         }
  213.         else
  214.         {
  215.             tvis.item.pszText = (LPTSTR)lpszName;
  216.             m_hTypeInfos = m_tree.InsertItem( &tvis ) ;
  217.         }
  218.  
  219.         ::SysFreeString( bstrName ) ;
  220.         ::SysFreeString( bstrDoc ) ;
  221.         ::SysFreeString( bstrHelp ) ;
  222.     }
  223.     CATCH(CException, pException)
  224.     {
  225.     }
  226.     END_CATCH
  227.  
  228.     if (m_hTypeInfos)
  229.     {
  230.         m_tree.Expand( m_hTypeInfos, TVE_EXPAND ) ;
  231.         //m_tree.SelectItem( m_hTypeInfos ) ;
  232.     }
  233.  
  234.     m_tree.SetRedraw( TRUE ) ;
  235.     EndWaitCursor() ;
  236. }
  237.  
  238. void CTypeLibTreeView::DeleteTreeItems( HTREEITEM htree )
  239. {
  240.     HTREEITEM       hItem, hItemNext ;
  241.     ASSERT(htree) ;
  242.  
  243.     hItem = m_tree.GetChildItem( htree ) ;
  244.     while( hItem )
  245.     {
  246.         hItemNext = m_tree.GetNextSiblingItem( hItem ) ;
  247.         m_tree.DeleteItem( hItem ) ;
  248.         hItem = hItemNext ;
  249.     }
  250. }
  251.  
  252. void CTypeLibTreeView::OnTreeSelchanged(NMHDR* pNMHDR, LRESULT* pResult)
  253. {
  254.     NM_TREEVIEW* pnmtv = (NM_TREEVIEW*)pNMHDR;
  255.     *pResult = 0;
  256.  
  257.     CTypeLibWnd* pFrame = (CTypeLibWnd*)GetParent()->GetParent() ;
  258.     ASSERT(pFrame->IsKindOf(RUNTIME_CLASS(CTypeLibWnd)));
  259.  
  260.     CTreeItem*  pItem = (CTreeItem*)pnmtv->itemNew.lParam ;
  261.     if (pItem == NULL)
  262.         return ;
  263.     ASSERT(pItem->IsKindOf(RUNTIME_CLASS(CTreeItem)));
  264.  
  265.     pFrame->m_pSelectedItem = pItem ;
  266.  
  267.     pFrame->UpdateAllViews( this, UPDF_NOTREEVIEW, pItem ) ;
  268. }
  269.  
  270. void CTypeLibTreeView::OnTreeItemExpanding(NMHDR* pNMHDR, LRESULT* pResult)
  271. {
  272.     *pResult = 0 ;
  273.     NM_TREEVIEW* pnmtv = (NM_TREEVIEW*)pNMHDR;
  274.  
  275.     if ((pnmtv->action != TVE_EXPAND && pnmtv->itemNew.lParam) ||
  276.         (pnmtv->itemNew.state & TVIS_EXPANDEDONCE))
  277.         return ;
  278.  
  279.     CTreeItem*  pItem = (CTreeItem*)pnmtv->itemNew.lParam ;
  280.     if (pItem == NULL)
  281.         return ;
  282.     ASSERT(pItem->IsKindOf(RUNTIME_CLASS(CTreeItem)));
  283.  
  284.     BeginWaitCursor() ;
  285.     m_tree.SetRedraw( FALSE ) ;
  286.  
  287.     *pResult = !pItem->Expand(  pnmtv->itemNew.hItem ) ;
  288.  
  289.     // No children
  290.     if (*pResult == TRUE)
  291.     {
  292.         TV_ITEM item ;
  293.         item.cChildren = 0 ;
  294.         item.mask = TVIF_CHILDREN ;
  295.         item.hItem = pnmtv->itemNew.hItem ;
  296.         m_tree.SetItem( &item ) ;
  297.     }
  298.  
  299.     m_tree.SetRedraw( TRUE ) ;
  300.     EndWaitCursor() ;
  301. }
  302.  
  303.  
  304. void CTypeLibTreeView::OnTreeItemExpanded(NMHDR* pNMHDR, LRESULT* pResult)
  305. {
  306.     *pResult = (LRESULT)FALSE ;
  307. }
  308.  
  309. void CTypeLibTreeView::OnTreeItemReturn(NMHDR* pNMHDR, LRESULT* pResult)
  310. {
  311.     *pResult = (LRESULT)TRUE ;
  312.     HTREEITEM hTreeItemSel = m_tree.GetSelectedItem() ;
  313.  
  314.     if (hTreeItemSel)
  315.         m_tree.Expand( hTreeItemSel, TVE_TOGGLE ) ;
  316. }
  317.  
  318. inline void CTypeLibTreeView::OnTreeDeleteItem(NMHDR* pNMHDR, LRESULT* pResult)
  319. {
  320.     *pResult = (LRESULT)TRUE ;
  321.     NM_TREEVIEW* pnmtv = (NM_TREEVIEW*)pNMHDR;
  322.  
  323.     if (pnmtv->itemOld.lParam)
  324.     {
  325.         CTreeItem* pItem = (CTreeItem*)pnmtv->itemOld.lParam ;
  326.         ASSERT(pItem->IsKindOf(RUNTIME_CLASS(CTreeItem)));
  327.         delete pItem ;
  328.         //pnmtv->itemOld.lParam = NULL ;
  329.     }
  330.  
  331. }
  332.