生活随笔
收集整理的這篇文章主要介紹了
VC树控件的简单使用
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
//頭文件聲明
?? ?CTreeCtrl m_VersionTree;
?? //在OnInitDialog()添加
??? CRect rc;
??? GetClientRect(&rc);
?? ?bool b=m_VersionTree.Create(TVS_LINESATROOT|TVS_HASLINES|TVS_HASBUTTONS|TVS_SHOWSELALWAYS,rc,this,10001);
?? ?m_VersionTree.ShowWindow(SW_SHOW);
?? ?HTREEITEM hItem,hSubItem;
?? ?hItem = test.InsertItem("Parent1",TVI_ROOT);//在根結(jié)點上添加Parent1
?? ?hSubItem = test.InsertItem("Child1_1",hItem);//在Parent1上添加一個子結(jié)點
?? ?hSubItem = test.InsertItem("Child1_2",hItem,hSubItem);//在Parent1上添加一個子結(jié)點,排在Child1_1后面
?? ?hSubItem = test.InsertItem("Child1_3",hItem,hSubItem);
?? ?hItem = test.InsertItem("Parent2",TVI_ROOT,hItem);? ?
?? ?hItem = test.InsertItem("Parent3",TVI_ROOT,hItem);
===============================================================================================
CTreeCtrl 控件使用總結(jié)
分類: MFC 2011-07-27 17:36 6390人閱讀 收藏 舉報
imagelist擴展nullstructurestructaction
一 基礎(chǔ)操作?
1 插入節(jié)點
1)插入根節(jié)點
?
[cpp] view plaincopy
?? HTREEITEM?hRoot;?? CString?str=L"ROOT" ?? hRoot=nTreeCtrl.InsertItem(str);???? ?? ?? hRoot=nTreeCtrl.InsertItem(str,TVI_ROOT,TVI_LAST);??
2)插入孩子節(jié)點
?
[cpp] view plaincopy
?? HTREEITEM?hChild=nTreeCtrl.InsertItem(str,hRoot);?? ?? ?? HTREEITEM?hChild=nTreeCtrl.InsertItem(str,hRoot,TVI_LAST);??
?
2?獲得節(jié)點句柄
[cpp] view plaincopy
?? HTREEITEM?hRootItem;?? hRootItem=nTreeCtrl.GetRootItem();?? ?? ?? ?? HTREEITEM?hCurrentItem;?? hCurrentItem=nTreeCtrl.GetSelectedItem();?? ?? ?? ?? ?? HTREEITEM?hPreItem;?? hPreItem=nTreeCtrl.GetNextItem(hItem,TVGN_PREVIOUS);?? ?? ?? ?? HTREEITEM?hNextItem;?? hNextItem=nTreeCtrl.GetNextItem(hItem,TVGN_NEXT);??
?
3?判斷某節(jié)點是否有孩子節(jié)點
[cpp] view plaincopy
?? if ?(nTreeCtrl.ItemHasChildren(hRoot))??
?
4 展開或收縮子節(jié)點
[cpp] view plaincopy
?? if (nTreeCtrl.ItemHasChildren(hRoot))??????nTreeCtrl.Expand(hParentItem,TVE_EXPAND);??
?
5?獲得第一個孩子節(jié)點的句柄
[cpp] view plaincopy
?? if ?(nTreeCtrl.ItemHasChildren(hRoot))??{?? ?????? ????HTREEITEM?hChild=nTreeCtrl.GetChildItem(hRoot);?? ?? }??
6 遍歷hRoot下一層的所有孩子節(jié)點
?
[cpp] view plaincopy
?? if ?(nTreeCtrl.ItemHasChildren(hRoot))??{?? ?????? ????HTREEITEM?hChild=nTreeCtrl.GetChildItem(hRoot);?? ?? ?????? ????while (hChild)?? ????{?? ????????hChild=nTreeCtrl.GetNextItem(hChild,TVGN_NEXT);?? ?? ????}?? ?? }??
?
7 ?獲得某節(jié)點上的文字
[cpp] view plaincopy
?? CString?str;?? nTreeCtrl.GetItemText(hRoot);??
?
8?選擇某節(jié)點,并讓其獲得焦點
?? 首先,TREE控件的樣式必須設(shè)置為TVS_SHOWSELALWAYS?
?? 其次: 選擇該節(jié)點
[html] view plaincopy
treeCtrl.SelectItem(hItem);??
? 最后,設(shè)置焦點
[html] view plaincopy
treeCtrl.SetFocus();??
Tree控件設(shè)置焦點后,會自動將焦點定位到選擇的節(jié)點上
9??清空樹控件
[cpp] view plaincopy
<strong>????nTreeCtrl.DeleteAllItems();</strong>??
?10? 將指定目錄下的文件插入節(jié)點
?
[cpp] view plaincopy
void ?InsertPath(CString?path,?HTREEITEM?hRoot,?CTreeCtrl&?ctrl)??{?? ????CFileFind?nFindFile;?? ????CString?str=L"" ;?? ????CString?nPicFileName=L"" ;?? ????BOOL ?IsExist=FALSE;?? ????HTREEITEM?hSubItem;?? ?? ????nPicFileName.Format(L"%s\\*.*" ,path);?? ????IsExist?=?nFindFile.FindFile(nPicFileName);?? ????while ?(IsExist)?? ????{?? ????????IsExist?=?nFindFile.FindNextFile();?? ????????if (nFindFile.IsDots())?? ????????????continue ;?? ????????nPicFileName?=?nFindFile.GetFileName();?? ?? ?????????? ????????if (nFindFile.IsDirectory())?? ????????{?? ????????????hSubItem?=?ctrl.InsertItem(nPicFileName,hRoot);?? ????????????InsertPath(nFindFile.GetFilePath(),hSubItem,ctrl);?? ????????}?? ????????else ?? ????????{?? ?????????????? ????????????str?=?nPicFileName.Right(4);?? ????????????if (!str.CompareNoCase(_T(".jpg" ))?||?!str.CompareNoCase(_T(".tif" )))?? ????????????{?? ????????????????ctrl.InsertItem(nPicFileName,hRoot);?? ????????????}?? ????????}?? ????}?? ????nFindFile.Close();?? }??
?
[cpp] view plaincopy
void ?LoadPath(CString?path)???{?? ????CTreeCtrl&?ctrl?=?GetTreeCtrl();?? ????ASSERT(ctrl);??? ????ctrl.DeleteAllItems();?? ????HTREEITEM?hRoot?=?ctrl.InsertItem(path);?? ????InsertPath(path,hRoot,ctrl);?? ????ctrl.Expand(hRoot,TVE_EXPAND);?? ?? }??
11 將文件列表中的文件插入樹控件中
[cpp] view plaincopy
void ?InsetAllFile(?list<CString>&?filePathList){???? ?? ????CTreeCtrl?&?nTreeCtrl=((CMyTreeView*)(((CMainFrame*)AfxGetMainWnd())->m_SplitterWnd.GetPane(0,0)))->GetTreeCtrl();?? ????nTreeCtrl.DeleteAllItems();?? ?? ????list<CString>::iterator?it=filePathList.begin();?? ????HTREEITEM?hRoot=NULL;?? ????CString?filePath;?? ????CString?treeRootName=L"根目錄" ;???? ?? ????while (it!=filePathList.end())?? ????{?? ????????filePath=*it;???? ?????????? ?? ?? ????????if (hRoot==NULL)?? ????????????hRoot=nTreeCtrl.InsertItem(treeRootName);???? ?? ?? ?? ????????if (filePath.Find(treeRootName)==0)??? ????????????filePath=filePath.Right(filePath.GetLength()-treeRootName.GetLength()-1);?? ?? ?? ????????LoadPicFiles(nTreeCtrl,filePath,?hRoot);?? ?? ????????it++;?? ????}?? ?? }??
[cpp] view plaincopy
void ?LoadPicFiles(CTreeCtrl&?nTreeCtrl,?CString?nFilePath,?HTREEITEM?nRoot)??{?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ????CString?nSubFolder;??????? ????CString?nSubFilePath;????? ????BOOL ?IsExist=FALSE;?? ?? ?????? ?? ????int ?nIndex=-1;?? ????nIndex=nFilePath.Find(L'\\' );?? ?? ????if (nIndex>=0)??? ????{?? ????????nSubFolder=nFilePath.Left(nIndex);?? ????????nSubFilePath=nFilePath.Right(nFilePath.GetLength()-nIndex-1);?? ?? ????????HTREEITEM?nSubRoot=NULL;?? ????????if (nTreeCtrl.ItemHasChildren(nRoot))?? ????????????nSubRoot=nTreeCtrl.GetChildItem(nRoot);?? ????????CString?str;?? ????????BOOL ??bExist=FALSE;?? ????????while (nSubRoot)?? ????????{?? ????????????str=nTreeCtrl.GetItemText(nSubRoot);?? ?? ????????????if ?(str.CompareNoCase(nSubFolder)==0)?? ????????????{?? ?? ????????????????bExist=TRUE;?? ????????????????break ;?? ????????????}?? ?? ????????????nSubRoot=nTreeCtrl.GetNextSiblingItem(nSubRoot);?? ????????}?? ?? ????????if (!bExist)?? ????????{?? ?? ????????????nSubRoot=nTreeCtrl.InsertItem(nSubFolder,nRoot);?? ?? ????????????LoadPicFiles(nTreeCtrl,nSubFilePath,nSubRoot);?? ????????}else {?? ????????????LoadPicFiles(nTreeCtrl,nSubFilePath,nSubRoot);?? ????????}?? ????}?? ????else ?if (nFilePath.Find(L".jpg" )!=-1?||?nFilePath.Find(L".tif" )!=-1)?? ????{?? ????????nTreeCtrl.InsertItem(nFilePath,nRoot);?? ????}?? }??
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
二 擴展操作
?
1 響應(yīng)TVN_ITEMEXPANDING? 消息時?? 如何獲得將要展開或收縮的那一個節(jié)點的句柄
MSDN:
?
<strong>TVN_ITEMEXPANDING</strong> <em><a target=_blank class="synParam" href="http://blog.csdn.net/shuilan0066/article/details/6638504">pnmtv</a></em> <strong>= (NM_TREEVIEW FAR *)</strong> <em>lParam</em>
pnmtv
Pointer to an NM_TREEVIEW structure. The itemNew member is aTVITEM structure that contains valid information about the parent item in thehItem ,state , andlParam members. Theaction member indicates whether the list is to expand or collapse. For a list of possible values, see the description of theTVM_EXPAND message.
。。。。。。。。。
[cpp] view plaincopy
typedef ?struct ?_NM_TREEVIEW?{?????NMHDR?hdr;??? ??UINT ?action;??? ??TV_ITEM?itemOld;??? ??TV_ITEM?itemNew;??? ??POINT?ptDrag;??? }?NM_TREEVIEW;?? typedef ?NM_TREEVIEW?FAR*?LPNM_TREEVIEW;?????
?
[cpp] view plaincopy
typedef ?struct ?_TV_ITEM?{?tvi????UINT ?mask;??? ??HTREEITEM?hItem;??? ??UINT ?state;??? ??UINT ?stateMask;??? ??LPSTR ?pszText;??? ??int ?cchTextMax;??? ??int ?iImage;??? ??int ?iSelectedImage;??? ??int ?cChildren;??? ??LPARAM ?lParam;?}??? TV_ITEM,?FAR*?LPTV_ITEM;?? ???
在 TV_ITEM 的 hItem中 存放著要展開項的句柄
?
解決:查了這么多,其實很簡單 代碼如下:
?
[cpp] view plaincopy
void ?CLeftView::OnItemexpanding(NMHDR*?pNMHDR,?LRESULT *?pResult)??{?? ????LPNMTREEVIEW?pNMTreeView?=?reinterpret_cast <LPNMTREEVIEW>(pNMHDR);?? ?????? ????HTREEITEM?htree=pNMTreeView->itemNew.hItem;??? ?? 。。。?? }??
?
?
2 怎么知道CTreeCtrl的一個節(jié)點是展開的還是收縮著的
?解決:
方法1
[cpp] view plaincopy
<strong>?????(GetItemState(hItem,???TVIS_EXPANDED???)&TVIS_EXPANDED)!=TVIS_EXPANDED????
?
方法2
響應(yīng) TVN_ITEMEXPANDING事件時:
[cpp] view plaincopy
void ?CExampleDlg::OnItemexpandingTree1(NMHDR*?pNMHDR,?LRESULT *?pResult)????? {??? ?? NM_TREEVIEW*?pNMTreeView?=?(NM_TREEVIEW*)pNMHDR;??? ?? if ?(pNMTreeView->action?==?TVE_COLLAPSE)??????? 。。。?? ?? 。。。?? ?? }??
?
?
?3? 判斷節(jié)點是否被擴展過
[cpp] view plaincopy
if ?((GetTreeCtrl().GetItemState(hItem,TVIS_EXPANDEDONCE?)&TVIS_EXPANDEDONCE?)!=0?)???
?
4?? 使用 CImageList m_ImageList; 加載位圖或圖標,并將其與樹控件聯(lián)系在一起,由此便可以設(shè)置每個節(jié)點的圖標
?
[cpp] view plaincopy
?????CImageList?m_ImageList;?? m_ImageList.Create(12,12,ILC_COLORDDB?|?ILC_MASK,?3,?1);?? HICON ?hAdd=::LoadIcon(::AfxGetInstanceHandle(),?(LPCTSTR )IDI_ADD);??HICON ?hRemove=::LoadIcon(::AfxGetInstanceHandle(),?(LPCTSTR )IDI_REMOVE);??HICON ?hLeaf=::LoadIcon(::AfxGetInstanceHandle(),?(LPCTSTR )IDI_LEAF);??m_ImageList.Add(hAdd);?? m_ImageList.Add(hRemove);?? m_ImageList.Add(hLeaf);?? GetTreeCtrl().SetImageList(&m_ImageList,TVSIL_NORMAL);????
[cpp] view plaincopy
?????????m_treeCtrl.SetItemImage(htree,0,0)?????
?
?5? 什么時候響應(yīng)OnItemexpanding 消息
?
? ??? 當節(jié)點第一次被展開時,才響應(yīng)此消息。也就是說:當以開后該節(jié)點再展開或收縮時,便不再響應(yīng)此消息了。
?
6? 設(shè)置樹控件形式為 TVS_HASBUTTONS|TVS_LINESATROOT 時, 樹控件節(jié)點前才會出現(xiàn)+ - 號
?
以下為綜合例子: 點擊按鈕上一個 顯示該節(jié)點的上一個兄弟節(jié)點,并更改控件焦點
?
設(shè)置控件樣式:
[html] view plaincopy
BOOL?CTreePathView::PreCreateWindow(CREATESTRUCT&?cs)?? {?? ????//?TODO:?在此處通過修改?? ????//??CREATESTRUCT?cs?來修改窗口類或樣式?? ?? ????cs.style|=TVS_HASLINES|TVS_SHOWSELALWAYS;???//若是想用CImageList的圖標?,則不要設(shè)置為TVS_HASBUTTONS形式?? ?? ?? ????return?CTreeView::PreCreateWindow(cs);?? }??
點擊按鈕5(焦點移動到上一個兄弟節(jié)點)
[html] view plaincopy
void?NewImageView::OnBnClickedButton5()?//?上一個圖?? {?? ????//?TODO:?在此添加控件通知處理程序代碼?? ?? ????CTreePathView?*?pTree =(CTreePathView*?)(((CMainFrame?*)AfxGetMainWnd())-> m_wndSplitter.GetPane(0,0));?? ?? ????CTreeCtrl?&?treeCtrl =pTree -> GetTreeCtrl();?? ?? ????HTREEITEM?hItem =treeCtrl .GetSelectedItem();?? ????if?(hItem!=NULL)?? ????{?? ????????hItem =treeCtrl .GetNextItem(hItem,TVGN_PREVIOUS);?? ?? ????????if?(hItem!=NULL)?? ????????{?? ????????????CString?str;?? ????????????str =pTree -> GetFullPath(hItem);?? ????????????SetImage(str);?? ????????????treeCtrl.SelectItem(hItem);?? ????????????treeCtrl.SetFocus();?? ????????????InvalidateRect(m_ClientRect);?? ????????}?? ????}?? }??
?
點擊按鈕6(焦點移動到下一個兄弟節(jié)點)
?
[html] view plaincopy
void?NewImageView::OnBnClickedButton6()?//下一個?? {?? ????//?TODO:?在此添加控件通知處理程序代碼?? ?? ????CTreePathView?*?pTree =(CTreePathView*?)(((CMainFrame?*)AfxGetMainWnd())-> m_wndSplitter.GetPane(0,0));?? ????CTreeCtrl?&?treeCtrl =pTree -> GetTreeCtrl();?? ????HTREEITEM?hItem =treeCtrl .GetSelectedItem();?? ?? ????if?(hItem!=NULL)?? ????{?? ????????hItem =treeCtrl .GetNextItem(hItem,TVGN_NEXT);?? ?? ????????if?(hItem!=NULL)?? ????????{?? ????????????CString?str;?? ????????????str =pTree -> GetFullPath(hItem);?? ????????????SetImage(str);?? ?? ????????????treeCtrl.SelectItem(hItem);?? ????????????treeCtrl.SetFocus();?? ????????????InvalidateRect(m_ClientRect);?? ????????}?? ????}?? }??
?
7 ?遍歷樹控件的所有節(jié)點
?
1) 獲得根節(jié)點句柄
[cpp] view plaincopy
CTreeCtrl&?nTreeCtrl=((CImportTreeView*)m_SplitterWnd.GetPane(0,0))->GetTreeCtrl();?? ?? HTREEITEM?hItem;?? ?? hItem?=?nTreeCtrl.GetRootItem();?? ?? TreeVisit(&nTreeCtrl,hItem);??
?
2)遍歷所有節(jié)點
[cpp] view plaincopy
void ?TreeVisit(CTreeCtrl*?pCtrl,HTREEITEM?hItem)???{?????? ????if (pCtrl->ItemHasChildren(hItem))??????? ????{??? ????????HTREEITEM???hChildItem?=?pCtrl->GetChildItem(hItem);??????? ????????while (hChildItem!=NULL)??????? ????????{??? ????????????TreeVisit(pCtrl,hChildItem);??? ????????????hChildItem??=?pCtrl->GetNextItem(hChildItem,?TVGN_NEXT);??????? ????????}??????? ????}?? ????else ??? ????????Leaf(pCtrl,hItem);?? }??
8 獲得某Item節(jié)點的全路徑
??
[cpp] view plaincopy
CString?m_ParentFolder[10];?? CString?m_OldParentFolder[10];??
?
[cpp] view plaincopy
?? BOOL ?AddParentFolder(CString?nParentFolder[10],?CString?nParent)??{?? ????for (int ?i=9;i>0;i--)?? ????????nParentFolder[i]=nParentFolder[i-1];?? ????nParentFolder[0]=nParent;?? ????return ?TRUE;?? }?? ?? ?? CString?AllCString(CString?nParentFolder[10])?? {?? ????CString?nAllCString=L"" ;?? ????for (int ?i=0;i<10;i++)?? ????{?? ????????if (nParentFolder[i]==L"" )?break ;?? ????????nAllCString+=L"\\" +nParentFolder[i];?? ????}?? ????return ?nAllCString;?? }??
獲得Item節(jié)點路徑的函數(shù)
[cpp] view plaincopy
CString?GetItemPath(CTreeCtrl*?pCtrl,HTREEITEM?hItem)?? {?? ????CString?nSelItemName=pCtrl->GetItemText(hItem);?? ?? ????HTREEITEM?parentItem=pCtrl->GetParentItem(hItem);???? ?? ????if ?(parentItem==NULL)??? ????????return ?nSelItemName;?? ?? ?????? ????for (int ?i=0;i<10;i++)?m_OldParentFolder[i]=L"" ;?? ?? ?????? ????for (int ?i=0;i<10;i++)????? ????????m_OldParentFolder[i]=m_ParentFolder[i];????? ?? ?????? ????for (int ?i=0;i<10;i++)????? ????????m_ParentFolder[i]=L"" ;???? ?? ????CString?itemPath;???? ????CString?parentFolder=nSelItemName;???? ?? ?????? ????AddParentFolder(m_ParentFolder,parentFolder);???? ?? ???? ?? ?????? ????while (parentItem!=NULL&&pCtrl->GetItemText(parentItem).Compare(m_PicFolder))???? ????{???? ????????parentFolder=pCtrl->GetItemText(parentItem);???? ????????AddParentFolder(m_ParentFolder,parentFolder);???? ????????parentItem=pCtrl->GetParentItem(parentItem);??? ?? ????}???? ?? ?????itemPath.Format(L"%s%s" ,m_PicFolder,AllCString(m_ParentFolder));???? ?? ??????? ?????for (int ?i=0;i<10;i++)?m_OldParentFolder[i]=L"" ;?? ??????? ?????for (int ?i=0;i<10;i++)????? ?????????m_ParentFolder[i]=L"" ;???? ?? ?????return ?itemPath;?? ?? }??
?獲得葉子節(jié)點的函數(shù)
[cpp] view plaincopy
void ?Leaf(CTreeCtrl*?pCtrl,HTREEITEM?hItem)??{?? ?????? ????CString?itemName=pCtrl->GetItemText(hItem);?? ?? ?????? ????if (nSelItemName.Find(L".jpg" )!=-1?||?nSelItemName.Find(L".tif" )!=-1)?? ????{?? ?? ?????????? ????????for (int ?i=0;i<10;i++)??? ????????????m_OldParentFolder[i]=m_ParentFolder[i];??? ?? ?????????? ????????for (int ?i=0;i<10;i++)??? ????????????m_ParentFolder[i]=L"" ;?? ?? ????????CString?imgPath=L"" ;?? ????????CString?parentFolder=itemName;?? ?? ?????????? ????????AddParentFolder(m_ParentFolder,parentFolder);?? ?? ????????HTREEITEM?parentItem=pCtrl->GetParentItem(hItem);?? ?? ?????????? ????????while (pCtrl->GetItemText(parentItem).Compare(m_imgPath))?? ????????{?? ????????????parentFolder=pCtrl->GetItemText(parentItem);?? ????????????AddParentFolder(m_ParentFolder,parentFolder);?? ????????????parentItem=pCtrl->GetParentItem(parentItem)?? ?? ????????}?? ?? ?????????? ????????imgPath.Format(L"%s%s" ,m_imgPath,AllCString(m_ParentFolder));?? ?? ????}?? ?? ?? ?????? ????ShowPic(imgPath);?? ?? ?? }??
9? 獲得樹中所有葉子節(jié)點的父目錄
??? 即:樹中可能有許多枝干,獲取這些枝干的路徑
[cpp] view plaincopy
std::vector<CString>?m_BookDirectory;???
[cpp] view plaincopy
void ?GetBookDirectory(CTreeCtrl*?pCtrl,HTREEITEM?hItem)??{?? ?? ????if (pCtrl->ItemHasChildren(hItem))??????? ????{??? ????????HTREEITEM???hChildItem?=?pCtrl->GetChildItem(hItem);??????? ????????while (hChildItem!=NULL)??????? ????????{??? ????????????GetBookDirectory(pCtrl,hChildItem);??? ?? ????????????if (pCtrl->ItemHasChildren(hChildItem))?? ????????????????hChildItem??=?pCtrl->GetNextItem(hChildItem,?TVGN_NEXT);?? ????????????else ?? ????????????????break ;?? ????????}??????? ????}?? ????else ?? ????{?? ????????HTREEITEM?parentItem=pCtrl->GetParentItem(hItem);???? ????????CString?bookPath=GetItemPath(pCtrl,parentItem);?? ?? ????????m_BookDirectory.push_back(bookPath);?? ?? ????}?? }??
[cpp] view plaincopy
CTreeCtrl&?nTreeCtrl=((CImportTreeView*)m_SplitterWnd.GetPane(0,0))->GetTreeCtrl();?? HTREEITEM?hItem;?? hItem?=?nTreeCtrl.GetRootItem();?? ?? m_BookDirectory.clear();?? GetBookDirectory(&nTreeCtrl,hItem);???
總結(jié)
以上是生活随笔 為你收集整理的VC树控件的简单使用 的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔 推薦給好友。