日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

《实用VC编程之玩转控件》第15课:Tree树形控件

發布時間:2024/3/7 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 《实用VC编程之玩转控件》第15课:Tree树形控件 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文轉載自:VC驛站

https://www.cctry.com/thread-297465-1-1.html

1、控件簡介:
Tree樹形控件也是我們編程過程中比較常用的一個控件,而且在其他軟件中也經常能看到,比如Windows系統中的資源管理器:
?

所以,接下來我就教大家如何來使用這個控件!

2、控件的使用:
a、拖拽Tree樹形控件到對話框模版上;
b、一些常用的屬性:
Check Boxes:結點前是否帶有復選框;
Edit Labels:結點名字是否可編輯;
Has Buttons:父節點是否有+號可供展開;
Has Lines:父子結點之間是否有連接線;
Lines At Root:是否從根節點開始就帶有虛線;
等等吧,大家可以根據自己的需要設置相關的屬性。

c、為Tree樹形控件綁定一個 CTreeCtrl 控件類型變量m_Tree;

3、控件的操作:
在樹形控件中每一個結點都有一個句柄(HTREEITEM),同時插入結點時必須提供父結點句柄,(其中根Root結點只有一個,既不可以添加也不可以刪除)利用
HTREEITEM InsertItem( LPCTSTR lpszItem, HTREEITEM hParent = TVI_ROOT, HTREEITEM hInsertAfter = TVI_LAST );
可以插入一個結點,pszItem為顯示的字符,hParent代表父結點的句柄,當前添加的結點會排在hInsertAfter表示的結點的后面,返回值為當前創建的結點的句柄。

a、添加結點(有多種重載方式,先介紹第一種):

????HTREEITEM hRoot = m_Tree.InsertItem(_T("父1"));
????HTREEITEM hSub1 = m_Tree.InsertItem(_T("子1"), hRoot);
????HTREEITEM hSub2 = m_Tree.InsertItem(_T("子2"), hRoot);

????HTREEITEM hSub3 = m_Tree.InsertItem(_T("子子1"), hSub2);

?

就這樣,可以一層一層的向樹形控件中插入節點。

b、獲得節點的文本:m_Tree.GetItemText(hSub3);
c、設置節點的文本:m_Tree.SetItemText(hSub3, _T("abc"));

d、獲得當前選中的節點:HTREEITEM hSelItem = m_Tree.GetSelectedItem();
e、設置當前選中的節點:m_Tree.SelectItem(hTreeItem);
f、默認上面的情況都是針對單選,那么Tree樹形控件支不支持多選呢?答案是:默認不支持
不過可以通過給節點前面加上 CheckBox 復選框來解決!下個知識點舉例講解!
備注:那么不通過CheckBox 能不能實現多選呢?答案也是可以的,不過要寫很多自定義代碼,大家感興趣的話可以看看這幾篇文章,課堂上咱們就不講解了:
http://www.codeguru.com/cpp/cont ... d/article.php/c629/
http://www.codeguru.com/cpp/cont ... d/article.php/c723/
http://www.codeguru.com/cpp/cont ... /article.php/c9219/

g、遍歷子節點:
需要用到的相關函數:

HTREEITEM GetRootItem( ); //得到根結點。
HTREEITEM GetChildItem(HTREEITEM hItem); //得到子結點。
HTREEITEM GetPrevSiblingItem/GetNextSiblingItem(HTREEITEM hItem); //得到指明結點的上/下一個兄弟結點。
HTREEITEM GetParentItem(HTREEITEM hItem); //得到父結點。

?

從根節點開始遍歷所有節點,判斷 CheckBox 是否勾選:
void CMFCTestDlg::EnumTreeItem(HTREEITEM hItem)
{
????if (!hItem) return;

????//先檢測自己是否被勾選
????if (m_Tree.GetCheck(hItem))
????{
????????CString strText = m_Tree.GetItemText(hItem);
????????MessageBox(strText + _T("##勾選了!"));
????}

????//再遍歷所有的子節點
????if (m_Tree.ItemHasChildren(hItem))
????{
????????HTREEITEM hChildItem = m_Tree.GetChildItem(hItem);
????????while (hChildItem)
????????{
????????????EnumTreeItem(hChildItem);
????????????HTREEITEM hNextItem = m_Tree.GetNextItem(hChildItem, TVGN_NEXT);
????????????hChildItem = hNextItem;
????????}
????}
}

void CMFCTestDlg::OnBnClickedBtnTree()
{
????HTREEITEM hRootItem = m_Tree.GetRootItem(); //從根節點開始遍歷
????EnumTreeItem(hRootItem);
}

h、刪除節點、刪除所有節點:

m_Tree.DeleteItem(hSub2); //刪除節點
m_Tree.DeleteAllItems();????//刪除所有節點

i:展開/收起所有節點:

void CMFCTestDlg::ExpandTree(HTREEITEM hItem, UINT nCode)
{
????if (!hItem) return;

????m_Tree.Expand(hItem, nCode);
????if (m_Tree.ItemHasChildren(hItem))
????{
????????HTREEITEM hChildItem = m_Tree.GetChildItem(hItem);
????????while (hChildItem)
????????{
????????????ExpandTree(hChildItem, nCode);
????????????HTREEITEM hNextItem = m_Tree.GetNextItem(hChildItem, TVGN_NEXT);
????????????hChildItem = hNextItem;
????????}
????}
}

void CMFCTestDlg::OnBnClickedBtnTree()
{
????HTREEITEM hRootItem = m_Tree.GetRootItem(); //從根節點開始遍歷
????static UINT nCode = TVE_EXPAND;
????ExpandTree(hRootItem, nCode);
????nCode = (nCode == TVE_EXPAND) ? TVE_COLLAPSE : TVE_EXPAND;
}

j:編輯節點文本:
①、控件的 Edit Labels 屬性設置為 True;
②、響應控件的 TVN_BEGINLABELEDIT 事件:

void CMFCTestDlg::OnTvnBeginlabeleditTree1(NMHDR *pNMHDR, LRESULT *pResult)
{
????LPNMTVDISPINFO pTVDispInfo = reinterpret_cast<LPNMTVDISPINFO>(pNMHDR);
????
????CEdit *pEdit = m_Tree.GetEditControl();
????if (pEdit) pEdit->LimitText(5);//設置編輯框文本長度為5個字符串

????*pResult = 0; //繼續
????//*pResult = 1; //取消,不繼續編輯,也不觸發 TVN_ENDLABELEDIT
}

③、響應控件的 TVN_ENDLABELEDIT 事件:

void CMFCTestDlg::OnTvnEndlabeleditTree1(NMHDR *pNMHDR, LRESULT *pResult)
{
????LPNMTVDISPINFO pTVDispInfo = reinterpret_cast<LPNMTVDISPINFO>(pNMHDR);
????if (pTVDispInfo && pTVDispInfo->item.pszText && _tcslen(pTVDispInfo->item.pszText))
????{
????????m_Tree.SetItemText(pTVDispInfo->item.hItem, pTVDispInfo->item.pszText);
????}
????*pResult = 0;
}


k、插入帶圖標的節點:
這里面給大家準備幾個ico圖標,供程序使用:
?ico.zip

①、將幾個ico圖標文件添加到工程資源中,ID分別為:IDI_ICON1、IDI_ICON2、IDI_ICON3
②、在對話框類類的頭文件中加入對象聲明:CImageList m_TreeImage;
③、在對話框的初始化函數中創建圖像列表:BOOL bRet = m_TreeImage.Create(16, 16, ILC_MASK | ILC_COLOR32, 1, 1);
④、添加圖標資源到圖像列表:

int iret = m_TreeImage.Add(AfxGetApp()->LoadIcon(IDI_ICON1));
iret = m_TreeImage.Add(AfxGetApp()->LoadIcon(IDI_ICON2));
iret = m_TreeImage.Add(AfxGetApp()->LoadIcon(IDI_ICON3));

⑤、關聯Tree樹形控件和圖像列表:m_Tree.SetImageList(&m_TreeImage, TVSIL_NORMAL);
⑥、將InsertItem插入節點的代碼改為:

HTREEITEM hRoot = m_Tree.InsertItem(_T("根"), 0, 1);
HTREEITEM hSub1 = m_Tree.InsertItem(_T("子1"), 0, 1, hRoot);
HTREEITEM hSub2 = m_Tree.InsertItem(_T("子2"), 0, 1, hRoot);

HTREEITEM hSub3 = m_Tree.InsertItem(_T("子子3"), 0, 1, hSub2);

?

這樣就可以啦~!

其中 InsertItem 的第二個參數0和第三個參數1是ico圖標在ImageList中的索引,第二個參數是節點默認的圖標,第三個參數是節點被選中后的圖標。

4、開源控件類:
codeproject 上面關于 Tree樹形控件 的開源控件類可謂是很多啊,這里面給大家分享一下,需要哪種自己直接拿過去用就行了:

https://www.codeproject.com/Arti ... port-for-HTML-XML-S
?

https://www.codeproject.com/Arti ... -Supports-Transpare
?

https://www.codeproject.com/Articles/6597/CDeviceTree
?

https://www.codeproject.com/Arti ... -select-folders-and
?

https://www.codeproject.com/Articles/2243/COptionTree
?

https://www.codeproject.com/Arti ... operty-Tree-Control
?

https://www.codeproject.com/Arti ... gImage-in-CTreeCtrl
?

https://www.codeproject.com/Arti ... heckboxes-Supported
?

https://www.codeproject.com/Arti ... esque-Owner-Drawn-C
?

https://www.codeproject.com/Arti ... l-that-has-Open-Clo
?

https://www.codeproject.com/Arti ... Millers-COptionTree
?

https://www.codeproject.com/Articles/768/CNetworkTreeCtrl
?

https://www.codeproject.com/Arti ... FX-and-CHourglassFX
?

https://www.codeproject.com/Articles/2913/A-Tree-List-Control
?

https://www.codeproject.com/Arti ... wn-TreeList-Control
?

https://www.codeproject.com/Arti ... th-ToolTip-Based-On
?

https://www.codeproject.com/Arti ... ontrol-with-Columns
?

5、小作業:
①、給Tree樹形控件添加右鍵彈出菜單,菜單中有個復制的菜單項,點擊可以復制結點的文本;
②、點選控件的 CheckBox 后,實際上當前選中的結點不是我點擊的結點,能否做到勾選CheckBox 之后,就選中該結點;
③、實現三態CheckBox,可以直接找開源類來實現:https://www.codeproject.com/Articles/847799/CQuadStateTree

具體操作細節見視頻教程的演示和講解!

第15課免費試看,下載地址:

https://www.cctry.com/thread-297465-1-1.html

總結

以上是生活随笔為你收集整理的《实用VC编程之玩转控件》第15课:Tree树形控件的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。