关于IHTMLDOMNode的一些用法(用来显示web page的DOM tree的类)

这篇文章,目前(2008.10.17)我主要借鉴怎样把IHTMLDOMNode与IHTMLDOMChildrenCollection相连接并使用。
  1. 用来显示web page的DOM tree的类,继承自CTreeCtrl --source file
  2. // DOMTree.cpp : implementation file
  3. #include "stdafx.h"
  4. #include "DOMTree.h"
  5. #include <queue> 
  6. #define IDM_EXPANDALL 10001
  7. #define IDM_COLLAPSEALL 10002 
  8. IMPLEMENT_DYNAMIC (CDOMTree, CTreeCtrl) 
  9. BEGIN_MESSAGE_MAP (CDOMTree, CTreeCtrl)
  10.     ON_NOTIFY_REFLECT(TVN_DELETEITEM, OnTvnDeleteitem)
  11.     ON_WM_DESTROY()
  12.     ON_NOTIFY_REFLECT(TVN_SELCHANGED, OnTvnSelchanged)
  13.     ON_COMMAND(IDM_EXPANDALL,OnExpandAll)
  14.     ON_COMMAND(IDM_COLLAPSEALL,OnCollapseAll)
  15.     ON_WM_RBUTTONDOWN()
  16. END_MESSAGE_MAP() 
  17. void CDOMTree::OnTvnDeleteitem(NMHDR *pNMHDR , LRESULT *pResult)
  18. {
  19.     LPNMTREEVIEW pNMTreeView = reinterpret_cast <LPNMTREEVIEW>(pNMHDR);
  20.     TVITEM* pItem = &pNMTreeView->itemOld ; 
  21.     if ( pItem && pItem->lParam)
  22.     {
  23.        IUnknown* pNodeUnknown = reinterpret_cast<IUnknown*>(pItem-> lParam);
  24. #if defined(_DEBUG)
  25.        long relcnt = pNodeUnknown->Release(); // for AddRef when added to the tree item data
  26.        ATLASSERT( relcnt == 0);
  27. #else
  28.        pNodeUnknown->Release ();
  29. #endif
  30.     }
  31.     *pResult = 0;
  32. }
  33. void CDOMTree::OnDestroy()
  34. {
  35.     CTreeCtrl::OnDestroy();
  36. }
  37. void CDOMTree::UpdateDOM(IHTMLDocument2* pDoc )
  38. {
  39.     SetRedraw( FALSE);
  40.     DeleteAllItems();
  41.     m_spDoc2 = pDoc;
  42.     PrepareDOMTree();
  43.     SetRedraw( TRUE);
  44. //a breadth first tree creating algorithm
  45. bool CDOMTree::PrepareDOMTree()
  46. {
  47.     CComQIPtr<IHTMLDocument3> spDoc3 = m_spDoc2;
  48.     bool bRet = spDoc3 != NULL;
  49.     if( !bRet ){
  50.        ATLASSERT(0);
  51.        return bRet;
  52.     } 
  53.     CComPtr <IHTMLElement> spRootElement;
  54.     bRet = SUCCEEDED( spDoc3-> get_documentElement( &spRootElement));
  55.     if( !bRet ) return bRet; 
  56.     CComQIPtr <IHTMLDOMNode> spRootNode = spRootElement ;
  57.     bRet = spRootNode != NULL;
  58.     if ( !bRet ) return bRet;
  59.     std:: queue<HTREEITEM> queue_tree_nodes;
  60.     std::queue<CComQIPtr< IHTMLDOMNode> > queue_DOMNodes;
  61.     queue_DOMNodes .push(spRootNode);
  62.     queue_tree_nodes.push(TVI_ROOT);
  63.     while( !queue_tree_nodes.empty() )
  64.     {
  65.        CComQIPtr<IHTMLDOMNode> spDOMNode=queue_DOMNodes.front();
  66.        HTREEITEM parent=queue_tree_nodes.front ();
  67.        queue_DOMNodes.pop();
  68.        queue_tree_nodes.pop(); 
  69.        HTREEITEM thisnode=InsertDOMNode(spDOMNode, parent);
  70.        CComPtr<IDispatch> spCollectionDispatch;
  71.        if ( SUCCEEDED( spDOMNode->get_childNodes( & spCollectionDispatch)))
  72.        {
  73.            long numChildren = 0;
  74.            CComQIPtr<IHTMLDOMChildrenCollection> spCollection = spCollectionDispatch;
  75.            if (!! spCollection)
  76.            {
  77.               spCollection->get_length( & numChildren);
  78.               for ( long i = 0; i < numChildren; i++)
  79.               {
  80.                   CComPtr<IDispatch> spItemDispatch;
  81.                   spCollection->item( i , &spItemDispatch);
  82.                   if ( !!spItemDispatch)
  83.                   {
  84.                      CComQIPtr<IHTMLDOMNode> spItemNode = spItemDispatch;
  85.                      if ( !!spItemNode)
  86.                      {
  87.                          queue_DOMNodes.push(spItemNode);
  88.                          queue_tree_nodes.push(thisnode);
  89.                      }                      
  90.                   }
  91.               }
  92.            }
  93.        }   
  94.     }
  95.     return bRet;
  96. HTREEITEM CDOMTree::InsertDOMNode( IHTMLDOMNode* pINode, HTREEITEM hparent)
  97. {
  98.     CComPtr<IDispatch> spCollectionDispatch;
  99.     CComPtr<IHTMLDOMNode> spNode(pINode);
  100.     CComBSTR NodeName; 
  101.     TV_INSERTSTRUCT tvis;
  102.     tvis.hParent = hparent;
  103.     tvis.hInsertAfter = TVI_LAST;
  104.     tvis.item.mask =  TVIF_TEXT | TVIF_PARAM;
  105.     if ( SUCCEEDED( spNode->get_nodeName( & NodeName)))
  106.     {
  107.        CString strNodeName( NodeName);
  108.        tvis.item.pszText= strdup(strNodeName);
  109.     }   
  110.     // Need to AddRef because we'll be keeping interface pointer as treeview item data
  111.     pINode->AddRef();
  112.     tvis.item.lParam = reinterpret_cast<LPARAM>(pINode);
  113.     HTREEITEM hthisItem = InsertItem( &tvis );
  114.     if ( hthisItem == NULL)
  115.     {
  116.        pINode->Release();
  117.        return NULL;
  118.     }
  119.     return hthisItem;
  120. void CDOMTree::OnTvnSelchanged(NMHDR *pNMHDR , LRESULT *pResult)
  121. {
  122.     LPNMTREEVIEW pNMTreeView = reinterpret_cast <LPNMTREEVIEW>(pNMHDR);
  123.     TVITEM* pItem = &pNMTreeView->itemNew ;
  124.     IHTMLDOMNode* pDOMNode= reinterpret_cast<IHTMLDOMNode*>(pItem-> lParam);
  125.     *pResult = 0;
  126. void CDOMTree:: OnExpandAll()
  127. {
  128.     ExpandAll();
  129. void CDOMTree::OnCollapseAll()
  130. {
  131.     CollapseAll();
  132. void CDOMTree::OnRButtonDown(UINT nFlags , CPoint point)
  133. {
  134.     CMenu context;
  135.     context.CreatePopupMenu();
  136.     ClientToScreen(&point);
  137.     context.AppendMenu(MF_STRING|MF_ENABLED ,IDM_EXPANDALL,_T("Expand All"));
  138.     context.AppendMenu(MF_STRING|MF_ENABLED ,IDM_COLLAPSEALL,_T("Collapse All"));
  139.     context.TrackPopupMenu( TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON, point.x, point.y, this);
  140.     CTreeCtrl::OnRButtonDown(nFlags, point);
  141. void CDOMTree::ExpandAll()
  142. {
  143.     HTREEITEM hCurrent = GetSelectedItem();
  144.     if ( !hCurrent)
  145.        hCurrent = GetRootItem();
  146.     if ( hCurrent)
  147.     {
  148.        SetRedraw( FALSE);
  149.        // When expanding we must expand parent before its children
  150.        unsigned int flags = DOPARENTFIRST;
  151.        DoForItemAndChildren( hCurrent, ExpandItem, flags);
  152.        EnsureVisible( hCurrent);
  153.        SetRedraw( TRUE);
  154.     }
  155. // Recursive helper that calls a method, that param fp points to, for a hParent node
  156. // and all of its children, its children's children, etc.
  157. // This is one of few cases where I used ->* notation for method call through a pointer
  158. void CDOMTree::DoForItemAndChildren( HTREEITEM hParent, FOREACHITEM fp, unsigned int flags /*= 0*/)
  159. {
  160.     // DOPARENTFIRST flag tells us if we want fp to be called on parent node first, then children, or viceversa
  161.     if ( flags & DOPARENTFIRST)
  162.     {
  163.        if ( !( flags & SKIPTOPPARENT))
  164.            (this->*fp)( hParent);
  165.     } 
  166.     HTREEITEM hChild = GetChildItem(hParent); 
  167.     while ( hChild)
  168.     {
  169.        DoForItemAndChildren( hChild, fp, ( flags & DOPARENTFIRST) ? DOPARENTFIRST : 0);
  170.        hChild = GetNextSiblingItem( hChild);
  171.     }; 
  172.     if ( !(flags & DOPARENTFIRST))
  173.     {
  174.        if ( !( flags & SKIPTOPPARENT))
  175.            (this->*fp)( hParent);
  176.     }
  177. void CDOMTree::CollapseAll()
  178. {
  179.     HTREEITEM hCurrent = GetSelectedItem();
  180.     if ( !hCurrent)
  181.        hCurrent = GetRootItem();
  182.     if ( hCurrent)
  183.     {
  184.        SetRedraw( FALSE);
  185.        Expand( hCurrent, TVE_COLLAPSE);
  186.        SetRedraw( TRUE);
  187.     }
  188. }

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值