前面兩節為大家講了列表視圖控件List Control,這一節開始介紹一種特殊的列表--樹形控件Tree Control。

       樹形控件簡介

       樹形控件在Windows系統中是很常見的,例如資源管理器左側的窗口中就有用來顯示目錄的樹形視圖。樹形視圖中以分層結構顯示數據,每層的縮進不同,層次越低縮進越多。樹形控件的節點一般都由標簽和圖標兩部分組成,圖標用來抽象的描述數據,能夠使樹形控件的層次關系更加清晰。

       樹形控件在插入新的樹節點時會稍麻煩些,回顧之前的列表框,插入新列表項時調用AddString成員函數就可以了,而對于樹形控件則需要指定新節點與已有節點的關系。另外,樹形控件與列表視圖控件一樣,可以在每一個節點的左邊加入圖標。這些都使得樹形控件給人一種復雜的感覺,但我們在使用它一兩次后會發現其實樹形控件用起來還是很方便的。

       樹形控件的通知消息

       下面列出樹形控件特有的通知消息中比較常用的幾個:

       TVN_SELCHANGING和TVN_SELCHANGED:在用戶改變了對樹節點的選擇時,控件會發送這兩個消息。消息會附帶一個指向NMTREEVIEW結構的指針,程序可從該結構中獲得必要的信息。兩個消息都會在該結構的itemOld成員中包含原來的選擇項信息,在itemNew成員中包含新選擇項的信息,在action成員中表明是用戶的什么行為觸發了該通知消息(若是TVC_BYKEYBOARD則表明是鍵盤,若是TVC_BYMOUSE則表明是鼠標,若是TVC_UNKNOWN則表示未知)。兩個消息的不同之處在于,如果TVN_SELCHANGING的消息處理函數返回TRUE,那么就阻止選擇的改變,如果返回FALSE,則允許改變。

       TVN_KEYDOWN:該消息表明了一個鍵盤事件。消息會附帶一個指向NMTVKEYDOWN結構的指針,通過該結構程序可以獲得按鍵的信息。

       TVN_BEGINLABELEDIT和TVN_ENDLABELEDIT:分別在用戶開始編輯和結束編輯節點的標簽時發送。消息會附帶一個指向NMTVDISPINFO結構的指針,程序可從該結構中獲得必要的信息。在前者的消息處理函數中,可以調用GetEditControl()成員函數返回一個指向用于編輯標題的編輯框的指針。如果處理函數返回FALSE,則允許編輯,如果返回TRUE,則禁止編輯。在后者的消息處理函數中,NMTVDISPINFO結構中的item.pszText指向編輯后的新標題,如果pszText為NULL,那么說明用戶放棄了編輯,否則,程序應負責更新節點的標簽,這可以由SetItem()或SetItemText()函數來完成。

VS2010/MFC編程入門之三十(常用控件:樹形控件Tree Control 上)

       樹形控件的相關數據結構

       1. HTREEITEM句柄

       樹形控件中的每個節點都可以由一個HTREEITEM類型的句柄表示。我們通過CTreeCtrl類的成員函數對樹進行訪問和操作時,很多時候都要用到HTREEITEM句柄。

       2. TVITEM結構體

       TVITEM結構體描述了樹形控件節點的屬性,定義如下:

C++代碼
  1. typedef struct tagTVITEM {   
  2.     UINT mask;       // 包含一些掩碼位(下面的括號中列出)的組合,用來表明結構的哪些成員是有效的   
  3.     HTREEITEM hItem; // 樹節點的句柄(TVIF_HANDLE)   
  4.     UINT state;      // 樹節點的狀態(TVIF_STATE)   
  5.     UINT stateMask;  // 狀態的掩碼組合(TVIF_STATE)   
  6.     LPTSTR pszText;  // 樹節點的標簽文本(TVIF_TEXT)   
  7.     int cchTextMax;  // 標簽文本緩沖區的大小(TVIF_TEXT)   
  8.     int iImage;      // 樹節點的圖像索引(TVIF_IMAGE)   
  9.     int iSelectedImage;  // 選中項的圖像索引(TVIF_SELECTEDIMAGE)   
  10.     int cChildren;   // 表明節點是否有子節點,為1則有,為0則沒有(TVIF_CHILDREN)   
  11.     LPARAM lParam;   // 一個32 位的附加數據(TVIF_PARAM)   
  12. } TVITEM, *LPTVITEM;  

       此結構體中多個元素涉及到了圖像和狀態等,有必要具體解釋下。

       樹形控件節點需要顯示圖標時,就要為樹形控件關聯一個圖像序列,上面的iImage成員就代表了該結構體對應的樹節點的圖標在圖像序列中的索引,iSelectedImage則代表該樹節點被選中時顯示的圖標在圖像序列中的索引。對于如何為樹形控件關聯圖像序列,雞啄米將在后面的實例中講到。

       stateMask用來說明要獲取或設置樹節點的哪些狀態。下面是state和stateMask的一些常用值及含義:

          state                            對應的stateMask                       含義         
       TVIS_CUT                          TVIS_CUT                        節點被選擇用來進行剪切和粘貼操作
       TVIS_DROPHILITED           TVIS_DROPHILITED         節點成為拖動操作的目標
       TVIS_EXPANDED               TVIS_EXPANDED              節點的子節點被展開
       TVIS_EXPANDEDONCE      TVIS_EXPANDEDONCE     節點的子節點曾經被展開過
       TVIS_SELECTED                TVIS_SELECTED               節點被選中

       lParam在實際開發中常用來存放與樹節點有關的附加數據。

       3. NMTREEVIEW結構體

       NMTREEVIEW結構體中包含了樹形控件通知消息的相關信息。樹形控件的大多數通知消息都會帶有指向該結構體的指針。NMTREEVIEW結構體的定義如下:

C++代碼
  1. typedef struct tagNMTREEVIEW {   
  2.     NMHDR hdr;      // 標準的NMHDR結構   
  3.     UINT action;    // 表明是用戶的什么行為觸發了該通知消息   
  4.     TVITEM itemOld; // 原節點的屬性   
  5.     TVITEM itemNew; // 新節點的屬性   
  6.     POINT ptDrag;   // 事件發生時鼠標的客戶區坐標   
  7. } NMTREEVIEW, *LPNMTREEVIEW;  

       4. TVINSERTSTRUCT結構體

       向樹形控件中插入新節點時需要用到TVINSERTSTRUCT結構體,它常與TVM_INSERTITEM消息一起使用。定義如下:

C++代碼
  1. typedef struct tagTVINSERTSTRUCT {   
  2.     HTREEITEM hParent;      // 父節點的句柄   
  3.     HTREEITEM hInsertAfter; // 指明插入到同層中哪一項的后面   
  4. #if (_WIN32_IE >= 0x0400)   
  5.     union  
  6.     {   
  7.         TVITEMEX itemex;   
  8.         TVITEM item;   
  9.     } DUMMYUNIONNAME;   
  10. #else   
  11.     TVITEM item;            // 要添加的新節點的屬性   
  12. #endif   
  13. } TVINSERTSTRUCT, *LPTVINSERTSTRUCT;  

       若hParent成員為TVI_ROOT或NULL,那么新節點將被作為樹的根節點插入。hInsertAfter除了可以是某個節點的句柄,還可以有四種取值:TVI_FIRST(插入到樹形控件的最前面)、TVI_LAST(插入到樹形控件的最后面)、TVI_ROOT(作為根節點插入)和TVI_SORT(按字母順序插入)。

       5. NMTVDISPINFO結構體

       NMTVDISPINFO結構體中包含了與樹節點的顯示有關的信息。定義如下:

C++代碼
  1. typedef struct tagNMTVDISPINFO {   
  2.     NMHDR hdr;   
  3.     TVITEM item;   
  4. } NMTVDISPINFO, *LPNMTVDISPINFO;  

       關于樹形控件的使用本節先講這么多,在下節將繼續講解CTreeCtrl類的相關知識和實例。雞啄米謝謝大家能一直跟隨著我學習VS2010/MFC,繼續加油!

除非特別注明,雞啄米文章均為原創
轉載請標明本文地址:http://www.cpbsu.com/software/200.html
2012年7月8日
作者:雞啄米 分類:軟件開發 瀏覽: 評論:12