天天看點

《實用VC程式設計之玩轉控件》第15課:Tree樹形控件

本文轉載自:VC驿站

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

1、控件簡介:

Tree樹形控件也是我們程式設計過程中比較常用的一個控件,而且在其他軟體中也經常能看到,比如Windows系統中的資料總管:

《實用VC程式設計之玩轉控件》第15課:Tree樹形控件

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

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);

《實用VC程式設計之玩轉控件》第15課:Tree樹形控件

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

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); //得到父結點。

《實用VC程式設計之玩轉控件》第15課:Tree樹形控件

從根節點開始周遊所有節點,判斷 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圖示,供程式使用:

《實用VC程式設計之玩轉控件》第15課:Tree樹形控件

 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);

《實用VC程式設計之玩轉控件》第15課:Tree樹形控件

這樣就可以啦~!

其中 InsertItem 的第二個參數0和第三個參數1是ico圖示在ImageList中的索引,第二個參數是節點預設的圖示,第三個參數是節點被選中後的圖示。

4、開源控件類:

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

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

《實用VC程式設計之玩轉控件》第15課:Tree樹形控件

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

《實用VC程式設計之玩轉控件》第15課:Tree樹形控件

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

《實用VC程式設計之玩轉控件》第15課:Tree樹形控件

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

《實用VC程式設計之玩轉控件》第15課:Tree樹形控件

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

《實用VC程式設計之玩轉控件》第15課:Tree樹形控件

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

《實用VC程式設計之玩轉控件》第15課:Tree樹形控件

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

《實用VC程式設計之玩轉控件》第15課:Tree樹形控件

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

《實用VC程式設計之玩轉控件》第15課:Tree樹形控件

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

《實用VC程式設計之玩轉控件》第15課:Tree樹形控件

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

《實用VC程式設計之玩轉控件》第15課:Tree樹形控件

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

《實用VC程式設計之玩轉控件》第15課:Tree樹形控件

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

《實用VC程式設計之玩轉控件》第15課:Tree樹形控件

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

《實用VC程式設計之玩轉控件》第15課:Tree樹形控件

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

《實用VC程式設計之玩轉控件》第15課:Tree樹形控件

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

《實用VC程式設計之玩轉控件》第15課:Tree樹形控件

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

《實用VC程式設計之玩轉控件》第15課:Tree樹形控件

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

《實用VC程式設計之玩轉控件》第15課:Tree樹形控件

5、小作業:

①、給Tree樹形控件添加右鍵彈出菜單,菜單中有個複制的菜單項,點選可以複制結點的文本;

②、點選控件的 CheckBox 後,實際上目前選中的結點不是我點選的結點,能否做到勾選CheckBox 之後,就選中該結點;

③、實作三态CheckBox,可以直接找開源類來實作:https://www.codeproject.com/Articles/847799/CQuadStateTree

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

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

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