轉(zhuǎn)帖|使用教程|編輯:鮑佳佳|2021-04-09 10:45:38.903|閱讀 562 次
概述:前面兩節(jié)為大家講了列表視圖控件List Control,這一節(jié)開(kāi)始介紹一種特殊的列表--樹(shù)形控件Tree Control。
# 界面/圖表報(bào)表/文檔/IDE等千款熱門(mén)軟控件火熱銷(xiāo)售中 >>
相關(guān)鏈接:
前面兩節(jié)為大家講了列表視圖控件List Control,這一節(jié)開(kāi)始介紹一種特殊的列表--樹(shù)形控件Tree Control。開(kāi)始前為大家介紹一款MFC萬(wàn)能控件xtreme toolkit Pro。
Xtreme Toolkit Pro:是屢獲殊榮的VC界面庫(kù),是MFC開(kāi)發(fā)中最全面界面控件套包,它提供了Windows開(kāi)發(fā)所需要的11種主流的Visual C++ MFC控件,包括Command Bars、Controls、Chart Pro、Calendar、Docking Pane、Property Grid、Report Control、Shortcut Bar、Syntax Edit、Skin Framework 和Task Panel。
點(diǎn)擊下載Xtreme Toolkit Pro最新試用版
樹(shù)形控件簡(jiǎn)介
樹(shù)形控件在Windows系統(tǒng)中是很常見(jiàn)的,例如資源管理器左側(cè)的窗口中就有用來(lái)顯示目錄的樹(shù)形視圖。樹(shù)形視圖中以分層結(jié)構(gòu)顯示數(shù)據(jù),每層的縮進(jìn)不同,層次越低縮進(jìn)越多。樹(shù)形控件的節(jié)點(diǎn)一般都由標(biāo)簽和圖標(biāo)兩部分組成,圖標(biāo)用來(lái)抽象的描述數(shù)據(jù),能夠使樹(shù)形控件的層次關(guān)系更加清晰。
樹(shù)形控件在插入新的樹(shù)節(jié)點(diǎn)時(shí)會(huì)稍麻煩些,回顧之前的列表框,插入新列表項(xiàng)時(shí)調(diào)用AddString成員函數(shù)就可以了,而對(duì)于樹(shù)形控件則需要指定新節(jié)點(diǎn)與已有節(jié)點(diǎn)的關(guān)系。另外,樹(shù)形控件與列表視圖控件一樣,可以在每一個(gè)節(jié)點(diǎn)的左邊加入圖標(biāo)。這些都使得樹(shù)形控件給人一種復(fù)雜的感覺(jué),但我們?cè)谑褂盟粌纱魏髸?huì)發(fā)現(xiàn)其實(shí)樹(shù)形控件用起來(lái)還是很方便的。
樹(shù)形控件的通知消息
下面列出樹(shù)形控件特有的通知消息中比較常用的幾個(gè):
TVN_SELCHANGING和TVN_SELCHANGED:在用戶改變了對(duì)樹(shù)節(jié)點(diǎn)的選擇時(shí),控件會(huì)發(fā)送這兩個(gè)消息。消息會(huì)附帶一個(gè)指向NMTREEVIEW結(jié)構(gòu)的指針,程序可從該結(jié)構(gòu)中獲得必要的信息。兩個(gè)消息都會(huì)在該結(jié)構(gòu)的itemOld成員中包含原來(lái)的選擇項(xiàng)信息,在itemNew成員中包含新選擇項(xiàng)的信息,在action成員中表明是用戶的什么行為觸發(fā)了該通知消息(若是TVC_BYKEYBOARD則表明是鍵盤(pán),若是TVC_BYMOUSE則表明是鼠標(biāo),若是TVC_UNKNOWN則表示未知)。兩個(gè)消息的不同之處在于,如果TVN_SELCHANGING的消息處理函數(shù)返回TRUE,那么就阻止選擇的改變,如果返回FALSE,則允許改變。
TVN_KEYDOWN:該消息表明了一個(gè)鍵盤(pán)事件。消息會(huì)附帶一個(gè)指向NMTVKEYDOWN結(jié)構(gòu)的指針,通過(guò)該結(jié)構(gòu)程序可以獲得按鍵的信息。
TVN_BEGINLABELEDIT和TVN_ENDLABELEDIT:分別在用戶開(kāi)始編輯和結(jié)束編輯節(jié)點(diǎn)的標(biāo)簽時(shí)發(fā)送。消息會(huì)附帶一個(gè)指向NMTVDISPINFO結(jié)構(gòu)的指針,程序可從該結(jié)構(gòu)中獲得必要的信息。在前者的消息處理函數(shù)中,可以調(diào)用GetEditControl()成員函數(shù)返回一個(gè)指向用于編輯標(biāo)題的編輯框的指針。如果處理函數(shù)返回FALSE,則允許編輯,如果返回TRUE,則禁止編輯。在后者的消息處理函數(shù)中,NMTVDISPINFO結(jié)構(gòu)中的item.pszText指向編輯后的新標(biāo)題,如果pszText為NULL,那么說(shuō)明用戶放棄了編輯,否則,程序應(yīng)負(fù)責(zé)更新節(jié)點(diǎn)的標(biāo)簽,這可以由SetItem()或SetItemText()函數(shù)來(lái)完成。
樹(shù)形控件的相關(guān)數(shù)據(jù)結(jié)構(gòu)
1. HTREEITEM句柄
樹(shù)形控件中的每個(gè)節(jié)點(diǎn)都可以由一個(gè)HTREEITEM類型的句柄表示。我們通過(guò)CTreeCtrl類的成員函數(shù)對(duì)樹(shù)進(jìn)行訪問(wèn)和操作時(shí),很多時(shí)候都要用到HTREEITEM句柄。
2. TVITEM結(jié)構(gòu)體
TVITEM結(jié)構(gòu)體描述了樹(shù)形控件節(jié)點(diǎn)的屬性,定義如下:
C++代碼
typedef struct tagTVITEM { UINT mask; // 包含一些掩碼位(下面的括號(hào)中列出)的組合,用來(lái)表明結(jié)構(gòu)的哪些成員是有效的 HTREEITEM hItem; // 樹(shù)節(jié)點(diǎn)的句柄(TVIF_HANDLE) UINT state; // 樹(shù)節(jié)點(diǎn)的狀態(tài)(TVIF_STATE) UINT stateMask; // 狀態(tài)的掩碼組合(TVIF_STATE) LPTSTR pszText; // 樹(shù)節(jié)點(diǎn)的標(biāo)簽文本(TVIF_TEXT) int cchTextMax; // 標(biāo)簽文本緩沖區(qū)的大小(TVIF_TEXT) int iImage; // 樹(shù)節(jié)點(diǎn)的圖像索引(TVIF_IMAGE) int iSelectedImage; // 選中項(xiàng)的圖像索引(TVIF_SELECTEDIMAGE) int cChildren; // 表明節(jié)點(diǎn)是否有子節(jié)點(diǎn),為1則有,為0則沒(méi)有(TVIF_CHILDREN) LPARAM lParam; // 一個(gè)32 位的附加數(shù)據(jù)(TVIF_PARAM) } TVITEM, *LPTVITEM;
此結(jié)構(gòu)體中多個(gè)元素涉及到了圖像和狀態(tài)等,有必要具體解釋下。
樹(shù)形控件節(jié)點(diǎn)需要顯示圖標(biāo)時(shí),就要為樹(shù)形控件關(guān)聯(lián)一個(gè)圖像序列,上面的iImage成員就代表了該結(jié)構(gòu)體對(duì)應(yīng)的樹(shù)節(jié)點(diǎn)的圖標(biāo)在圖像序列中的索引,iSelectedImage則代表該樹(shù)節(jié)點(diǎn)被選中時(shí)顯示的圖標(biāo)在圖像序列中的索引。對(duì)于如何為樹(shù)形控件關(guān)聯(lián)圖像序列,雞啄米將在后面的實(shí)例中講到。
stateMask用來(lái)說(shuō)明要獲取或設(shè)置樹(shù)節(jié)點(diǎn)的哪些狀態(tài)。下面是state和stateMask的一些常用值及含義:
state 對(duì)應(yīng)的stateMask 含義
TVIS_CUT TVIS_CUT 節(jié)點(diǎn)被選擇用來(lái)進(jìn)行剪切和粘貼操作
TVIS_DROPHILITED TVIS_DROPHILITED 節(jié)點(diǎn)成為拖動(dòng)操作的目標(biāo)
TVIS_EXPANDED TVIS_EXPANDED 節(jié)點(diǎn)的子節(jié)點(diǎn)被展開(kāi)
TVIS_EXPANDEDONCE TVIS_EXPANDEDONCE 節(jié)點(diǎn)的子節(jié)點(diǎn)曾經(jīng)被展開(kāi)過(guò)
TVIS_SELECTED TVIS_SELECTED 節(jié)點(diǎn)被選中
lParam在實(shí)際開(kāi)發(fā)中常用來(lái)存放與樹(shù)節(jié)點(diǎn)有關(guān)的附加數(shù)據(jù)。
3. NMTREEVIEW結(jié)構(gòu)體
NMTREEVIEW結(jié)構(gòu)體中包含了樹(shù)形控件通知消息的相關(guān)信息。樹(shù)形控件的大多數(shù)通知消息都會(huì)帶有指向該結(jié)構(gòu)體的指針。NMTREEVIEW結(jié)構(gòu)體的定義如下:
C++代碼
typedef struct tagNMTREEVIEW { NMHDR hdr; // 標(biāo)準(zhǔn)的NMHDR結(jié)構(gòu) UINT action; // 表明是用戶的什么行為觸發(fā)了該通知消息 TVITEM itemOld; // 原節(jié)點(diǎn)的屬性 TVITEM itemNew; // 新節(jié)點(diǎn)的屬性 POINT ptDrag; // 事件發(fā)生時(shí)鼠標(biāo)的客戶區(qū)坐標(biāo) } NMTREEVIEW, *LPNMTREEVIEW;
4. TVINSERTSTRUCT結(jié)構(gòu)體
向樹(shù)形控件中插入新節(jié)點(diǎn)時(shí)需要用到TVINSERTSTRUCT結(jié)構(gòu)體,它常與TVM_INSERTITEM消息一起使用。定義如下:
C++代碼
typedef struct tagTVINSERTSTRUCT { HTREEITEM hParent; // 父節(jié)點(diǎn)的句柄 HTREEITEM hInsertAfter; // 指明插入到同層中哪一項(xiàng)的后面 #if (_WIN32_IE >= 0x0400) union { TVITEMEX itemex; TVITEM item; } DUMMYUNIONNAME; #else TVITEM item; // 要添加的新節(jié)點(diǎn)的屬性 #endif } TVINSERTSTRUCT, *LPTVINSERTSTRUCT;
若hParent成員為T(mén)VI_ROOT或NULL,那么新節(jié)點(diǎn)將被作為樹(shù)的根節(jié)點(diǎn)插入。hInsertAfter除了可以是某個(gè)節(jié)點(diǎn)的句柄,還可以有四種取值:TVI_FIRST(插入到樹(shù)形控件的最前面)、TVI_LAST(插入到樹(shù)形控件的最后面)、TVI_ROOT(作為根節(jié)點(diǎn)插入)和TVI_SORT(按字母順序插入)。
5. NMTVDISPINFO結(jié)構(gòu)體
NMTVDISPINFO結(jié)構(gòu)體中包含了與樹(shù)節(jié)點(diǎn)的顯示有關(guān)的信息。定義如下:
C++代碼
typedef struct tagNMTVDISPINFO { NMHDR hdr; TVITEM item; } NMTVDISPINFO, *LPNMTVDISPINFO;
關(guān)于樹(shù)形控件的使用本節(jié)先講這么多,在下節(jié)將繼續(xù)講解CTreeCtrl類的相關(guān)知識(shí)和實(shí)例。
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請(qǐng)務(wù)必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請(qǐng)郵件反饋至chenjj@fc6vip.cn