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 / obj_vw.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-03-27  |  32.4 KB  |  1,186 lines

  1. // obj_vw.cpp
  2. //
  3. // Implementation of the CObjTreeView class
  4. //
  5.  
  6. // This is a part of the Microsoft Foundation Classes C++ library.
  7. // Copyright (C) 1992-1998 Microsoft Corporation
  8. // All rights reserved.
  9. //
  10. // This source code is only intended as a supplement to the
  11. // Microsoft Foundation Classes Reference and related
  12. // electronic documentation provided with the library.
  13. // See these sources for detailed information regarding the
  14. // Microsoft Foundation Classes product.
  15.  
  16. #include "stdafx.h"
  17. #include "OleView.h"
  18. #include "shadow.h"
  19. #include "obj_vw.h"
  20. #include <winnls.h>
  21.  
  22. #ifdef _DEBUG
  23. #undef THIS_FILE
  24. static char BASED_CODE THIS_FILE[] = __FILE__;
  25. #endif
  26.  
  27. /////////////////////////////////////////////////////////////////////////////
  28. // CObjectData
  29.  
  30. IMPLEMENT_DYNCREATE(CObjectData, CObject)
  31.  
  32. CObjectData::CObjectData()
  33. {
  34.     m_nType = typeUnknown ;
  35.     m_pcf = NULL ;
  36.     m_punk = NULL ;
  37.     m_uiBitmap = NULL ;
  38.  
  39. }
  40.  
  41. CObjectData::~CObjectData()
  42. {
  43. }
  44.  
  45. BOOL CObjectData::Release()
  46. {
  47.     if (m_pcf)
  48.         m_pcf->Release() ;
  49.  
  50.     if (m_punk)
  51.         m_punk->Release() ;
  52.  
  53.     m_pcf = NULL ;
  54.     m_punk = NULL ;
  55.  
  56.     CoFreeUnusedLibraries();
  57.  
  58.     return TRUE ;
  59. }
  60.  
  61. HRESULT CObjectData::CreateInstance( DWORD clsctx )
  62. {
  63.     Release() ;
  64.  
  65.     HRESULT hr = NOERROR ;
  66.     CString strError ;
  67.     IUnknown* punk = NULL ;
  68.     TRY
  69.     {
  70.         hr = CoGetClassObject( m_clsid, clsctx, NULL, IID_IUnknown, (void**)&punk ) ;
  71.         if (FAILED(hr))
  72.         {
  73.             strError = "CoGetClassObject failed." ;
  74.             AfxThrowOleException(hr) ;
  75.         }
  76.         ASSERT(punk) ;
  77.  
  78.         hr = punk->QueryInterface( IID_IClassFactory, (void**)&m_pcf ) ;
  79.         if (FAILED(hr))
  80.         {
  81.             strError = "QueryInterface on class factory for IClassFactory failed." ;
  82.             AfxThrowOleException(hr) ;
  83.         }
  84.         ASSERT(m_pcf) ;
  85.  
  86.         punk->Release() ;
  87.         punk = NULL ;
  88.  
  89.         hr = m_pcf->CreateInstance( NULL, IID_IUnknown, (void**)&m_punk ) ;
  90.         if (FAILED(hr))
  91.         {
  92.             strError = "IClassFactory::CreateInstance failed." ;
  93.             AfxThrowOleException(hr) ;
  94.         }
  95.  
  96.         m_pcf->Release() ;
  97.         m_pcf = NULL ;
  98.     }
  99.     CATCH(COleException, pException)
  100.     {
  101.         if (punk)
  102.             punk->Release() ;
  103.         Release() ;
  104.  
  105.         ErrorMessage( strError, hr ) ;
  106.     }
  107.     END_CATCH ;
  108.  
  109.     return hr ;
  110. }
  111.  
  112. /////////////////////////////////////////////////////////////////////////////
  113. // CObjTreeView
  114.  
  115. IMPLEMENT_DYNCREATE(CObjTreeView, CTreeView)
  116.  
  117. BEGIN_MESSAGE_MAP(CObjTreeView, CTreeView)
  118.     //{{AFX_MSG_MAP(CObjTreeView)
  119.     ON_WM_CREATE()
  120.     ON_WM_DESTROY()
  121.     ON_WM_LBUTTONDBLCLK()
  122.     ON_COMMAND(ID_OBJECT_DELETE, OnObjectDelete)
  123.     ON_COMMAND(ID_OBJECT_VERIFY, OnObjectVerify)
  124.     //}}AFX_MSG_MAP
  125.     ON_NOTIFY_REFLECT(TVN_SELCHANGED,OnTreeSelchanged)
  126.     ON_NOTIFY_REFLECT(TVN_ITEMEXPANDING, OnTreeItemExpanding)
  127.     ON_NOTIFY_REFLECT(TVN_ITEMEXPANDED,OnTreeItemExpanded)
  128.     ON_NOTIFY_REFLECT(TVN_DELETEITEM,OnTreeDeleteItem)
  129.     ON_MESSAGE( WM_COMMANDHELP, OnCommandHelp)
  130.     ON_NOTIFY_REFLECT(NM_RETURN, OnTreeReturn)
  131. END_MESSAGE_MAP()
  132.  
  133. /////////////////////////////////////////////////////////////////////////////
  134. // CObjTreeView construction/destruction
  135.  
  136. CObjTreeView::CObjTreeView()
  137. {
  138.     m_hObjects = NULL ;
  139.     m_hTypeLibs= NULL ;
  140.     m_hInterfaces = NULL ;
  141.  
  142.     m_hInsertable = NULL ;
  143.     m_hControls= NULL ;
  144.     m_hInternal= NULL ;
  145. #ifdef SHOW_CONTAINERS
  146.     m_hContainers= NULL ;
  147. #endif
  148.     m_hOLE1= NULL ;
  149.     m_hUnclassified= NULL ;
  150. }
  151.  
  152. CObjTreeView::~CObjTreeView()
  153. {
  154. }
  155.  
  156. LRESULT CObjTreeView::OnCommandHelp(WPARAM, LPARAM lParam)
  157. {
  158.     theApp.WinHelp( lParam, HELP_CONTEXT ) ;
  159.     return TRUE ;
  160. }
  161.  
  162. BOOL CObjTreeView::PreCreateWindow(CREATESTRUCT& cs)
  163. {
  164.     if (!CTreeView::PreCreateWindow(cs))
  165.         return FALSE;
  166.  
  167.     cs.style = WS_CHILD | WS_VISIBLE | WS_BORDER | TVS_LINESATROOT |
  168.         TVS_HASLINES | TVS_HASBUTTONS | TVS_DISABLEDRAGDROP;
  169.     return TRUE;
  170. }
  171.  
  172.  
  173. int CObjTreeView::OnCreate(LPCREATESTRUCT lpCreateStruct)
  174. {
  175.     if (CTreeView::OnCreate(lpCreateStruct) == -1)
  176.         return -1;
  177. #ifdef _MARCOC_OLD
  178.     RECT rect ;
  179.     rect.top = lpCreateStruct->y ;
  180.     rect.left = lpCreateStruct->x ;
  181.     rect.bottom = lpCreateStruct->cy ;
  182.     rect.right = lpCreateStruct->cx ;
  183.  
  184.     if (!GetTreeCtrl().Create( WS_CHILD | WS_VISIBLE |
  185.                                 WS_BORDER |
  186.                                 TVS_LINESATROOT |
  187.                                 TVS_HASLINES |
  188. //                                TVS_SHOWSELALWAYS |
  189.                                 TVS_HASBUTTONS |
  190.                                 TVS_DISABLEDRAGDROP,
  191.                                 rect, this, ID_TREEVIEW ))
  192.     {
  193.         TRACE( _T("Tree control failed to create!") ) ;
  194.         return -1 ;
  195.     }
  196. #endif
  197.     return 0;
  198. }
  199.  
  200. void CObjTreeView::OnInitialUpdate()
  201. {
  202.     GetTreeCtrl().SetImageList( &theApp.m_images, TVSIL_NORMAL ) ;
  203.  
  204.     TV_INSERTSTRUCT tvis ;
  205.     tvis.hParent = TVI_ROOT ;
  206.     tvis.hInsertAfter = TVI_LAST ;
  207.     tvis.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_CHILDREN ;
  208.     tvis.item.lParam = 0 ;
  209.     tvis.item.cChildren = 1 ;
  210.  
  211.     tvis.item.pszText = "Objects" ;
  212.     tvis.item.iImage = BMINDEX(IDB_OBJECTFOLDER) ;
  213.     tvis.item.iSelectedImage = BMINDEX(IDB_OBJECTFOLDER) ;
  214.     m_hObjects = GetTreeCtrl().InsertItem( &tvis ) ;
  215.  
  216.     tvis.hParent = m_hObjects ;
  217.     tvis.item.pszText = "OLE Document Objects" ;
  218.     tvis.item.iImage = BMINDEX(IDB_OBJECT_INSERTABLE) ;
  219.     tvis.item.iSelectedImage = BMINDEX(IDB_OBJECT_INSERTABLE) ;
  220.     m_hInsertable = GetTreeCtrl().InsertItem( &tvis ) ;
  221.  
  222.     tvis.item.pszText = "OLE Controls" ;
  223.     tvis.item.iImage = BMINDEX(IDB_OBJECT_CONTROL) ;
  224.     tvis.item.iSelectedImage = BMINDEX(IDB_OBJECT_CONTROL) ;
  225.     m_hControls = GetTreeCtrl().InsertItem( &tvis ) ;
  226.  
  227.     tvis.item.pszText = "Unclassified Objects" ;
  228.     tvis.item.iImage = BMINDEX(IDB_OBJECT) ;
  229.     tvis.item.iSelectedImage = BMINDEX(IDB_OBJECT) ;
  230.     m_hUnclassified = GetTreeCtrl().InsertItem( &tvis ) ;
  231.  
  232. #ifdef SHOW_CONTAINERS
  233.     tvis.item.pszText = "Containers" ;
  234.     tvis.item.iImage = BMINDEX(IDB_CONTAINER) ;
  235.     tvis.item.iSelectedImage = BMINDEX(IDB_CONTAINER) ;
  236.     m_hContainers = GetTreeCtrl().InsertItem( &tvis ) ;
  237. #endif
  238.  
  239.     tvis.item.pszText = "OLE 1.0 Objects" ;
  240.     tvis.item.iImage = BMINDEX(IDB_OBJECT_INSERTABLE10) ;
  241.     tvis.item.iSelectedImage = BMINDEX(IDB_OBJECT_INSERTABLE10) ;
  242.     m_hOLE1 = GetTreeCtrl().InsertItem( &tvis ) ;
  243.  
  244.     tvis.item.pszText = "Internal OLE Objects" ;
  245.     tvis.item.iImage = BMINDEX(IDB_QUESTION) ;
  246.     tvis.item.iSelectedImage = BMINDEX(IDB_QUESTION) ;
  247.     m_hInternal = GetTreeCtrl().InsertItem( &tvis ) ;
  248.  
  249.     GetTreeCtrl().Expand( m_hObjects, TVE_EXPAND ) ;
  250.  
  251.     tvis.hParent = TVI_ROOT ;
  252.     tvis.item.pszText = "Type Libraries" ;
  253.     tvis.item.iImage = BMINDEX(IDB_TYPELIBFOLDER) ;
  254.     tvis.item.iSelectedImage = BMINDEX(IDB_TYPELIBFOLDER) ;
  255.     m_hTypeLibs = GetTreeCtrl().InsertItem( &tvis ) ;
  256.  
  257.     tvis.item.pszText = "Interfaces" ;
  258.     tvis.item.iImage = BMINDEX(IDB_IFACEFOLDER) ;
  259.     tvis.item.iSelectedImage = BMINDEX(IDB_IFACEFOLDER) ;
  260.     m_hInterfaces = GetTreeCtrl().InsertItem( &tvis ) ;
  261. }
  262.  
  263. void CObjTreeView::OnDestroy()
  264. {
  265.     DeleteTreeContents() ;
  266.     CTreeView::OnDestroy();
  267. }
  268.  
  269.  
  270. void CObjTreeView::OnLButtonDblClk(UINT nFlags, CPoint point)
  271. {
  272.     UINT hitflags ;
  273.     HTREEITEM hitem ;
  274.  
  275.     hitem = GetTreeCtrl().HitTest( point, &hitflags ) ;
  276.     if (hitflags & (TVHT_ONITEM | TVHT_ONITEMBUTTON))
  277.     {
  278.         NM_TREEVIEW nm ;
  279.         nm.itemNew.mask = TVIF_PARAM  ;
  280.         nm.itemNew.hItem = hitem ;
  281.         if (GetTreeCtrl().GetItem( &nm.itemNew ))
  282.         {
  283.             CObjectData* pObjectData = (CObjectData*)nm.itemNew.lParam;
  284.             CallInterfaceViewer(pObjectData, nm.itemNew.hItem);
  285.         }
  286.     }
  287.     CTreeView::OnLButtonDblClk(nFlags, point);
  288. }
  289.  
  290.  
  291. /////////////////////////////////////////////////////////////////////////////
  292. // CObjTreeView drawing
  293.  
  294. BOOL HasServer32( HKEY hkCLSID )
  295. {
  296.     HKEY hkTemp ;
  297.     if ((RegOpenKey( hkCLSID, _T("InprocServer32"), &hkTemp ) == ERROR_SUCCESS) ||
  298.         (RegOpenKey( hkCLSID, _T("InprocHandler32"), &hkTemp ) == ERROR_SUCCESS) ||
  299.         (RegOpenKey( hkCLSID, _T("LocalServer32"), &hkTemp ) == ERROR_SUCCESS))
  300.     {
  301.         RegCloseKey( hkTemp ) ;
  302.         return TRUE ;
  303.     }
  304.  
  305.     return FALSE ;
  306. }
  307.  
  308. BOOL HasServer16( HKEY hkCLSID )
  309. {
  310.     HKEY hkTemp ;
  311.     if ((RegOpenKey( hkCLSID, _T("InprocServer"), &hkTemp ) == ERROR_SUCCESS) ||
  312.         (RegOpenKey( hkCLSID, _T("InprocHandler"), &hkTemp ) == ERROR_SUCCESS) ||
  313.         (RegOpenKey( hkCLSID, _T("LocalServer"), &hkTemp ) == ERROR_SUCCESS))
  314.     {
  315.         RegCloseKey( hkTemp ) ;
  316.         return TRUE ;
  317.     }
  318.  
  319.     return FALSE ;
  320. }
  321.  
  322. void CObjTreeView::DeleteTreeItems( HTREEITEM htree )
  323. {
  324.     HTREEITEM       hItem, hItemNext ;
  325.  
  326.     hItem = GetTreeCtrl().GetChildItem( htree ) ;
  327.     while( hItem )
  328.     {
  329.         hItemNext = GetTreeCtrl().GetNextSiblingItem( hItem ) ;
  330.         GetTreeCtrl().DeleteItem( hItem ) ;
  331.         hItem = hItemNext ;
  332.     }
  333. }
  334.  
  335. void CObjTreeView::DeleteTreeContents()
  336. {
  337.     // Delete current contents
  338.     //
  339.     if ((int)GetTreeCtrl().GetCount() > 0)
  340.     {
  341.         DeleteTreeItems( m_hInsertable ) ;
  342.         DeleteTreeItems( m_hControls ) ;
  343.         DeleteTreeItems( m_hInternal ) ;
  344. #ifdef SHOW_CONTAINERS
  345.         DeleteTreeItems( m_hContainers ) ;
  346. #endif
  347.         DeleteTreeItems( m_hOLE1 ) ;
  348.         DeleteTreeItems( m_hUnclassified ) ;
  349.  
  350.         DeleteTreeItems( m_hTypeLibs ) ;
  351.         DeleteTreeItems( m_hInterfaces ) ;
  352.     }
  353. }
  354.  
  355. void CObjTreeView::OnDraw( CDC* /*pdc */ )
  356. {
  357. }
  358.  
  359. void CObjTreeView::OnUpdate( CView* pSender, LPARAM lHint, CObject* pHint )
  360. {
  361.     pSender; pHint ;
  362.     if (lHint & UPD_NOOBJECTVIEW)
  363.         return ;
  364.  
  365.     BeginWaitCursor() ;
  366.     GetTreeCtrl().SetRedraw( FALSE ) ;
  367.     GetTreeCtrl().SelectItem( NULL ) ;
  368.  
  369.     if ((int)GetTreeCtrl().GetCount() > 0)
  370.     {
  371.         BOOL fExpanded = FALSE ;
  372.         TV_ITEM tvi ;
  373.         tvi.mask = TVIF_STATE ;
  374.  
  375.         tvi.hItem = m_hInsertable ;
  376.         if (GetTreeCtrl().GetItem( &tvi ))
  377.         {
  378.             fExpanded = (tvi.state & TVIS_EXPANDED) ;
  379.             GetTreeCtrl().Expand( tvi.hItem, TVE_COLLAPSE ) ;
  380.             DeleteTreeItems( tvi.hItem ) ;
  381.             tvi.state &= ~TVIS_EXPANDEDONCE ;
  382.             GetTreeCtrl().SetItem( &tvi ) ;
  383.             if (fExpanded)
  384.                 GetTreeCtrl().Expand( tvi.hItem, TVE_EXPAND ) ;
  385.         }
  386.  
  387.         tvi.hItem = m_hControls ;
  388.         if (GetTreeCtrl().GetItem( &tvi ))
  389.         {
  390.             fExpanded = (tvi.state & TVIS_EXPANDED) ;
  391.             GetTreeCtrl().Expand( tvi.hItem, TVE_COLLAPSE ) ;
  392.             DeleteTreeItems( tvi.hItem ) ;
  393.             tvi.state &= ~TVIS_EXPANDEDONCE ;
  394.             GetTreeCtrl().SetItem( &tvi ) ;
  395.             if (fExpanded)
  396.                 GetTreeCtrl().Expand( tvi.hItem, TVE_EXPAND ) ;
  397.         }
  398.  
  399.         tvi.hItem = m_hInternal ;
  400.         if (GetTreeCtrl().GetItem( &tvi ))
  401.         {
  402.             fExpanded = (tvi.state & TVIS_EXPANDED) ;
  403.             GetTreeCtrl().Expand( tvi.hItem, TVE_COLLAPSE ) ;
  404.             DeleteTreeItems( tvi.hItem ) ;
  405.             tvi.state &= ~TVIS_EXPANDEDONCE ;
  406.             GetTreeCtrl().SetItem( &tvi ) ;
  407.             if (fExpanded)
  408.                 GetTreeCtrl().Expand( tvi.hItem, TVE_EXPAND ) ;
  409.         }
  410.  
  411.         tvi.hItem = m_hOLE1 ;
  412.         if (GetTreeCtrl().GetItem( &tvi ))
  413.         {
  414.             fExpanded = (tvi.state & TVIS_EXPANDED) ;
  415.             GetTreeCtrl().Expand( tvi.hItem, TVE_COLLAPSE ) ;
  416.             DeleteTreeItems( tvi.hItem ) ;
  417.             tvi.state &= ~TVIS_EXPANDEDONCE ;
  418.             GetTreeCtrl().SetItem( &tvi ) ;
  419.             if (fExpanded)
  420.                 GetTreeCtrl().Expand( tvi.hItem, TVE_EXPAND ) ;
  421.         }
  422.  
  423.         tvi.hItem = m_hUnclassified ;
  424.         if (GetTreeCtrl().GetItem( &tvi ))
  425.         {
  426.             fExpanded = (tvi.state & TVIS_EXPANDED) ;
  427.             GetTreeCtrl().Expand( tvi.hItem, TVE_COLLAPSE ) ;
  428.             DeleteTreeItems( tvi.hItem ) ;
  429.             tvi.state &= ~TVIS_EXPANDEDONCE ;
  430.             GetTreeCtrl().SetItem( &tvi ) ;
  431.             if (fExpanded)
  432.                 GetTreeCtrl().Expand( tvi.hItem, TVE_EXPAND ) ;
  433.         }
  434.  
  435.         tvi.hItem = m_hTypeLibs ;
  436.         if (GetTreeCtrl().GetItem( &tvi ))
  437.         {
  438.             fExpanded = (tvi.state & TVIS_EXPANDED) ;
  439.             GetTreeCtrl().Expand( tvi.hItem, TVE_COLLAPSE ) ;
  440.             DeleteTreeItems( tvi.hItem ) ;
  441.             tvi.state &= ~TVIS_EXPANDEDONCE ;
  442.             GetTreeCtrl().SetItem( &tvi ) ;
  443.             if (fExpanded)
  444.                 GetTreeCtrl().Expand( tvi.hItem, TVE_EXPAND ) ;
  445.         }
  446.  
  447.         tvi.hItem = m_hInterfaces ;
  448.         if (GetTreeCtrl().GetItem( &tvi ))
  449.         {
  450.             fExpanded = (tvi.state & TVIS_EXPANDED) ;
  451.             GetTreeCtrl().Expand( tvi.hItem, TVE_COLLAPSE ) ;
  452.             DeleteTreeItems( tvi.hItem ) ;
  453.             tvi.state &= ~TVIS_EXPANDEDONCE ;
  454.             GetTreeCtrl().SetItem( &tvi ) ;
  455.             if (fExpanded)
  456.                 GetTreeCtrl().Expand( tvi.hItem, TVE_EXPAND ) ;
  457.         }
  458.     }
  459.  
  460.     GetTreeCtrl().SetRedraw( TRUE ) ;
  461.     EndWaitCursor() ;
  462. }
  463.  
  464.  
  465. /////////////////////////////////////////////////////////////////////////////
  466. // CObjTreeView diagnostics
  467.  
  468. #ifdef _DEBUG
  469. void CObjTreeView::AssertValid() const
  470. {
  471.     CTreeView::AssertValid();
  472. }
  473.  
  474. void CObjTreeView::Dump(CDumpContext& dc) const
  475. {
  476.     CTreeView::Dump(dc);
  477. }
  478.  
  479. #endif //_DEBUG
  480.  
  481. /////////////////////////////////////////////////////////////////////////////
  482. // CObjTreeView message handlers
  483.  
  484. void CObjTreeView::OnTreeSelchanged(NMHDR* pNMHDR, LRESULT* pResult)
  485. {
  486.     COle2ViewDoc*   pDoc = GetDocument() ;
  487.     NM_TREEVIEW* pnmtv = (NM_TREEVIEW*)pNMHDR;
  488.     CObjectData*    lpOD ;
  489.  
  490.     lpOD = (CObjectData*)pnmtv->itemNew.lParam ;
  491.  
  492.     // special case typelibs because there may be multiple entries (versions)
  493.     // for a given TYPELIBID
  494.     //
  495.     if (lpOD && (!IsEqualCLSID( lpOD->m_clsid, pDoc->m_clsidCur ) || pDoc->m_fTypeLib))
  496.     {
  497.         pDoc->m_fTypeLib = (lpOD->m_uiBitmap == BMINDEX(IDB_AUTOMATION)) ;
  498.         pDoc->m_fInterface = (lpOD->m_uiBitmap == BMINDEX(IDB_INTERFACE)) ;
  499.         pDoc->m_clsidCur = lpOD->m_clsid ;
  500.  
  501.         TV_ITEM tvi ;
  502.         tvi.hItem = pnmtv->itemNew.hItem ;
  503.         tvi.mask = TVIF_TEXT ;
  504.         tvi.cchTextMax = 256 ;
  505.         tvi.pszText = new TCHAR[256] ;
  506.         if (GetTreeCtrl().GetItem( &tvi ))
  507.         {
  508.             pDoc->m_szObjectCur = tvi.pszText ;
  509.         }
  510.         else
  511.             pDoc->m_szObjectCur = "ERROR" ;
  512.         delete tvi.pszText ;
  513.     }
  514.     else
  515.     {
  516.         pDoc->m_fTypeLib = FALSE ;
  517.         pDoc->m_fInterface = FALSE ;
  518.         pDoc->m_clsidCur =  GUID_NULL;
  519.         pDoc->m_szObjectCur = "" ;
  520.     }
  521.     pDoc->UpdateAllViews( this, UPD_NOOBJECTVIEW ) ;
  522.     *pResult = 0;
  523. }
  524.  
  525. void CObjTreeView::OnTreeItemExpanding(NMHDR* pNMHDR, LRESULT* pResult)
  526. {
  527.     *pResult = 0;
  528.     COle2ViewDoc*   pDoc = GetDocument() ;
  529.     NM_TREEVIEW* pnmtv = (NM_TREEVIEW*)pNMHDR;
  530.     if (pnmtv->action == TVE_EXPAND && pnmtv->itemNew.hItem != m_hObjects)
  531.     {
  532.         if (pnmtv->itemNew.state & TVIS_EXPANDEDONCE)
  533.             return ;
  534.  
  535.         BeginWaitCursor() ;
  536.         GetTreeCtrl().SetRedraw( FALSE ) ;
  537.  
  538.         if (pnmtv->itemNew.hItem == m_hInterfaces)
  539.             ExpandInterfaces( pnmtv ) ;
  540.         else if (pnmtv->itemNew.hItem == m_hTypeLibs)
  541.             ExpandTypeLibs( pnmtv ) ;
  542.         else if (pnmtv->itemNew.lParam != NULL)
  543.             ExpandObject( pnmtv ) ;
  544.         else
  545.             ExpandClassification( pnmtv ) ;
  546.  
  547.         GetTreeCtrl().SetRedraw( TRUE ) ;
  548.         EndWaitCursor() ;
  549.     }
  550. }
  551.  
  552. void CObjTreeView::ExpandClassification( NM_TREEVIEW* pnmtv )
  553. {
  554.     USES_CONVERSION;
  555.     HKEY    hkCLSID ;
  556.     COle2ViewDoc* pDoc = GetDocument();
  557.  
  558.     if (RegOpenKey( HKEY_CLASSES_ROOT, _T("CLSID"), &hkCLSID) == ERROR_SUCCESS)
  559.     {
  560.         CObjectData* lpOD ;
  561.         LONG     cb ;
  562.         TCHAR    szBuf[_MAX_PATH] ;
  563.         TCHAR    szName[64] ;
  564.         TCHAR    szCLSID[64] ;
  565.         DWORD   dwIndex ;
  566.  
  567.         for ( dwIndex = 0 ;
  568.               RegEnumKey( hkCLSID, dwIndex, szCLSID, sizeof(szCLSID)) == ERROR_SUCCESS ;
  569.               ++dwIndex )
  570.         {
  571.             lpOD = NULL ;
  572.             cb = sizeof(szName);
  573.             if (RegQueryValue( hkCLSID, (LPTSTR)szCLSID, szName, &cb) == ERROR_SUCCESS)
  574.             {
  575.                 lpOD = new CObjectData ;
  576.                 lpOD->m_nType = CObjectData::typeObject ;
  577.                 ASSERT(lpOD) ;
  578.                 ::CLSIDFromString( T2OLE(szCLSID), &lpOD->m_clsid);
  579.                 lpOD->m_szProgID[0] = '\0' ;
  580.  
  581.                 // Assume it's an object
  582.                 lpOD->m_uiBitmap = BMINDEX(IDB_OBJECT) ;
  583.  
  584.  
  585.                 // Now find out more about it.
  586.                 //
  587.                 // #1 Look in CLSID\{clsid} for the \Control key
  588.                 // #2 Assume it is an 'non-embeddable' OLE 2.0 object
  589.                 // #3 If \<progid>\NotInsertable exists we're done
  590.                 // #4 if !#2 then if \<progid>\Insertable it's an insertable OLE 2.0 object
  591.                 //    and we're done
  592.                 // #5 if !#3 see if it's an OLE 1.0 object by checking Ole1Class
  593.                 //
  594.                 HKEY    hkClass, hkTemp ;
  595.  
  596.                 if (RegOpenKey( hkCLSID, szCLSID, &hkClass ) == ERROR_SUCCESS)
  597.                 {
  598.                     BOOL    fHasServer32 = HasServer32( hkClass ) ;
  599.  
  600.                     if (fHasServer32)
  601.                         lpOD->m_uiBitmap = BMINDEX(IDB_OBJECT32) ;
  602.                     else
  603.                         lpOD->m_uiBitmap = BMINDEX(IDB_OBJECT) ;
  604.  
  605.                     // First determine if it is a system component
  606.                     //
  607.                     cb = sizeof(szBuf) ;
  608.                     if (RegQueryValue( hkClass, (LPTSTR)_T("InprocServer32"), szBuf, &cb ) == ERROR_SUCCESS)
  609.                     {
  610.                         if ((0 == lstrcmpi( szBuf, _T("ole32.dll") )) ||
  611.                             (0 == lstrcmpi( szBuf, _T("oleprx32.dll") )) ||
  612.                             (0 == lstrcmpi( szBuf, _T("ole2pr32.dll") )) ||
  613.                             (0 == lstrcmpi( szBuf, _T("olecnv32.dll") )) ||
  614.                             (0 == lstrcmpi( szBuf, _T("oleaut32.dll") )))
  615.                         {
  616.                             lpOD->m_uiBitmap = BMINDEX(IDB_QUESTION32) ;
  617.                         }
  618.                     } // Query InprocServer
  619.                     else if (RegQueryValue( hkClass, (LPTSTR)_T("InprocServer"), szBuf, &cb ) == ERROR_SUCCESS)
  620.                     {
  621.                         if ((0 == lstrcmpi( szBuf, _T("ole2prox.dll") )) ||
  622.                             (0 == lstrcmpi( szBuf, _T("ole2.dll") )) ||
  623.                             (0 == lstrcmpi( szBuf, _T("ole2disp.dll") )))
  624.                         {
  625.                             lpOD->m_uiBitmap = BMINDEX(IDB_QUESTION) ;
  626.                         }
  627.                     }
  628.  
  629.                     // If it has "Ole1Class" then it's an OLE 1.0 object
  630.                     //
  631.                     wsprintf( szBuf, _T("CLSID\\%s\\Ole1Class"), (LPTSTR)szCLSID) ;
  632.                     if (RegOpenKey( HKEY_CLASSES_ROOT, szBuf, &hkTemp ) == ERROR_SUCCESS)
  633.                     {
  634.                         // Is it 32 bit or 16 bit?
  635.                         if (fHasServer32)
  636.                             lpOD->m_uiBitmap = BMINDEX(IDB_OBJECT_INSERTABLE1032) ;   // that succeeded.  This means we're insertable
  637.                         else
  638.                             lpOD->m_uiBitmap = BMINDEX(IDB_OBJECT_INSERTABLE10) ;   // that succeeded.  This means we're insertable
  639.                         RegCloseKey( hkTemp ) ;
  640.                         goto lblInsertInList ;
  641.                     }
  642.                                         // We now recognize the "Control" key which indicates it's
  643.                     // an OLE Custom Control.
  644.                     //
  645.                     wsprintf( szBuf, _T("CLSID\\%s\\Control"), (LPTSTR)szCLSID) ;
  646.                     if (RegOpenKey( HKEY_CLASSES_ROOT, szBuf, &hkTemp ) == ERROR_SUCCESS)
  647.                     {
  648.                         // Is it 32 bit or 16 bit?
  649.                         if (fHasServer32)
  650.                             lpOD->m_uiBitmap = BMINDEX(IDB_OBJECT_CONTROL32) ;
  651.                         else
  652.                             lpOD->m_uiBitmap = BMINDEX(IDB_OBJECT_CONTROL) ;
  653.                         RegCloseKey( hkTemp ) ;
  654.                         goto lblInsertInList ;
  655.                     }
  656.  
  657.                     // If it's not a control, but it's insertable it must be a CD object
  658.                     //
  659.                     wsprintf( szBuf, _T("CLSID\\%s\\Insertable"), (LPTSTR)szCLSID) ;
  660.                     if (RegOpenKey( HKEY_CLASSES_ROOT, szBuf, &hkTemp ) == ERROR_SUCCESS)
  661.                     {
  662.                         // Is it 32 bit or 16 bit?
  663.                         if (fHasServer32)
  664.                             lpOD->m_uiBitmap = BMINDEX(IDB_OBJECT_INSERTABLE32) ;   // that succeeded.  This means we're insertable
  665.                         else
  666.                             lpOD->m_uiBitmap = BMINDEX(IDB_OBJECT_INSERTABLE) ;   // that succeeded.  This means we're insertable
  667.                         RegCloseKey( hkTemp ) ;
  668.                         goto lblInsertInList ;
  669.                     }
  670.  
  671.  
  672.                     cb = sizeof(lpOD->m_szProgID) ;
  673.                     if (RegQueryValue( hkClass, (LPTSTR)_T("ProgID"), lpOD->m_szProgID, &cb) == ERROR_SUCCESS)
  674.                     {
  675.                         HKEY    hkInsertable ;
  676.  
  677.                         // Is it an OLE 1.0 object?
  678.                         //
  679.                         cb = 64 ;
  680.                         if (RegQueryValue( hkClass, (LPTSTR)"Ole1Class", szBuf, &cb ) == ERROR_SUCCESS)
  681.                         {
  682.                             if (fHasServer32)
  683.                                 lpOD->m_uiBitmap = BMINDEX( IDB_OBJECT_INSERTABLE1032 ) ;
  684.                             else
  685.                                 lpOD->m_uiBitmap = BMINDEX( IDB_OBJECT_INSERTABLE10 ) ;
  686.                             goto lblInsertInList ;
  687.                         }
  688.  
  689.                         // Does the object force "NotInsertable"?
  690.                         //
  691.                         wsprintf( szBuf, _T("%s\\NotInsertable"), (LPTSTR)lpOD->m_szProgID ) ;
  692.                         if (RegOpenKey( HKEY_CLASSES_ROOT, szBuf, &hkInsertable ) == ERROR_SUCCESS)
  693.                         {
  694.                             if (fHasServer32)
  695.                                 lpOD->m_uiBitmap = BMINDEX(IDB_OBJECT32) ;
  696.                             else
  697.                                 lpOD->m_uiBitmap = BMINDEX(IDB_OBJECT) ;
  698.  
  699.                             RegCloseKey( hkInsertable ) ;
  700.                             goto lblInsertInList ;
  701.                         }
  702.  
  703.                         // Is it insertable?
  704.                         //
  705.                         wsprintf( szBuf, _T("%s\\Insertable"), (LPTSTR)lpOD->m_szProgID ) ;
  706.                         if (RegOpenKey( HKEY_CLASSES_ROOT, szBuf, &hkInsertable ) == ERROR_SUCCESS)
  707.                         {
  708.                             if (fHasServer32)
  709.                                 lpOD->m_uiBitmap = BMINDEX(IDB_OBJECT_INSERTABLE32) ;   // that succeeded.  This means we're insertable
  710.                             else
  711.                                 lpOD->m_uiBitmap = BMINDEX(IDB_OBJECT_INSERTABLE) ;   // that succeeded.  This means we're insertable
  712.                             RegCloseKey( hkInsertable ) ;
  713.                             goto lblInsertInList ;
  714.                         }
  715.  
  716. #ifdef SHOW_CONTAINERS
  717.                         // Try HKEY_CLASSES_ROOT\szProgID\shell\open to see if it's
  718.                         // a container.
  719.                         //
  720.                         wsprintf( szBuf, _T("%s\\shell\\open"), (LPTSTR)lpOD->m_szProgID ) ;
  721.                         if (RegOpenKey( HKEY_CLASSES_ROOT, szBuf, &hkInsertable ) == ERROR_SUCCESS)
  722.                         {
  723.                             if (fHasServer32)
  724.                                 lpOD->m_uiBitmap = BMINDEX(IDB_CONTAINER32) ;
  725.                             else
  726.                                 lpOD->m_uiBitmap = BMINDEX(IDB_CONTAINER) ;
  727.                             RegCloseKey( hkInsertable ) ;
  728.                             goto lblInsertInList ;
  729.                         }
  730. #endif
  731.                     }
  732.                     RegCloseKey( hkClass ) ;
  733.  
  734.                 }  // if RegOpenKey( ... &hkClass )
  735.  
  736. lblInsertInList:
  737.                 HTREEITEM htree = NULL ;
  738.                 switch( lpOD->m_uiBitmap )
  739.                 {
  740.                     case BMINDEX(IDB_QUESTION):
  741.                     case BMINDEX(IDB_QUESTION32):
  742.                         htree = m_hInternal ;
  743.                     break ;
  744.  
  745.                     case BMINDEX(IDB_OBJECT_INSERTABLE10):
  746.                     case BMINDEX(IDB_OBJECT_INSERTABLE1032):
  747.                         htree = m_hOLE1 ;
  748.                     break ;
  749.  
  750.                     case BMINDEX(IDB_OBJECT_INSERTABLE):
  751.                     case BMINDEX(IDB_OBJECT_INSERTABLE32):
  752.                         htree = m_hInsertable ;
  753.                     break ;
  754.  
  755. #ifdef SHOW_CONTAINERS
  756.                     case BMINDEX(IDB_CONTAINER):
  757.                     case BMINDEX(IDB_CONTAINER32):
  758.                         htree = m_hContainers ;
  759.                     break ;
  760. #endif
  761.  
  762.                     case BMINDEX(IDB_OBJECT_CONTROL):
  763.                     case BMINDEX(IDB_OBJECT_CONTROL32):
  764.                         htree = m_hControls ;
  765.                     break ;
  766.  
  767.                     case BMINDEX(IDB_OBJECT):
  768.                     case BMINDEX(IDB_OBJECT32):
  769.                     default:
  770.                         htree = m_hUnclassified ;
  771.                     break ;
  772.  
  773.                 }
  774.  
  775.                 if (htree && htree == pnmtv->itemNew.hItem)
  776.                 {
  777.                     RegOpenKey( hkCLSID, szCLSID, &hkClass ) ;
  778.                     cb = sizeof(szBuf) ;
  779.                     if (RegQueryValue( hkClass, (LPTSTR)"ToolboxBitmap32", szBuf, &cb ) == ERROR_SUCCESS ||
  780.                         RegQueryValue( hkClass, (LPTSTR)"ToolboxBitmap", szBuf, &cb ) == ERROR_SUCCESS)
  781.                     {
  782.                         TCHAR * pszBitmapModule = _tcstok(szBuf, _T(","));
  783.                         TCHAR * pszBitmapId = _tcstok(NULL, _T(","));
  784.                         HINSTANCE hinstBitmap;
  785.                         int nBitmapId;
  786.                         if ((pszBitmapModule != NULL) && (pszBitmapId != NULL))
  787.                         {
  788.                             LPTSTR p ;
  789.                             if (*pszBitmapModule == '"')
  790.                             {
  791.                                 lstrcpy( pszBitmapModule, pszBitmapModule+1 ) ;
  792.                                 p = strrchr( pszBitmapModule, '"' ) ;
  793.                                 if (p) *p = '\0' ;
  794.                             }
  795.                             nBitmapId = _ttoi(pszBitmapId);
  796.                             if (g_osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
  797.                                 hinstBitmap = LoadLibrary(pszBitmapModule);
  798.                             else
  799.                                 hinstBitmap = LoadLibraryEx(pszBitmapModule, NULL, LOAD_LIBRARY_AS_DATAFILE);
  800.                             if (hinstBitmap && (nBitmapId > 0))
  801.                             {
  802.                                 HBITMAP hbmGlyph = ::LoadBitmap(hinstBitmap, MAKEINTRESOURCE(nBitmapId));
  803.                                 if (hbmGlyph)
  804.                                 {
  805.                                     lpOD->m_uiBitmap = theApp.m_images.Add( CBitmap::FromHandle(hbmGlyph), RGBLTGRAY ) ;
  806.                                     ::DeleteObject(hbmGlyph) ;
  807.                                 }
  808.                                 FreeLibrary( hinstBitmap ) ;
  809.                             }
  810.                         }
  811.                     }
  812.                     RegCloseKey( hkClass ) ;
  813.                     ASSERT(lpOD) ;
  814.  
  815.                     TV_INSERTSTRUCT tvis ;
  816.                     tvis.hParent = htree ;
  817.                     tvis.hInsertAfter = TVI_SORT ;
  818.                     tvis.item.mask = TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE |TVIF_CHILDREN ;
  819.                     tvis.item.cChildren = 1 ;
  820.                     tvis.item.lParam = (LPARAM)(LPVOID)lpOD ;
  821.                     tvis.item.pszText = szName ;
  822.                     tvis.item.iImage = tvis.item.iSelectedImage = lpOD->m_uiBitmap ;
  823.                     GetTreeCtrl().InsertItem( &tvis ) ;
  824.                 }
  825.                 else
  826.                     delete lpOD ;
  827.             }
  828.         }
  829.         RegCloseKey( hkCLSID ) ;
  830.     }
  831. }
  832.  
  833. void CObjTreeView::ExpandTypeLibs( NM_TREEVIEW* /* pnmtv */ )
  834. {
  835.     USES_CONVERSION;
  836.     HKEY    hkTypeLib ;
  837.     if (RegOpenKey( HKEY_CLASSES_ROOT, _T("TypeLib"), &hkTypeLib) == ERROR_SUCCESS)
  838.     {
  839.         LONG    cb ;
  840.         TCHAR    szVer[64] ;
  841.         TCHAR    szName[64] ;
  842.         TCHAR    szGUID[64] ;
  843.         TCHAR    szBuf[256] ;
  844.         DWORD   dwIndex, dwIndex2 ;
  845.         HKEY    hkGUID ;
  846.  
  847.         // Enum \TypeInfo
  848.         for ( dwIndex = 0 ;
  849.               RegEnumKey( hkTypeLib, dwIndex, szGUID, sizeof(szGUID)) == ERROR_SUCCESS ;
  850.               ++dwIndex )
  851.         {
  852.             // Gotta open \TypeInfo\szGUID
  853.             if (RegOpenKey( hkTypeLib, szGUID, &hkGUID ) == ERROR_SUCCESS)
  854.             {
  855.                 // Enum all at this level (major.minor = name)
  856.                 for (dwIndex2 = 0 ;
  857.                     RegEnumKey( hkGUID, dwIndex2, szVer, sizeof(szVer)) == ERROR_SUCCESS ;
  858.                     ++dwIndex2 )
  859.                 {
  860.                     cb = sizeof(szName);
  861.                     if (RegQueryValue( hkGUID, (LPTSTR)szVer, szName, &cb) == ERROR_SUCCESS)
  862.                     {
  863.                         wsprintf( szBuf, _T("%s (Ver %s)"), (LPTSTR)szName, (LPTSTR)szVer ) ;
  864.  
  865.                         CObjectData* lpOD = new CObjectData ;
  866.                         lpOD->m_nType = CObjectData::typeTypeLib ;
  867.                         ::CLSIDFromString(T2OLE(szGUID), &lpOD->m_clsid);
  868.                         lpOD->m_szProgID[0] = '\0' ;
  869.  
  870.                         lpOD->m_uiBitmap = BMINDEX(IDB_AUTOMATION) ;
  871.                         lpOD->m_wMajorVer = (WORD)atoi( szVer ) ;
  872.                         PTSTR p = strrchr( szVer, '.' ) ;
  873.                         if (p)
  874.                             lpOD->m_wMinorVer = (WORD)atoi( p+1 ) ;
  875.                         else
  876.                             lpOD->m_wMinorVer = 0 ;
  877.  
  878.                         TV_INSERTSTRUCT tvis ;
  879.                         tvis.hParent = m_hTypeLibs ;
  880.                         tvis.hInsertAfter = TVI_SORT ;
  881.                         tvis.item.mask = TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
  882.                         tvis.item.iImage = tvis.item.iSelectedImage = lpOD->m_uiBitmap ;
  883.                         tvis.item.lParam = (LPARAM)(LPVOID)lpOD ;
  884.                         tvis.item.pszText = szBuf ;
  885.                         GetTreeCtrl().InsertItem( &tvis ) ;
  886.                     }
  887.                 }
  888.                 RegCloseKey( hkGUID ) ;
  889.             }
  890.         }
  891.         RegCloseKey( hkTypeLib ) ;
  892.     }
  893. }
  894.  
  895. void CObjTreeView::ExpandObject( NM_TREEVIEW* pnmtv )
  896. {
  897.     USES_CONVERSION;
  898.     COle2ViewDoc*   pDoc = GetDocument() ;
  899.     TV_INSERTSTRUCT tvis ;
  900.     CObjectData* pod = (CObjectData*)pnmtv->itemNew.lParam ;
  901.  
  902.     if (pod->m_nType == CObjectData::typeObject)
  903.     {
  904.         HRESULT hr = pod->CreateInstance( pDoc->m_dwClsCtx ) ;
  905.         if (FAILED(hr))
  906.             return ;
  907.  
  908.         tvis.hParent = pnmtv->itemNew.hItem  ;
  909.         tvis.hInsertAfter = TVI_SORT ;
  910.         tvis.item.mask = TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE ;
  911.         tvis.item.iImage = tvis.item.iSelectedImage = BMINDEX(IDB_INTERFACE) ;
  912.  
  913.         HKEY hk ;
  914.         TCHAR szIID[80] ;
  915.         IID  iid ;
  916.         IUnknown* pfoo = NULL ;
  917.         TCHAR szValue[256] ;
  918.         if (RegOpenKey( HKEY_CLASSES_ROOT, _T("Interface"), &hk) == ERROR_SUCCESS)
  919.         {
  920.             for ( DWORD dwIndex = 0 ;
  921.                   RegEnumKey( hk, dwIndex, szIID, sizeof(szIID)) == ERROR_SUCCESS ;
  922.                   ++dwIndex )
  923.             {
  924.                 LONG cb = sizeof(szValue);
  925.                 if (RegQueryValue( hk, (LPTSTR)szIID, szValue, &cb) == ERROR_SUCCESS)
  926.                 {
  927.                     ::CLSIDFromString(T2OLE(szIID), &iid ) ;
  928.                     if (SUCCEEDED(pod->m_punk->QueryInterface( iid, (void**)&pfoo )))
  929.                     {
  930.                         pfoo->Release() ;
  931.                         pfoo = NULL ;
  932.  
  933.                         CObjectData* lpOD = new CObjectData ;
  934.                         lpOD->m_nType = CObjectData::typeInterface ;
  935.                         lpOD->m_clsid = iid ;
  936.                         lpOD->m_szProgID[0] = '\0' ;
  937.                         lpOD->m_uiBitmap = BMINDEX(IDB_INTERFACE) ;
  938.                         lpOD->m_wMajorVer =  lpOD->m_wMajorVer  = 0 ;
  939.                         tvis.item.lParam = (LPARAM)(LPVOID)lpOD ;
  940.                         tvis.item.pszText = szValue ;
  941.                         GetTreeCtrl().InsertItem( &tvis ) ;
  942.                     }
  943.                 }
  944.             }
  945.             RegCloseKey( hk ) ;
  946.         }
  947.     }
  948. }
  949.  
  950. void CObjTreeView::ExpandInterfaces( NM_TREEVIEW* pnmtv )
  951. {
  952.     USES_CONVERSION;
  953.     if (pnmtv->itemNew.hItem == m_hInterfaces)
  954.     {
  955.         TV_INSERTSTRUCT tvis ;
  956.         tvis.hParent = pnmtv->itemNew.hItem  ;
  957.         tvis.hInsertAfter = TVI_SORT ;
  958.         tvis.item.mask = TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE ;
  959.         tvis.item.iImage = tvis.item.iSelectedImage = BMINDEX(IDB_INTERFACE) ;
  960.  
  961.         HKEY hk ;
  962.         TCHAR szTypeLibID[80] ;
  963.         TCHAR szValue[256] ;
  964.         if (RegOpenKey( HKEY_CLASSES_ROOT, _T("Interface"), &hk) == ERROR_SUCCESS)
  965.         {
  966.             for ( DWORD dwIndex = 0 ;
  967.                   RegEnumKey( hk, dwIndex, szTypeLibID, sizeof(szTypeLibID)) == ERROR_SUCCESS ;
  968.                   ++dwIndex )
  969.             {
  970.                 LONG cb = sizeof(szValue);
  971.                 if (RegQueryValue( hk, (LPTSTR)szTypeLibID, szValue, &cb) == ERROR_SUCCESS)
  972.                 {
  973.                     CObjectData* lpOD = new CObjectData ;
  974.                     lpOD->m_nType = CObjectData::typeStaticInterface ;
  975.                     ::CLSIDFromString(T2OLE(szTypeLibID), &lpOD->m_clsid );
  976.                     lpOD->m_szProgID[0] = '\0' ;
  977.                     lpOD->m_uiBitmap = BMINDEX(IDB_INTERFACE) ;
  978.                     lpOD->m_wMajorVer =  lpOD->m_wMajorVer  = 0 ;
  979.  
  980.                     tvis.item.lParam = (LPARAM)(LPVOID)lpOD ;
  981.                     tvis.item.pszText = szValue ;
  982.                     GetTreeCtrl().InsertItem( &tvis ) ;
  983.                 }
  984.             }
  985.             RegCloseKey( hk ) ;
  986.         }
  987.         return ;
  988.     }
  989. }
  990.  
  991. void CObjTreeView::OnTreeItemExpanded(NMHDR* pNMHDR, LRESULT* pResult)
  992. {
  993.     *pResult = 0;
  994.     COle2ViewDoc*   pDoc = GetDocument() ;
  995.     NM_TREEVIEW* pnmtv = (NM_TREEVIEW*)pNMHDR;
  996.     if ( pnmtv->itemNew.lParam != NULL &&
  997.          pnmtv->action == TVE_COLLAPSE)
  998.     {
  999. //        TV_INSERTSTRUCT tvis ;
  1000.         CObjectData* pod = (CObjectData*)pnmtv->itemNew.lParam ;
  1001.  
  1002.         switch(pod->m_nType)
  1003.         {
  1004.         case CObjectData::typeObject:
  1005.         {
  1006.             pod->Release() ;
  1007.             GetTreeCtrl().Expand( pnmtv->itemNew.hItem, TVE_COLLAPSERESET ) ;
  1008.         }
  1009.         break ;
  1010.         }
  1011.     }
  1012.  }
  1013.  
  1014. void CObjTreeView::CallInterfaceViewer(CObjectData* pObjectData, HTREEITEM hItem)
  1015. {
  1016.     COle2ViewDoc*   pDoc = GetDocument() ;
  1017.  
  1018.     if (pObjectData != NULL)
  1019.     {
  1020.         ASSERT_KINDOF(CObjectData,pObjectData);
  1021.  
  1022.         switch(pObjectData->m_nType)
  1023.         {
  1024.         case CObjectData::typeInterface:
  1025.         {
  1026.             CObjectData* podParent = NULL ;
  1027.             TV_ITEM tviParent ;
  1028.             tviParent.hItem = GetTreeCtrl().GetParentItem(hItem);
  1029.             ASSERT(tviParent.hItem) ;
  1030.             tviParent.mask = TVIF_PARAM ;
  1031.             GetTreeCtrl().GetItem( &tviParent ) ;
  1032.             if (tviParent.lParam)
  1033.             {
  1034.                 podParent = (CObjectData*)tviParent.lParam ;
  1035.  
  1036.                 ASSERT(podParent->m_punk) ;
  1037.                 if (podParent->m_punk)
  1038.                     ViewInterface( theApp.m_pMainWnd->GetSafeHwnd(), pObjectData->m_clsid, podParent->m_punk ) ;
  1039.             }
  1040.         }
  1041.         break ;
  1042.  
  1043.         case CObjectData::typeTypeLib:
  1044.         {
  1045.             ITypeLib* pTypeLib ;
  1046.             LCID      lcid = GetUserDefaultLCID() ;
  1047.             HRESULT hr = ::LoadRegTypeLib( pObjectData->m_clsid, pObjectData->m_wMajorVer,
  1048.                                pObjectData->m_wMinorVer, lcid, &pTypeLib ) ;
  1049.             if (FAILED(hr))
  1050.             {
  1051.                 USES_CONVERSION;
  1052.                 TCHAR szTemp[256] ;
  1053.                 LPOLESTR lpStr;
  1054.                 StringFromCLSID(pObjectData->m_clsid, &lpStr);
  1055.                 wsprintf(szTemp, _T("LoadRegTypeLib(%s, %u, %u, %lu, ...) failed."),
  1056.                         OLE2CT(lpStr), pObjectData->m_wMajorVer, pObjectData->m_wMinorVer,
  1057.                         lcid);
  1058.                 CoTaskMemFree(lpStr);
  1059.                 ErrorMessage( szTemp, hr ) ;
  1060.             }
  1061.             else
  1062.             {
  1063.                 ViewInterface( theApp.m_pMainWnd->GetSafeHwnd(), IID_ITypeLib, pTypeLib ) ;
  1064.                 #ifdef _DEBUG
  1065.                 ASSERT( 0 == pTypeLib->Release() ) ;
  1066.                 #else
  1067.                 pTypeLib->Release() ;
  1068.                 #endif
  1069.             }
  1070.         }
  1071.         break ;
  1072.         }
  1073.     }
  1074. }
  1075.  
  1076. void CObjTreeView::OnTreeReturn(NMHDR* /*pNMHDR */, LRESULT* pResult)
  1077. {
  1078.     *pResult = (LRESULT)TRUE ;
  1079.     HTREEITEM hTreeItemSel = GetTreeCtrl().GetSelectedItem() ;
  1080.  
  1081.     if (hTreeItemSel)
  1082.         GetTreeCtrl().Expand( hTreeItemSel, TVE_TOGGLE ) ;
  1083. }
  1084.  
  1085. void CObjTreeView::OnTreeDeleteItem(NMHDR* pNMHDR, LRESULT*)
  1086. {
  1087.     NM_TREEVIEW* pnmtv = (NM_TREEVIEW*)pNMHDR;
  1088.  
  1089.     if (pnmtv->itemOld.lParam)
  1090.     {
  1091.         CObjectData* pod = (CObjectData*)pnmtv->itemOld.lParam ;
  1092.         ASSERT(pod->IsKindOf(RUNTIME_CLASS(CObjectData)));
  1093.         delete (CObjectData*)pnmtv->itemOld.lParam ;
  1094.         pnmtv->itemOld.lParam = NULL ;
  1095.     }
  1096. }
  1097.  
  1098. void CObjTreeView::OnObjectDelete()
  1099. {
  1100.     AfxMessageBox("Not implemented yet" ) ;
  1101.  
  1102. }
  1103.  
  1104. void CObjTreeView::OnObjectVerify()
  1105. {
  1106.     AfxMessageBox("Not implemented yet" ) ;
  1107.  
  1108. }
  1109.  
  1110. BOOL CObjTreeView::IsValidSel()
  1111. {
  1112.     return (GetTreeCtrl().GetSelectedItem() != NULL) ;
  1113. }
  1114.  
  1115. #ifdef _DEBUG
  1116.  
  1117. COle2ViewDoc* CObjTreeView::GetDocument() // non-debug version is inline
  1118. {
  1119.     ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(COle2ViewDoc)));
  1120.     return (COle2ViewDoc*) m_pDocument;
  1121. }
  1122.  
  1123. #endif //_DEBUG
  1124.  
  1125. void CObjTreeView::OnUseInProcServer()
  1126. {
  1127.     COle2ViewDoc*   pDoc = GetDocument() ;
  1128.  
  1129.     if (pDoc->m_dwClsCtx & CLSCTX_INPROC_SERVER)
  1130.         pDoc->m_dwClsCtx &= ~CLSCTX_INPROC_SERVER ;
  1131.     else
  1132.         pDoc->m_dwClsCtx |= CLSCTX_INPROC_SERVER ;
  1133.     if (pDoc->m_dwClsCtx == NULL)
  1134.         pDoc->m_dwClsCtx = CLSCTX_INPROC_SERVER ;
  1135. //    OnUpdate( this, NULL, NULL ) ;
  1136. }
  1137.  
  1138. void CObjTreeView::OnUpdateUseInProcServer(CCmdUI* pCmdUI)
  1139. {
  1140.     COle2ViewDoc*   pDoc = GetDocument() ;
  1141.     pCmdUI->SetCheck( pDoc->m_dwClsCtx & CLSCTX_INPROC_SERVER ? TRUE : FALSE  ) ;
  1142. }
  1143.  
  1144. void CObjTreeView::OnUseInProcHandler()
  1145. {
  1146.     COle2ViewDoc*   pDoc = GetDocument() ;
  1147.     if (pDoc->m_dwClsCtx & CLSCTX_INPROC_HANDLER)
  1148.         pDoc->m_dwClsCtx &= ~CLSCTX_INPROC_HANDLER ;
  1149.     else
  1150.         pDoc->m_dwClsCtx |= CLSCTX_INPROC_HANDLER ;
  1151.     if (pDoc->m_dwClsCtx == NULL)
  1152.         pDoc->m_dwClsCtx = CLSCTX_INPROC_HANDLER ;
  1153. //    OnUpdate( this, NULL, NULL ) ;
  1154. }
  1155.  
  1156. void CObjTreeView::OnUpdateUseInProcHandler(CCmdUI* pCmdUI)
  1157. {
  1158.     COle2ViewDoc*   pDoc = GetDocument() ;
  1159.     pCmdUI->SetCheck( pDoc->m_dwClsCtx & CLSCTX_INPROC_HANDLER ? TRUE : FALSE ) ;
  1160. }
  1161.  
  1162. void CObjTreeView::OnUseLocalServer()
  1163. {
  1164.     COle2ViewDoc*   pDoc = GetDocument() ;
  1165.     if (pDoc->m_dwClsCtx & CLSCTX_LOCAL_SERVER)
  1166.         pDoc->m_dwClsCtx &= ~CLSCTX_LOCAL_SERVER ;
  1167.     else
  1168.         pDoc->m_dwClsCtx |= CLSCTX_LOCAL_SERVER ;
  1169.  
  1170.     if (pDoc->m_dwClsCtx == NULL)
  1171.         pDoc->m_dwClsCtx = CLSCTX_LOCAL_SERVER ;
  1172.  
  1173. //    OnUpdate( this, NULL, NULL ) ;
  1174. }
  1175.  
  1176. void CObjTreeView::OnUpdateUseLocalServer(CCmdUI* pCmdUI)
  1177. {
  1178.     COle2ViewDoc*   pDoc = GetDocument() ;
  1179.     pCmdUI->SetCheck( pDoc->m_dwClsCtx & CLSCTX_LOCAL_SERVER ? TRUE : FALSE ) ;
  1180. }
  1181.  
  1182.  
  1183. void CObjTreeView::OnFileBind()
  1184. {
  1185. }
  1186.