CTreeCtrl的用法



一 基础操作 

1 插入节点

1)插入根节点

 

[cpp]  view plain  copy
  1. //插入根节点  
  2. HTREEITEM hRoot;  
  3. CString str=L"ROOT"  
  4. hRoot=nTreeCtrl.InsertItem(str);    
  5.   
  6. //相当于   
  7. hRoot=nTreeCtrl.InsertItem(str,TVI_ROOT,TVI_LAST);  


2)插入孩子节点

 

[cpp]  view plain  copy
  1. //添加hRoot节点的孩子节点,并且被添加的节点位于hRoot所有孩子节点的末尾  
  2. HTREEITEM hChild=nTreeCtrl.InsertItem(str,hRoot);  
  3.   
  4. //相当于  
  5. HTREEITEM hChild=nTreeCtrl.InsertItem(str,hRoot,TVI_LAST);  


 

2 获得节点句柄

[cpp]  view plain  copy
  1. //获得根节点  
  2. HTREEITEM hRootItem;  
  3. hRootItem=nTreeCtrl.GetRootItem();  
  4.   
  5.   
  6. //获得当前节点  
  7. HTREEITEM hCurrentItem;  
  8. hCurrentItem=nTreeCtrl.GetSelectedItem();  
  9.   
  10.   
  11. //获得hItem的前一个节点  
  12.   
  13. HTREEITEM hPreItem;  
  14. hPreItem=nTreeCtrl.GetNextItem(hItem,TVGN_PREVIOUS);  
  15.   
  16.   
  17. //获得hItem的下一个节点  
  18. HTREEITEM hNextItem;  
  19. hNextItem=nTreeCtrl.GetNextItem(hItem,TVGN_NEXT);  


 

3 判断某节点是否有孩子节点

[cpp]  view plain  copy
  1. //判断某节点是否有孩子节点  
  2. if (nTreeCtrl.ItemHasChildren(hRoot))  

 

4 展开或收缩子节点

[cpp]  view plain  copy
  1. //展开  
  2. if(nTreeCtrl.ItemHasChildren(hRoot))  
  3.     nTreeCtrl.Expand(hParentItem,TVE_EXPAND);  


 


5 获得第一个孩子节点的句柄

[cpp]  view plain  copy
  1. //判断某节点是否有孩子节点  
  2. if (nTreeCtrl.ItemHasChildren(hRoot))  
  3. {  
  4.     //获得孩子节点  
  5.     HTREEITEM hChild=nTreeCtrl.GetChildItem(hRoot);  
  6.   
  7. }  


6 遍历hRoot下一层的所有孩子节点

 

[cpp]  view plain  copy
  1. //判断某节点是否有孩子节点  
  2. if (nTreeCtrl.ItemHasChildren(hRoot))  
  3. {  
  4.     //获得孩子节点  
  5.     HTREEITEM hChild=nTreeCtrl.GetChildItem(hRoot);  
  6.   
  7.     //遍历hRoot下一层的所有孩子节点  
  8.     while(hChild)  
  9.     {  
  10.         hChild=nTreeCtrl.GetNextItem(hChild,TVGN_NEXT);  
  11.   
  12.     }  
  13.   
  14. }  


 

7  获得某节点上的文字

[cpp]  view plain  copy
  1. //获得某节点上的文字  
  2. CString str;  
  3. nTreeCtrl.GetItemText(hRoot);  

 

8 选择某节点,并让其获得焦点

   首先,TREE控件的样式必须设置为TVS_SHOWSELALWAYS 

   其次: 选择该节点

[html]  view plain  copy
  1. treeCtrl.SelectItem(hItem);  

  最后,设置焦点

[html]  view plain  copy
  1. treeCtrl.SetFocus();  

Tree控件设置焦点后,会自动将焦点定位到选择的节点上


9  清空树控件

[cpp]  view plain  copy
  1. <strong>  nTreeCtrl.DeleteAllItems();</strong>  


 10  将指定目录下的文件插入节点

 

[cpp]  view plain  copy
  1. void InsertPath(CString path, HTREEITEM hRoot, CTreeCtrl& ctrl)  
  2. {  
  3.     CFileFind nFindFile;  
  4.     CString str=L"";  
  5.     CString nPicFileName=L"";  
  6.     BOOL IsExist=FALSE;  
  7.     HTREEITEM hSubItem;  
  8.   
  9.     nPicFileName.Format(L"%s\\*.*",path);  
  10.     IsExist = nFindFile.FindFile(nPicFileName);  
  11.     while (IsExist)  
  12.     {  
  13.         IsExist = nFindFile.FindNextFile();  
  14.         if(nFindFile.IsDots())  
  15.             continue;  
  16.         nPicFileName = nFindFile.GetFileName();  
  17.   
  18.         //路径  
  19.         if(nFindFile.IsDirectory())  
  20.         {  
  21.             hSubItem = ctrl.InsertItem(nPicFileName,hRoot);  
  22.             InsertPath(nFindFile.GetFilePath(),hSubItem,ctrl);  
  23.         }  
  24.         else  
  25.         {  
  26.             //文件  
  27.             str = nPicFileName.Right(4);  
  28.             if(!str.CompareNoCase(_T(".jpg")) || !str.CompareNoCase(_T(".tif")))  
  29.             {  
  30.                 ctrl.InsertItem(nPicFileName,hRoot);  
  31.             }  
  32.         }  
  33.     }  
  34.     nFindFile.Close();  
  35. }  


 

[cpp]  view plain  copy
  1. void LoadPath(CString path) //path为指定目录   此函数的作用为将path目录下的文件插入树控件中  
  2. {  
  3.     CTreeCtrl& ctrl = GetTreeCtrl();  
  4.     ASSERT(ctrl);   
  5.     ctrl.DeleteAllItems();  
  6.     HTREEITEM hRoot = ctrl.InsertItem(path);  
  7.     InsertPath(path,hRoot,ctrl);  
  8.     ctrl.Expand(hRoot,TVE_EXPAND);  
  9.   
  10. }  


11 将文件列表中的文件插入树控件中

[cpp]  view plain  copy
  1. void InsetAllFile( list<CString>& filePathList){  
  2.   
  3.   
  4.     CTreeCtrl & nTreeCtrl=((CMyTreeView*)(((CMainFrame*)AfxGetMainWnd())->m_SplitterWnd.GetPane(0,0)))->GetTreeCtrl();  
  5.     nTreeCtrl.DeleteAllItems();  
  6.   
  7.     list<CString>::iterator it=filePathList.begin();  
  8.     HTREEITEM hRoot=NULL;  
  9.     CString filePath;  
  10.     CString treeRootName=L"根目录";  //所有的文件都在根目录下  即:默认所有的文件都在同一个目录下  
  11.   
  12.     while(it!=filePathList.end())  
  13.     {  
  14.         filePath=*it;    
  15.           
  16.   
  17.   
  18.         if(hRoot==NULL)  
  19.             hRoot=nTreeCtrl.InsertItem(treeRootName);  //建立根目录  
  20.   
  21.   
  22.   
  23.         if(filePath.Find(treeRootName)==0) // 文件第一层目录与根目录相同,则截去文件第一层目录,文件从第二层目录开始  
  24.             filePath=filePath.Right(filePath.GetLength()-treeRootName.GetLength()-1);  
  25.   
  26.   
  27.         LoadPicFiles(nTreeCtrl,filePath, hRoot);  
  28.   
  29.         it++;  
  30.     }  
  31.   
  32. }  


[cpp]  view plain  copy
  1. void LoadPicFiles(CTreeCtrl& nTreeCtrl, CString nFilePath, HTREEITEM nRoot)  
  2. {  
  3.   
  4. // 判断nPicFolder是目录还是文件  
  5. // 如果是文件  
  6. //     直接将文件插入到树控件中 nTreeCtrl.InsertItem(nPicFolder,nRoot);  
  7. // 如果是目录  
  8. //     获取nPicFolder的第一层目录  
  9. //     判断nRoot目录下是否已经有此层目录  
  10. //     如果有此层目录  
  11. //         递归插入其他  
  12. //     如果无此层目录  
  13. //         插入此层目录,然后递归插入其他  
  14.   
  15.   
  16.     CString nSubFolder;     //首层目录  
  17.     CString nSubFilePath;   //去掉首层目录后的文件名  
  18.     BOOL IsExist=FALSE;  
  19.   
  20.       
  21.   
  22.     int nIndex=-1;  
  23.     nIndex=nFilePath.Find(L'\\');  
  24.   
  25.     if(nIndex>=0) //目录  
  26.     {  
  27.         nSubFolder=nFilePath.Left(nIndex);  
  28.         nSubFilePath=nFilePath.Right(nFilePath.GetLength()-nIndex-1);  
  29.   
  30.         HTREEITEM nSubRoot=NULL;  
  31.         if(nTreeCtrl.ItemHasChildren(nRoot))  
  32.             nSubRoot=nTreeCtrl.GetChildItem(nRoot);  
  33.         CString str;  
  34.         BOOL  bExist=FALSE;  
  35.         while(nSubRoot)  
  36.         {  
  37.             str=nTreeCtrl.GetItemText(nSubRoot);  
  38.   
  39.             if (str.CompareNoCase(nSubFolder)==0)  
  40.             {  
  41.   
  42.                 bExist=TRUE;  
  43.                 break;  
  44.             }  
  45.   
  46.             nSubRoot=nTreeCtrl.GetNextSiblingItem(nSubRoot);  
  47.         }  
  48.   
  49.         if(!bExist)  
  50.         {  
  51.   
  52.             nSubRoot=nTreeCtrl.InsertItem(nSubFolder,nRoot);  
  53.   
  54.             LoadPicFiles(nTreeCtrl,nSubFilePath,nSubRoot);  
  55.         }else{  
  56.             LoadPicFiles(nTreeCtrl,nSubFilePath,nSubRoot);  
  57.         }  
  58.     }  
  59.     else if(nFilePath.Find(L".jpg")!=-1 || nFilePath.Find(L".tif")!=-1)  
  60.     {  
  61.         nTreeCtrl.InsertItem(nFilePath,nRoot);  
  62.     }  
  63. }  



-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

二 扩展操作

 

1 响应TVN_ITEMEXPANDING  消息时   如何获得将要展开或收缩的那一个节点的句柄

MSDN:

 

TVN_ITEMEXPANDING pnmtv = (NM_TREEVIEW FAR *) lParam
pnmtv
Pointer to an  NM_TREEVIEW structure. The itemNew member is a TVITEM structure that contains valid information about the parent item in the hItem, state, and lParam members. The action member indicates whether the list is to expand or collapse. For a list of possible values, see the description of the TVM_EXPAND message.

。。。。。。。。。

[cpp]  view plain  copy
  1. typedef struct _NM_TREEVIEW {   
  2.   NMHDR hdr;   
  3.   UINT action;   
  4.   TV_ITEM itemOld;   
  5.   TV_ITEM itemNew;   
  6.   POINT ptDrag;   
  7. } NM_TREEVIEW;  
  8. typedef NM_TREEVIEW FAR* LPNM_TREEVIEW;  
  9.    

 

[cpp]  view plain  copy
  1. typedef struct _TV_ITEM { tvi  
  2.   UINT mask;   
  3.   HTREEITEM hItem;   
  4.   UINT state;   
  5.   UINT stateMask;   
  6.   LPSTR pszText;   
  7.   int cchTextMax;   
  8.   int iImage;   
  9.   int iSelectedImage;   
  10.   int cChildren;   
  11.   LPARAM lParam; }   
  12. TV_ITEM, FAR* LPTV_ITEM;  
  13.    


在 TV_ITEM 的 hItem中 存放着要展开项的句柄

 

解决:查了这么多,其实很简单 代码如下:

 

[cpp]  view plain  copy
  1. void CLeftView::OnItemexpanding(NMHDR* pNMHDR, LRESULT* pResult)  
  2. {  
  3.     LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);  
  4.     // TODO: 在此添加控件通知处理程序代  
  5.     HTREEITEM htree=pNMTreeView->itemNew.hItem; // 这个就是 将要被扩展或收缩节点的句柄  
  6.   
  7. 。。。  
  8. }  

 

 

2 怎么知道CTreeCtrl的一个节点是展开的还是收缩着的

 解决:

方法1

[cpp]  view plain  copy
  1. <strong>     (GetItemState(hItem,   TVIS_EXPANDED   )&TVIS_EXPANDED)!=TVIS_EXPANDED  //如果相等,则说明改节点是扩展的,如果不相等,则说明该节点是收缩的</strong>  

 

方法2

响应TVN_ITEMEXPANDING事件时:

[cpp]  view plain  copy
  1. void CExampleDlg::OnItemexpandingTree1(NMHDR* pNMHDR, LRESULT* pResult)   
  2.   
  3. {   
  4.   
  5. NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;   
  6.   
  7. if (pNMTreeView->action == TVE_COLLAPSE)   //判断action的值  
  8.   
  9. 。。。  
  10.   
  11. 。。。  
  12.   
  13. }  


 

 

 3  判断节点是否被扩展过

[cpp]  view plain  copy
  1. if ((GetTreeCtrl().GetItemState(hItem,TVIS_EXPANDEDONCE )&TVIS_EXPANDEDONCE )!=0 ) //判断是否扩展过一次,若!=0则说明被扩展过   


 


4   使用 CImageList m_ImageList; 加载位图或图标,并将其与树控件联系在一起,由此便可以设置每个节点的图标

 

[cpp]  view plain  copy
  1.      CImageList m_ImageList;  
  2. m_ImageList.Create(12,12,ILC_COLORDDB | ILC_MASK, 3, 1);  
  3. HICON hAdd=::LoadIcon(::AfxGetInstanceHandle(), (LPCTSTR)IDI_ADD);  
  4. HICON hRemove=::LoadIcon(::AfxGetInstanceHandle(), (LPCTSTR)IDI_REMOVE);  
  5. HICON hLeaf=::LoadIcon(::AfxGetInstanceHandle(), (LPCTSTR)IDI_LEAF);  
  6. m_ImageList.Add(hAdd);  
  7. m_ImageList.Add(hRemove);  
  8. m_ImageList.Add(hLeaf);  
  9. GetTreeCtrl().SetImageList(&m_ImageList,TVSIL_NORMAL);  // 树控件和图像列表相连  
[cpp]  view plain  copy
  1.          m_treeCtrl.SetItemImage(htree,0,0)   // 通过SetItemImage(htree,0,0) 设置节点的图标  


 

 5  什么时候响应OnItemexpanding 消息

 

     当节点第一次被展开时,才响应此消息。也就是说:当以开后该节点再展开或收缩时,便不再响应此消息了。

 

6  设置树控件形式为 TVS_HASBUTTONS|TVS_LINESATROOT 时, 树控件节点前才会出现+ - 号

 


以下为综合例子: 点击按钮上一个 显示该节点的上一个兄弟节点,并更改控件焦点

 

设置控件样式:

[html]  view plain  copy
  1. BOOL CTreePathView::PreCreateWindow(CREATESTRUCT& cs)  
  2. {  
  3.     // TODO: 在此处通过修改  
  4.     //  CREATESTRUCT cs 来修改窗口类或样式  
  5.   
  6.     cs.style|=TVS_HASLINES|TVS_SHOWSELALWAYS;   //若是想用CImageList的图标 ,则不要设置为TVS_HASBUTTONS形式  
  7.   
  8.   
  9.     return CTreeView::PreCreateWindow(cs);  
  10. }  


点击按钮5(焦点移动到上一个兄弟节点)

[html]  view plain  copy
  1. void NewImageView::OnBnClickedButton5() // 上一个图  
  2. {  
  3.     // TODO: 在此添加控件通知处理程序代码  
  4.   
  5.     CTreePathView * pTree=(CTreePathView* )(((CMainFrame *)AfxGetMainWnd())->m_wndSplitter.GetPane(0,0));  
  6.   
  7.     CTreeCtrl & treeCtrl=pTree->GetTreeCtrl();  
  8.   
  9.     HTREEITEM hItem=treeCtrl.GetSelectedItem();  
  10.     if (hItem!=NULL)  
  11.     {  
  12.         hItem=treeCtrl.GetNextItem(hItem,TVGN_PREVIOUS);  
  13.   
  14.         if (hItem!=NULL)  
  15.         {  
  16.             CString str;  
  17.             str=pTree->GetFullPath(hItem);  
  18.             SetImage(str);  
  19.             treeCtrl.SelectItem(hItem);  
  20.             treeCtrl.SetFocus();  
  21.             InvalidateRect(m_ClientRect);  
  22.         }  
  23.     }  
  24. }  


 

点击按钮6(焦点移动到下一个兄弟节点)

 

[html]  view plain  copy
  1. void NewImageView::OnBnClickedButton6() //下一个  
  2. {  
  3.     // TODO: 在此添加控件通知处理程序代码  
  4.   
  5.     CTreePathView * pTree=(CTreePathView* )(((CMainFrame *)AfxGetMainWnd())->m_wndSplitter.GetPane(0,0));  
  6.     CTreeCtrl & treeCtrl=pTree->GetTreeCtrl();  
  7.     HTREEITEM hItem=treeCtrl.GetSelectedItem();  
  8.   
  9.     if (hItem!=NULL)  
  10.     {  
  11.         hItem=treeCtrl.GetNextItem(hItem,TVGN_NEXT);  
  12.   
  13.         if (hItem!=NULL)  
  14.         {  
  15.             CString str;  
  16.             str=pTree->GetFullPath(hItem);  
  17.             SetImage(str);  
  18.   
  19.             treeCtrl.SelectItem(hItem);  
  20.             treeCtrl.SetFocus();  
  21.             InvalidateRect(m_ClientRect);  
  22.         }  
  23.     }  
  24. }  


 

7  遍历树控件的所有节点

 

1) 获得根节点句柄

[cpp]  view plain  copy
  1. CTreeCtrl& nTreeCtrl=((CImportTreeView*)m_SplitterWnd.GetPane(0,0))->GetTreeCtrl();  
  2.   
  3. HTREEITEM hItem;  
  4. //获得根目录节点  
  5. hItem = nTreeCtrl.GetRootItem();  
  6. //遍历树控件节点  
  7. TreeVisit(&nTreeCtrl,hItem);  

 

2)遍历所有节点

[cpp]  view plain  copy
  1. void TreeVisit(CTreeCtrl* pCtrl,HTREEITEM hItem)   
  2. {      
  3.     if(pCtrl->ItemHasChildren(hItem))       
  4.     {   
  5.         HTREEITEM   hChildItem = pCtrl->GetChildItem(hItem);       
  6.         while(hChildItem!=NULL)       
  7.         {   
  8.             TreeVisit(pCtrl,hChildItem); //递归遍历孩子节点       
  9.             hChildItem  = pCtrl->GetNextItem(hChildItem, TVGN_NEXT);       
  10.         }       
  11.     }  
  12.     else // 对叶子节点进行操作  
  13.         Leaf(pCtrl,hItem);  
  14. }  



8 获得某Item节点的全路径

   

[cpp]  view plain  copy
  1. CString m_ParentFolder[10];  
  2. CString m_OldParentFolder[10];  


 

[cpp]  view plain  copy
  1. //--------------------将nParent添加到nParentFolder[10]第一位----------------------  
  2. BOOL AddParentFolder(CString nParentFolder[10], CString nParent)  
  3. {  
  4.     for(int i=9;i>0;i--)  
  5.         nParentFolder[i]=nParentFolder[i-1];  
  6.     nParentFolder[0]=nParent;  
  7.     return TRUE;  
  8. }  
  9.   
  10. //---------------------nParentFolder[10]中的有效数据整合(加\)---------------------  
  11. CString AllCString(CString nParentFolder[10])  
  12. {  
  13.     CString nAllCString=L"";  
  14.     for(int i=0;i<10;i++)  
  15.     {  
  16.         if(nParentFolder[i]==L""break;  
  17.         nAllCString+=L"\\"+nParentFolder[i];  
  18.     }  
  19.     return nAllCString;  
  20. }  


获得Item节点路径的函数

[cpp]  view plain  copy
  1. CString GetItemPath(CTreeCtrl* pCtrl,HTREEITEM hItem)  
  2. {  
  3.     CString nSelItemName=pCtrl->GetItemText(hItem);  
  4.   
  5.     HTREEITEM parentItem=pCtrl->GetParentItem(hItem);    
  6.   
  7.     if (parentItem==NULL) //hItem即为根目录  
  8.         return nSelItemName;  
  9.   
  10.     //清空OLD  
  11.     for(int i=0;i<10;i++) m_OldParentFolder[i]=L"";  
  12.   
  13.     //m_OldParentFolder 记录上一个节点的父节点    
  14.     for(int i=0;i<10;i++)     
  15.         m_OldParentFolder[i]=m_ParentFolder[i];     
  16.   
  17.     //m_ParentFolder 记录当前节点的父亲节点    
  18.     for(int i=0;i<10;i++)     
  19.         m_ParentFolder[i]=L"";    
  20.   
  21.     CString itemPath;    
  22.     CString parentFolder=nSelItemName;    
  23.   
  24.     //将parentFolder添加到m_ParentFolder[0],其他值依次后移    
  25.     AddParentFolder(m_ParentFolder,parentFolder);    
  26.   
  27.     
  28.   
  29.     // m_PicFolder 为根节点对应的名字    
  30.     while(parentItem!=NULL&&pCtrl->GetItemText(parentItem).Compare(m_PicFolder))    
  31.     {    
  32.         parentFolder=pCtrl->GetItemText(parentItem);    
  33.         AddParentFolder(m_ParentFolder,parentFolder);    
  34.         parentItem=pCtrl->GetParentItem(parentItem);   
  35.   
  36.     }    
  37.   
  38.      itemPath.Format(L"%s%s",m_PicFolder,AllCString(m_ParentFolder));    
  39.   
  40.      //清空OLD  
  41.      for(int i=0;i<10;i++) m_OldParentFolder[i]=L"";  
  42.      //清空     
  43.      for(int i=0;i<10;i++)     
  44.          m_ParentFolder[i]=L"";    
  45.   
  46.      return itemPath;  
  47.   
  48. }  



 获得叶子节点的函数

[cpp]  view plain  copy
  1. void Leaf(CTreeCtrl* pCtrl,HTREEITEM hItem)  
  2. {  
  3.       
  4.     CString itemName=pCtrl->GetItemText(hItem);  
  5.   
  6.     // 叶子节点是jpg文件或tif文件  
  7.     if(nSelItemName.Find(L".jpg")!=-1 || nSelItemName.Find(L".tif")!=-1)  
  8.     {  
  9.   
  10.         //m_OldParentFolder 记录上一个节点的父节点  
  11.         for(int i=0;i<10;i++)   
  12.             m_OldParentFolder[i]=m_ParentFolder[i];   
  13.   
  14.         //m_ParentFolder 记录当前节点的父亲节点  
  15.         for(int i=0;i<10;i++)   
  16.             m_ParentFolder[i]=L"";  
  17.   
  18.         CString imgPath=L"";  
  19.         CString parentFolder=itemName;  
  20.   
  21.         //将parentFolder添加到m_ParentFolder[0],其他值依次后移  
  22.         AddParentFolder(m_ParentFolder,parentFolder);  
  23.   
  24.         HTREEITEM parentItem=pCtrl->GetParentItem(hItem);  
  25.   
  26.         // m_imgPath 为根节点对应的名字  
  27.         while(pCtrl->GetItemText(parentItem).Compare(m_imgPath))  
  28.         {  
  29.             parentFolder=pCtrl->GetItemText(parentItem);  
  30.             AddParentFolder(m_ParentFolder,parentFolder);  
  31.             parentItem=pCtrl->GetParentItem(parentItem)  
  32.   
  33.         }  
  34.   
  35.         // 获得叶子节点的全路径  
  36.         imgPath.Format(L"%s%s",m_imgPath,AllCString(m_ParentFolder));  
  37.   
  38.     }  
  39.   
  40.   
  41.     // 对imgPath 所指的文件进行操作  
  42.     ShowPic(imgPath);  
  43.   
  44.   
  45. }  


上述方法过于繁杂,再来了简洁些的


使用栈,依次将本节点-->根节点入栈     出栈时顺序便为根节点-->本节点


1)叶子节点

[cpp]  view plain  copy
  1. //本地是否存在此文章  
  2. void CMainFrame::PostPath(CTreeCtrl& nTreeCtrl, HTREEITEM hItem,CString &path)  
  3. {  
  4.     stack<HTREEITEM> itemStack;  
  5.     while (hItem!=nTreeCtrl.GetRootItem ())  
  6.     {  
  7.         itemStack.push(hItem);  
  8.         hItem=nTreeCtrl.GetParentItem (hItem);  
  9.     }  
  10.     itemStack.push(nTreeCtrl.GetRootItem ());  
  11.     CString itemName;  
  12.     while (!itemStack.empty())  
  13.     {  
  14.         hItem=(HTREEITEM)itemStack.top();  
  15.         itemStack.pop();  
  16.         itemName=nTreeCtrl.GetItemText (hItem);  
  17.         path+=itemName;  
  18.         path+=L"\\";  
  19.     }  
  20.     path.TrimRight(L"\\");  
  21.     path+=L".xml";  
  22. }  

2)目录节点

[cpp]  view plain  copy
  1. void CMainFrame::DirPath(CTreeCtrl& nTreeCtrl, HTREEITEM nRoot,CString &path)  
  2. {  
  3.     stack<HTREEITEM> itemStack;  
  4.     while (hItem!=nTreeCtrl.GetRootItem ())  
  5.     {  
  6.         itemStack.push(hItem);  
  7.         hItem=nTreeCtrl.GetParentItem (hItem);  
  8.     }  
  9.     itemStack.push(nTreeCtrl.GetRootItem ());  
  10.     CString itemName;  
  11.     while (!itemStack.empty())  
  12.     {  
  13.         hItem=(HTREEITEM)itemStack.top();  
  14.         itemStack.pop();  
  15.         itemName=nTreeCtrl.GetItemText (hItem);  
  16.         path+=itemName;  
  17.         path+=L"\\";  
  18.     }  
  19. }  




9  获得树中所有叶子节点的父目录

    即:树中可能有许多枝干,获取这些枝干的路径


[cpp]  view plain  copy
  1. std::vector<CString> m_BookDirectory; //存放所有叶子节点的父目录  

[cpp]  view plain  copy
  1. void GetBookDirectory(CTreeCtrl* pCtrl,HTREEITEM hItem)  
  2. {  
  3.   
  4.     if(pCtrl->ItemHasChildren(hItem))       
  5.     {   
  6.         HTREEITEM   hChildItem = pCtrl->GetChildItem(hItem);       
  7.         while(hChildItem!=NULL)       
  8.         {   
  9.             GetBookDirectory(pCtrl,hChildItem); //递归遍历孩子节点    
  10.   
  11.             if(pCtrl->ItemHasChildren(hChildItem))  
  12.                 hChildItem  = pCtrl->GetNextItem(hChildItem, TVGN_NEXT);  
  13.             else  
  14.                 break;  
  15.         }       
  16.     }  
  17.     else  
  18.     {  
  19.         HTREEITEM parentItem=pCtrl->GetParentItem(hItem);    
  20.         CString bookPath=GetItemPath(pCtrl,parentItem);  
  21.   
  22.         m_BookDirectory.push_back(bookPath);  
  23.   
  24.     }  
  25. }  


[cpp]  view plain  copy
  1. CTreeCtrl& nTreeCtrl=((CImportTreeView*)m_SplitterWnd.GetPane(0,0))->GetTreeCtrl();  
  2. HTREEITEM hItem;  
  3. hItem = nTreeCtrl.GetRootItem();  
  4.   
  5. m_BookDirectory.clear();  
  6. GetBookDirectory(&nTreeCtrl,hItem);  //获得几本书 及书的路径  


10 利用InsertItem、SetItemData 存放与该节点有关的数字信息 

[cpp]  view plain  copy
  1. HTREEITEM InsertItem(  
  2.    LPCTSTR lpszItem,  
  3.    int nImage,        //实测范围0-65535    
  4.    int nSelectedImage,  
  5.    HTREEITEM hParent = TVI_ROOT,  
  6.    HTREEITEM hInsertAfter = TVI_LAST  
  7. );  
  8.    


存放65535以上的大数据时 用SetItemData 
A 32-bit application-specific value 


[cpp]  view plain  copy
  1. BOOL SetItemData(  
  2.    HTREEITEM hItem,  
  3.    DWORD_PTR dwData   
  4. );  
  5.    

一 基础操作 

1 插入节点

1)插入根节点

 

[cpp]  view plain  copy
  1. //插入根节点  
  2. HTREEITEM hRoot;  
  3. CString str=L"ROOT"  
  4. hRoot=nTreeCtrl.InsertItem(str);    
  5.   
  6. //相当于   
  7. hRoot=nTreeCtrl.InsertItem(str,TVI_ROOT,TVI_LAST);  


2)插入孩子节点

 

[cpp]  view plain  copy
  1. //添加hRoot节点的孩子节点,并且被添加的节点位于hRoot所有孩子节点的末尾  
  2. HTREEITEM hChild=nTreeCtrl.InsertItem(str,hRoot);  
  3.   
  4. //相当于  
  5. HTREEITEM hChild=nTreeCtrl.InsertItem(str,hRoot,TVI_LAST);  


 

2 获得节点句柄

[cpp]  view plain  copy
  1. //获得根节点  
  2. HTREEITEM hRootItem;  
  3. hRootItem=nTreeCtrl.GetRootItem();  
  4.   
  5.   
  6. //获得当前节点  
  7. HTREEITEM hCurrentItem;  
  8. hCurrentItem=nTreeCtrl.GetSelectedItem();  
  9.   
  10.   
  11. //获得hItem的前一个节点  
  12.   
  13. HTREEITEM hPreItem;  
  14. hPreItem=nTreeCtrl.GetNextItem(hItem,TVGN_PREVIOUS);  
  15.   
  16.   
  17. //获得hItem的下一个节点  
  18. HTREEITEM hNextItem;  
  19. hNextItem=nTreeCtrl.GetNextItem(hItem,TVGN_NEXT);  


 

3 判断某节点是否有孩子节点

[cpp]  view plain  copy
  1. //判断某节点是否有孩子节点  
  2. if (nTreeCtrl.ItemHasChildren(hRoot))  

 

4 展开或收缩子节点

[cpp]  view plain  copy
  1. //展开  
  2. if(nTreeCtrl.ItemHasChildren(hRoot))  
  3.     nTreeCtrl.Expand(hParentItem,TVE_EXPAND);  


 


5 获得第一个孩子节点的句柄

[cpp]  view plain  copy
  1. //判断某节点是否有孩子节点  
  2. if (nTreeCtrl.ItemHasChildren(hRoot))  
  3. {  
  4.     //获得孩子节点  
  5.     HTREEITEM hChild=nTreeCtrl.GetChildItem(hRoot);  
  6.   
  7. }  


6 遍历hRoot下一层的所有孩子节点

 

[cpp]  view plain  copy
  1. //判断某节点是否有孩子节点  
  2. if (nTreeCtrl.ItemHasChildren(hRoot))  
  3. {  
  4.     //获得孩子节点  
  5.     HTREEITEM hChild=nTreeCtrl.GetChildItem(hRoot);  
  6.   
  7.     //遍历hRoot下一层的所有孩子节点  
  8.     while(hChild)  
  9.     {  
  10.         hChild=nTreeCtrl.GetNextItem(hChild,TVGN_NEXT);  
  11.   
  12.     }  
  13.   
  14. }  


 

7  获得某节点上的文字

[cpp]  view plain  copy
  1. //获得某节点上的文字  
  2. CString str;  
  3. nTreeCtrl.GetItemText(hRoot);  

 

8 选择某节点,并让其获得焦点

   首先,TREE控件的样式必须设置为TVS_SHOWSELALWAYS 

   其次: 选择该节点

[html]  view plain  copy
  1. treeCtrl.SelectItem(hItem);  

  最后,设置焦点

[html]  view plain  copy
  1. treeCtrl.SetFocus();  

Tree控件设置焦点后,会自动将焦点定位到选择的节点上


9  清空树控件

[cpp]  view plain  copy
  1. <strong>  nTreeCtrl.DeleteAllItems();</strong>  


 10  将指定目录下的文件插入节点

 

[cpp]  view plain  copy
  1. void InsertPath(CString path, HTREEITEM hRoot, CTreeCtrl& ctrl)  
  2. {  
  3.     CFileFind nFindFile;  
  4.     CString str=L"";  
  5.     CString nPicFileName=L"";  
  6.     BOOL IsExist=FALSE;  
  7.     HTREEITEM hSubItem;  
  8.   
  9.     nPicFileName.Format(L"%s\\*.*",path);  
  10.     IsExist = nFindFile.FindFile(nPicFileName);  
  11.     while (IsExist)  
  12.     {  
  13.         IsExist = nFindFile.FindNextFile();  
  14.         if(nFindFile.IsDots())  
  15.             continue;  
  16.         nPicFileName = nFindFile.GetFileName();  
  17.   
  18.         //路径  
  19.         if(nFindFile.IsDirectory())  
  20.         {  
  21.             hSubItem = ctrl.InsertItem(nPicFileName,hRoot);  
  22.             InsertPath(nFindFile.GetFilePath(),hSubItem,ctrl);  
  23.         }  
  24.         else  
  25.         {  
  26.             //文件  
  27.             str = nPicFileName.Right(4);  
  28.             if(!str.CompareNoCase(_T(".jpg")) || !str.CompareNoCase(_T(".tif")))  
  29.             {  
  30.                 ctrl.InsertItem(nPicFileName,hRoot);  
  31.             }  
  32.         }  
  33.     }  
  34.     nFindFile.Close();  
  35. }  


 

[cpp]  view plain  copy
  1. void LoadPath(CString path) //path为指定目录   此函数的作用为将path目录下的文件插入树控件中  
  2. {  
  3.     CTreeCtrl& ctrl = GetTreeCtrl();  
  4.     ASSERT(ctrl);   
  5.     ctrl.DeleteAllItems();  
  6.     HTREEITEM hRoot = ctrl.InsertItem(path);  
  7.     InsertPath(path,hRoot,ctrl);  
  8.     ctrl.Expand(hRoot,TVE_EXPAND);  
  9.   
  10. }  


11 将文件列表中的文件插入树控件中

[cpp]  view plain  copy
  1. void InsetAllFile( list<CString>& filePathList){  
  2.   
  3.   
  4.     CTreeCtrl & nTreeCtrl=((CMyTreeView*)(((CMainFrame*)AfxGetMainWnd())->m_SplitterWnd.GetPane(0,0)))->GetTreeCtrl();  
  5.     nTreeCtrl.DeleteAllItems();  
  6.   
  7.     list<CString>::iterator it=filePathList.begin();  
  8.     HTREEITEM hRoot=NULL;  
  9.     CString filePath;  
  10.     CString treeRootName=L"根目录";  //所有的文件都在根目录下  即:默认所有的文件都在同一个目录下  
  11.   
  12.     while(it!=filePathList.end())  
  13.     {  
  14.         filePath=*it;    
  15.           
  16.   
  17.   
  18.         if(hRoot==NULL)  
  19.             hRoot=nTreeCtrl.InsertItem(treeRootName);  //建立根目录  
  20.   
  21.   
  22.   
  23.         if(filePath.Find(treeRootName)==0) // 文件第一层目录与根目录相同,则截去文件第一层目录,文件从第二层目录开始  
  24.             filePath=filePath.Right(filePath.GetLength()-treeRootName.GetLength()-1);  
  25.   
  26.   
  27.         LoadPicFiles(nTreeCtrl,filePath, hRoot);  
  28.   
  29.         it++;  
  30.     }  
  31.   
  32. }  


[cpp]  view plain  copy
  1. void LoadPicFiles(CTreeCtrl& nTreeCtrl, CString nFilePath, HTREEITEM nRoot)  
  2. {  
  3.   
  4. // 判断nPicFolder是目录还是文件  
  5. // 如果是文件  
  6. //     直接将文件插入到树控件中 nTreeCtrl.InsertItem(nPicFolder,nRoot);  
  7. // 如果是目录  
  8. //     获取nPicFolder的第一层目录  
  9. //     判断nRoot目录下是否已经有此层目录  
  10. //     如果有此层目录  
  11. //         递归插入其他  
  12. //     如果无此层目录  
  13. //         插入此层目录,然后递归插入其他  
  14.   
  15.   
  16.     CString nSubFolder;     //首层目录  
  17.     CString nSubFilePath;   //去掉首层目录后的文件名  
  18.     BOOL IsExist=FALSE;  
  19.   
  20.       
  21.   
  22.     int nIndex=-1;  
  23.     nIndex=nFilePath.Find(L'\\');  
  24.   
  25.     if(nIndex>=0) //目录  
  26.     {  
  27.         nSubFolder=nFilePath.Left(nIndex);  
  28.         nSubFilePath=nFilePath.Right(nFilePath.GetLength()-nIndex-1);  
  29.   
  30.         HTREEITEM nSubRoot=NULL;  
  31.         if(nTreeCtrl.ItemHasChildren(nRoot))  
  32.             nSubRoot=nTreeCtrl.GetChildItem(nRoot);  
  33.         CString str;  
  34.         BOOL  bExist=FALSE;  
  35.         while(nSubRoot)  
  36.         {  
  37.             str=nTreeCtrl.GetItemText(nSubRoot);  
  38.   
  39.             if (str.CompareNoCase(nSubFolder)==0)  
  40.             {  
  41.   
  42.                 bExist=TRUE;  
  43.                 break;  
  44.             }  
  45.   
  46.             nSubRoot=nTreeCtrl.GetNextSiblingItem(nSubRoot);  
  47.         }  
  48.   
  49.         if(!bExist)  
  50.         {  
  51.   
  52.             nSubRoot=nTreeCtrl.InsertItem(nSubFolder,nRoot);  
  53.   
  54.             LoadPicFiles(nTreeCtrl,nSubFilePath,nSubRoot);  
  55.         }else{  
  56.             LoadPicFiles(nTreeCtrl,nSubFilePath,nSubRoot);  
  57.         }  
  58.     }  
  59.     else if(nFilePath.Find(L".jpg")!=-1 || nFilePath.Find(L".tif")!=-1)  
  60.     {  
  61.         nTreeCtrl.InsertItem(nFilePath,nRoot);  
  62.     }  
  63. }  



-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

二 扩展操作

 

1 响应TVN_ITEMEXPANDING  消息时   如何获得将要展开或收缩的那一个节点的句柄

MSDN:

 

TVN_ITEMEXPANDING pnmtv = (NM_TREEVIEW FAR *) lParam
pnmtv
Pointer to an  NM_TREEVIEW structure. The itemNew member is a TVITEM structure that contains valid information about the parent item in the hItem, state, and lParam members. The action member indicates whether the list is to expand or collapse. For a list of possible values, see the description of the TVM_EXPAND message.

。。。。。。。。。

[cpp]  view plain  copy
  1. typedef struct _NM_TREEVIEW {   
  2.   NMHDR hdr;   
  3.   UINT action;   
  4.   TV_ITEM itemOld;   
  5.   TV_ITEM itemNew;   
  6.   POINT ptDrag;   
  7. } NM_TREEVIEW;  
  8. typedef NM_TREEVIEW FAR* LPNM_TREEVIEW;  
  9.    

 

[cpp]  view plain  copy
  1. typedef struct _TV_ITEM { tvi  
  2.   UINT mask;   
  3.   HTREEITEM hItem;   
  4.   UINT state;   
  5.   UINT stateMask;   
  6.   LPSTR pszText;   
  7.   int cchTextMax;   
  8.   int iImage;   
  9.   int iSelectedImage;   
  10.   int cChildren;   
  11.   LPARAM lParam; }   
  12. TV_ITEM, FAR* LPTV_ITEM;  
  13.    


在 TV_ITEM 的 hItem中 存放着要展开项的句柄

 

解决:查了这么多,其实很简单 代码如下:

 

[cpp]  view plain  copy
  1. void CLeftView::OnItemexpanding(NMHDR* pNMHDR, LRESULT* pResult)  
  2. {  
  3.     LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);  
  4.     // TODO: 在此添加控件通知处理程序代  
  5.     HTREEITEM htree=pNMTreeView->itemNew.hItem; // 这个就是 将要被扩展或收缩节点的句柄  
  6.   
  7. 。。。  
  8. }  

 

 

2 怎么知道CTreeCtrl的一个节点是展开的还是收缩着的

 解决:

方法1

[cpp]  view plain  copy
  1. <strong>     (GetItemState(hItem,   TVIS_EXPANDED   )&TVIS_EXPANDED)!=TVIS_EXPANDED  //如果相等,则说明改节点是扩展的,如果不相等,则说明该节点是收缩的</strong>  

 

方法2

响应TVN_ITEMEXPANDING事件时:

[cpp]  view plain  copy
  1. void CExampleDlg::OnItemexpandingTree1(NMHDR* pNMHDR, LRESULT* pResult)   
  2.   
  3. {   
  4.   
  5. NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;   
  6.   
  7. if (pNMTreeView->action == TVE_COLLAPSE)   //判断action的值  
  8.   
  9. 。。。  
  10.   
  11. 。。。  
  12.   
  13. }  


 

 

 3  判断节点是否被扩展过

[cpp]  view plain  copy
  1. if ((GetTreeCtrl().GetItemState(hItem,TVIS_EXPANDEDONCE )&TVIS_EXPANDEDONCE )!=0 ) //判断是否扩展过一次,若!=0则说明被扩展过   


 


4   使用 CImageList m_ImageList; 加载位图或图标,并将其与树控件联系在一起,由此便可以设置每个节点的图标

 

[cpp]  view plain  copy
  1.      CImageList m_ImageList;  
  2. m_ImageList.Create(12,12,ILC_COLORDDB | ILC_MASK, 3, 1);  
  3. HICON hAdd=::LoadIcon(::AfxGetInstanceHandle(), (LPCTSTR)IDI_ADD);  
  4. HICON hRemove=::LoadIcon(::AfxGetInstanceHandle(), (LPCTSTR)IDI_REMOVE);  
  5. HICON hLeaf=::LoadIcon(::AfxGetInstanceHandle(), (LPCTSTR)IDI_LEAF);  
  6. m_ImageList.Add(hAdd);  
  7. m_ImageList.Add(hRemove);  
  8. m_ImageList.Add(hLeaf);  
  9. GetTreeCtrl().SetImageList(&m_ImageList,TVSIL_NORMAL);  // 树控件和图像列表相连  
[cpp]  view plain  copy
  1.          m_treeCtrl.SetItemImage(htree,0,0)   // 通过SetItemImage(htree,0,0) 设置节点的图标  


 

 5  什么时候响应OnItemexpanding 消息

 

     当节点第一次被展开时,才响应此消息。也就是说:当以开后该节点再展开或收缩时,便不再响应此消息了。

 

6  设置树控件形式为 TVS_HASBUTTONS|TVS_LINESATROOT 时, 树控件节点前才会出现+ - 号

 


以下为综合例子: 点击按钮上一个 显示该节点的上一个兄弟节点,并更改控件焦点

 

设置控件样式:

[html]  view plain  copy
  1. BOOL CTreePathView::PreCreateWindow(CREATESTRUCT& cs)  
  2. {  
  3.     // TODO: 在此处通过修改  
  4.     //  CREATESTRUCT cs 来修改窗口类或样式  
  5.   
  6.     cs.style|=TVS_HASLINES|TVS_SHOWSELALWAYS;   //若是想用CImageList的图标 ,则不要设置为TVS_HASBUTTONS形式  
  7.   
  8.   
  9.     return CTreeView::PreCreateWindow(cs);  
  10. }  


点击按钮5(焦点移动到上一个兄弟节点)

[html]  view plain  copy
  1. void NewImageView::OnBnClickedButton5() // 上一个图  
  2. {  
  3.     // TODO: 在此添加控件通知处理程序代码  
  4.   
  5.     CTreePathView * pTree=(CTreePathView* )(((CMainFrame *)AfxGetMainWnd())->m_wndSplitter.GetPane(0,0));  
  6.   
  7.     CTreeCtrl & treeCtrl=pTree->GetTreeCtrl();  
  8.   
  9.     HTREEITEM hItem=treeCtrl.GetSelectedItem();  
  10.     if (hItem!=NULL)  
  11.     {  
  12.         hItem=treeCtrl.GetNextItem(hItem,TVGN_PREVIOUS);  
  13.   
  14.         if (hItem!=NULL)  
  15.         {  
  16.             CString str;  
  17.             str=pTree->GetFullPath(hItem);  
  18.             SetImage(str);  
  19.             treeCtrl.SelectItem(hItem);  
  20.             treeCtrl.SetFocus();  
  21.             InvalidateRect(m_ClientRect);  
  22.         }  
  23.     }  
  24. }  


 

点击按钮6(焦点移动到下一个兄弟节点)

 

[html]  view plain  copy
  1. void NewImageView::OnBnClickedButton6() //下一个  
  2. {  
  3.     // TODO: 在此添加控件通知处理程序代码  
  4.   
  5.     CTreePathView * pTree=(CTreePathView* )(((CMainFrame *)AfxGetMainWnd())->m_wndSplitter.GetPane(0,0));  
  6.     CTreeCtrl & treeCtrl=pTree->GetTreeCtrl();  
  7.     HTREEITEM hItem=treeCtrl.GetSelectedItem();  
  8.   
  9.     if (hItem!=NULL)  
  10.     {  
  11.         hItem=treeCtrl.GetNextItem(hItem,TVGN_NEXT);  
  12.   
  13.         if (hItem!=NULL)  
  14.         {  
  15.             CString str;  
  16.             str=pTree->GetFullPath(hItem);  
  17.             SetImage(str);  
  18.   
  19.             treeCtrl.SelectItem(hItem);  
  20.             treeCtrl.SetFocus();  
  21.             InvalidateRect(m_ClientRect);  
  22.         }  
  23.     }  
  24. }  


 

7  遍历树控件的所有节点

 

1) 获得根节点句柄

[cpp]  view plain  copy
  1. CTreeCtrl& nTreeCtrl=((CImportTreeView*)m_SplitterWnd.GetPane(0,0))->GetTreeCtrl();  
  2.   
  3. HTREEITEM hItem;  
  4. //获得根目录节点  
  5. hItem = nTreeCtrl.GetRootItem();  
  6. //遍历树控件节点  
  7. TreeVisit(&nTreeCtrl,hItem);  

 

2)遍历所有节点

[cpp]  view plain  copy
  1. void TreeVisit(CTreeCtrl* pCtrl,HTREEITEM hItem)   
  2. {      
  3.     if(pCtrl->ItemHasChildren(hItem))       
  4.     {   
  5.         HTREEITEM   hChildItem = pCtrl->GetChildItem(hItem);       
  6.         while(hChildItem!=NULL)       
  7.         {   
  8.             TreeVisit(pCtrl,hChildItem); //递归遍历孩子节点       
  9.             hChildItem  = pCtrl->GetNextItem(hChildItem, TVGN_NEXT);       
  10.         }       
  11.     }  
  12.     else // 对叶子节点进行操作  
  13.         Leaf(pCtrl,hItem);  
  14. }  



8 获得某Item节点的全路径

   

[cpp]  view plain  copy
  1. CString m_ParentFolder[10];  
  2. CString m_OldParentFolder[10];  


 

[cpp]  view plain  copy
  1. //--------------------将nParent添加到nParentFolder[10]第一位----------------------  
  2. BOOL AddParentFolder(CString nParentFolder[10], CString nParent)  
  3. {  
  4.     for(int i=9;i>0;i--)  
  5.         nParentFolder[i]=nParentFolder[i-1];  
  6.     nParentFolder[0]=nParent;  
  7.     return TRUE;  
  8. }  
  9.   
  10. //---------------------nParentFolder[10]中的有效数据整合(加\)---------------------  
  11. CString AllCString(CString nParentFolder[10])  
  12. {  
  13.     CString nAllCString=L"";  
  14.     for(int i=0;i<10;i++)  
  15.     {  
  16.         if(nParentFolder[i]==L""break;  
  17.         nAllCString+=L"\\"+nParentFolder[i];  
  18.     }  
  19.     return nAllCString;  
  20. }  


获得Item节点路径的函数

[cpp]  view plain  copy
  1. CString GetItemPath(CTreeCtrl* pCtrl,HTREEITEM hItem)  
  2. {  
  3.     CString nSelItemName=pCtrl->GetItemText(hItem);  
  4.   
  5.     HTREEITEM parentItem=pCtrl->GetParentItem(hItem);    
  6.   
  7.     if (parentItem==NULL) //hItem即为根目录  
  8.         return nSelItemName;  
  9.   
  10.     //清空OLD  
  11.     for(int i=0;i<10;i++) m_OldParentFolder[i]=L"";  
  12.   
  13.     //m_OldParentFolder 记录上一个节点的父节点    
  14.     for(int i=0;i<10;i++)     
  15.         m_OldParentFolder[i]=m_ParentFolder[i];     
  16.   
  17.     //m_ParentFolder 记录当前节点的父亲节点    
  18.     for(int i=0;i<10;i++)     
  19.         m_ParentFolder[i]=L"";    
  20.   
  21.     CString itemPath;    
  22.     CString parentFolder=nSelItemName;    
  23.   
  24.     //将parentFolder添加到m_ParentFolder[0],其他值依次后移    
  25.     AddParentFolder(m_ParentFolder,parentFolder);    
  26.   
  27.     
  28.   
  29.     // m_PicFolder 为根节点对应的名字    
  30.     while(parentItem!=NULL&&pCtrl->GetItemText(parentItem).Compare(m_PicFolder))    
  31.     {    
  32.         parentFolder=pCtrl->GetItemText(parentItem);    
  33.         AddParentFolder(m_ParentFolder,parentFolder);    
  34.         parentItem=pCtrl->GetParentItem(parentItem);   
  35.   
  36.     }    
  37.   
  38.      itemPath.Format(L"%s%s",m_PicFolder,AllCString(m_ParentFolder));    
  39.   
  40.      //清空OLD  
  41.      for(int i=0;i<10;i++) m_OldParentFolder[i]=L"";  
  42.      //清空     
  43.      for(int i=0;i<10;i++)     
  44.          m_ParentFolder[i]=L"";    
  45.   
  46.      return itemPath;  
  47.   
  48. }  



 获得叶子节点的函数

[cpp]  view plain  copy
  1. void Leaf(CTreeCtrl* pCtrl,HTREEITEM hItem)  
  2. {  
  3.       
  4.     CString itemName=pCtrl->GetItemText(hItem);  
  5.   
  6.     // 叶子节点是jpg文件或tif文件  
  7.     if(nSelItemName.Find(L".jpg")!=-1 || nSelItemName.Find(L".tif")!=-1)  
  8.     {  
  9.   
  10.         //m_OldParentFolder 记录上一个节点的父节点  
  11.         for(int i=0;i<10;i++)   
  12.             m_OldParentFolder[i]=m_ParentFolder[i];   
  13.   
  14.         //m_ParentFolder 记录当前节点的父亲节点  
  15.         for(int i=0;i<10;i++)   
  16.             m_ParentFolder[i]=L"";  
  17.   
  18.         CString imgPath=L"";  
  19.         CString parentFolder=itemName;  
  20.   
  21.         //将parentFolder添加到m_ParentFolder[0],其他值依次后移  
  22.         AddParentFolder(m_ParentFolder,parentFolder);  
  23.   
  24.         HTREEITEM parentItem=pCtrl->GetParentItem(hItem);  
  25.   
  26.         // m_imgPath 为根节点对应的名字  
  27.         while(pCtrl->GetItemText(parentItem).Compare(m_imgPath))  
  28.         {  
  29.             parentFolder=pCtrl->GetItemText(parentItem);  
  30.             AddParentFolder(m_ParentFolder,parentFolder);  
  31.             parentItem=pCtrl->GetParentItem(parentItem)  
  32.   
  33.         }  
  34.   
  35.         // 获得叶子节点的全路径  
  36.         imgPath.Format(L"%s%s",m_imgPath,AllCString(m_ParentFolder));  
  37.   
  38.     }  
  39.   
  40.   
  41.     // 对imgPath 所指的文件进行操作  
  42.     ShowPic(imgPath);  
  43.   
  44.   
  45. }  


上述方法过于繁杂,再来了简洁些的


使用栈,依次将本节点-->根节点入栈     出栈时顺序便为根节点-->本节点


1)叶子节点

[cpp]  view plain  copy
  1. //本地是否存在此文章  
  2. void CMainFrame::PostPath(CTreeCtrl& nTreeCtrl, HTREEITEM hItem,CString &path)  
  3. {  
  4.     stack<HTREEITEM> itemStack;  
  5.     while (hItem!=nTreeCtrl.GetRootItem ())  
  6.     {  
  7.         itemStack.push(hItem);  
  8.         hItem=nTreeCtrl.GetParentItem (hItem);  
  9.     }  
  10.     itemStack.push(nTreeCtrl.GetRootItem ());  
  11.     CString itemName;  
  12.     while (!itemStack.empty())  
  13.     {  
  14.         hItem=(HTREEITEM)itemStack.top();  
  15.         itemStack.pop();  
  16.         itemName=nTreeCtrl.GetItemText (hItem);  
  17.         path+=itemName;  
  18.         path+=L"\\";  
  19.     }  
  20.     path.TrimRight(L"\\");  
  21.     path+=L".xml";  
  22. }  

2)目录节点

[cpp]  view plain  copy
  1. void CMainFrame::DirPath(CTreeCtrl& nTreeCtrl, HTREEITEM nRoot,CString &path)  
  2. {  
  3.     stack<HTREEITEM> itemStack;  
  4.     while (hItem!=nTreeCtrl.GetRootItem ())  
  5.     {  
  6.         itemStack.push(hItem);  
  7.         hItem=nTreeCtrl.GetParentItem (hItem);  
  8.     }  
  9.     itemStack.push(nTreeCtrl.GetRootItem ());  
  10.     CString itemName;  
  11.     while (!itemStack.empty())  
  12.     {  
  13.         hItem=(HTREEITEM)itemStack.top();  
  14.         itemStack.pop();  
  15.         itemName=nTreeCtrl.GetItemText (hItem);  
  16.         path+=itemName;  
  17.         path+=L"\\";  
  18.     }  
  19. }  




9  获得树中所有叶子节点的父目录

    即:树中可能有许多枝干,获取这些枝干的路径


[cpp]  view plain  copy
  1. std::vector<CString> m_BookDirectory; //存放所有叶子节点的父目录  

[cpp]  view plain  copy
  1. void GetBookDirectory(CTreeCtrl* pCtrl,HTREEITEM hItem)  
  2. {  
  3.   
  4.     if(pCtrl->ItemHasChildren(hItem))       
  5.     {   
  6.         HTREEITEM   hChildItem = pCtrl->GetChildItem(hItem);       
  7.         while(hChildItem!=NULL)       
  8.         {   
  9.             GetBookDirectory(pCtrl,hChildItem); //递归遍历孩子节点    
  10.   
  11.             if(pCtrl->ItemHasChildren(hChildItem))  
  12.                 hChildItem  = pCtrl->GetNextItem(hChildItem, TVGN_NEXT);  
  13.             else  
  14.                 break;  
  15.         }       
  16.     }  
  17.     else  
  18.     {  
  19.         HTREEITEM parentItem=pCtrl->GetParentItem(hItem);    
  20.         CString bookPath=GetItemPath(pCtrl,parentItem);  
  21.   
  22.         m_BookDirectory.push_back(bookPath);  
  23.   
  24.     }  
  25. }  


[cpp]  view plain  copy
  1. CTreeCtrl& nTreeCtrl=((CImportTreeView*)m_SplitterWnd.GetPane(0,0))->GetTreeCtrl();  
  2. HTREEITEM hItem;  
  3. hItem = nTreeCtrl.GetRootItem();  
  4.   
  5. m_BookDirectory.clear();  
  6. GetBookDirectory(&nTreeCtrl,hItem);  //获得几本书 及书的路径  


10 利用InsertItem、SetItemData 存放与该节点有关的数字信息 

[cpp]  view plain  copy
  1. HTREEITEM InsertItem(  
  2.    LPCTSTR lpszItem,  
  3.    int nImage,        //实测范围0-65535    
  4.    int nSelectedImage,  
  5.    HTREEITEM hParent = TVI_ROOT,  
  6.    HTREEITEM hInsertAfter = TVI_LAST  
  7. );  
  8.    


存放65535以上的大数据时 用SetItemData 
A 32-bit application-specific value 


[cpp]  view plain  copy
  1. BOOL SetItemData(  
  2.    HTREEITEM hItem,  
  3.    DWORD_PTR dwData   
  4. );  
  5.    
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值