CTree 使用詳解 轉:

來源:互聯網
上載者:User
樹型視的三個結構TVINSERTSTRUCT、TVITEM、NMTREEVIEWTVINSERTSTRUCT 包含添加新項到樹形視控制項所使用的資訊。這個結構被TVM_INSERTITEM訊息使用。這個結構與 TV_INSERTSTRUCT結構是一樣的,但它已經按當前的命名習慣重新命名了。
typedef struct tagTVINSERTSTRUCT {    HTREEITEM hParent;    HTREEITEM hInsertAfter;#if (_WIN32_IE >= 0x0400)    union    {        TVITEMEX itemex;        TVITEM item;    } DUMMYUNIONNAME;#else    TVITEM item;#endif} TVINSERTSTRUCT, FAR *LPTVINSERTSTRUCT;
成員
hParent
父項的控制代碼。如果這個成員的值是TVI_ROOT或NULL,這項將被作為樹形控制項的根插入。
hInsertAfter
插入的新項之後的項的控制代碼。或是下列值之一:

意味
TVI_FIRST 在列表的開始插入項
TVI_LAST 在列表的最後插入項
TVI_ROOT 作為一個根項添加
TVI_SORT 以字母順序插入項
itemex
版本4.71。TVITEMEX包含關於項添加的資訊。
item
TVITEM包含關於項添加的資訊。
需求   Windows NT/2000:需要Windows NT 3.51或更高版本。
   Windows 95/98:需要Windows 95或更高版本。
   Header:定義在commctrl.h。TVITEM指定或接收樹形視項的屬性。這個結構與 TV_ITEM結構一樣,但它已經被當前命名協議重新命名了。新的應用程式應該使用這個結構。
typedef struct tagTVITEM{    UINT      mask;    HTREEITEM hItem;    UINT      state;    UINT      stateMask;    LPTSTR    pszText;    int       cchTextMax;    int       iImage;    int       iSelectedImage;    int       cChildren;    LPARAM    lParam;} TVITEM, FAR *LPTVITEM;
成員
mask
指出其它的結構成員哪些包含有效資料的標記數組。當這個結構被TVM_GETITEM訊息使用時, mask成員指出項的屬性被取回。這個成員可以是下列值的一個或多個。

TVIF_CHILDREN cChildren成員是有效。
TVIF_DI_SETITEM 樹形視控制項將保留支援資訊並且不重新請求它。當處理TVN_GETDISPINF通知時,這個標記是有效。
TVIF_HANDLE hItem成員有效。
TVIF_IMAGE iImage成員有效。
TVIF_PARAM lParam成員有效。
TVIF_SELECTEDIMAGE iSelectedImage成員有效。
TVIF_STATE statestateMask成員有效。
TVIF_TEXT pszTextcchTextMax成員有效。
hItem
這個函數引用的項。
state
位標記和映像清單索引的設定,指出項的狀態。當設定了一個項的狀態, stateMask成員指出這個成員的位是有效。當取加一個項的狀態時,這個成員返回 stateMask成員指出的位的目前狀態。

這個成員的0至7位包含了項的狀態標記。關於可能的項狀態標記,參見Tree View Control Item States.覆蓋映像覆蓋在項的表徵圖映像之上。這個成員的8至11位指定了以1為基準的覆蓋映像索引。如果這些位是0,這個項沒有覆蓋映像。要隔離這些位,使用TVIS_OVERLAYMASK掩碼。要在這個成員中設定覆蓋映像索引,使用INDEXTOOVERLAYMASK宏。映像列表的覆蓋映像是被ImageList_SetOverlayImage函數設定的。一個狀態映像是僅次於指出應用程式定義的狀態的項的表徵圖顯示的。通過發送TVM_SETIMAGELIST訊息來指定一個狀態映像列表。要設定一個項的狀態映像,在 TVITEM結構的 stateMask成員中包含TVIS_STATEIMAGEMASK值。結構的 state成員的12至15位指定狀態映像列表中被繪製映像的索引。要設定狀態映像索引,使用INDEXTOSTATEIMAGEMASK。這個宏把一個索引適當的設定到12至15位上。要指出項沒有狀態映像,設定索引為0。這意味著在狀態映像列表中的映像0不能被作為一個狀態映像使用。要隔離 state成員的位12至15,使用TVIS_STATEIMAGEMASK掩碼。
stateMask
state成員的位是有效。如果你取回了一個項的狀態,設定 stateMask成員的位來指出 state成員中的這個位被返回。如果你設定了一個項的狀態,設定 stateMask成員的位來指出 state成員的這個位是你想設定的。要設定或取回一個項的覆蓋映像的索引,設定TVIS_OVERLAYMASK位。要設定和取回一個項的狀態映像索引,設定TVIS_STATEIMAGEMASK位。
pszText
如果這個結構指定了項屬性,那麼這個成員是指向一個以Null 字元結束的字串,包含有項的文本。如果這個成員是值LPSTR_TEXTCALLBACK,那麼父視窗為儲存名字負責。既然這樣,當樹形視控制項需要顯示、儲存或編輯項文本時,向父視窗發送TVN_GETDISPINFO通過訊息,當項文本改變時,發送TVN_SETDISPINFO通知訊息。

如果結構是取回項的屬性,這個成員是取回項文本緩衝的地址。
cchTextMax
pszText成員指定緩衝的大小,以字元為單位。如果這個結構被使用來設定項屬性,這個成員被忽略。
iImage
當項是在非選擇狀態中時,是樹形控制項的映像列表的索引。

如果這個成員是值I_IMAGECALLBACK,父視窗為儲存索引負責。既然這樣,當樹形視控制項需要顯示這個映像時,向父視窗發送TVN_GETDISPINFO通知訊息來獲得索引。
iSelectedImage
當項被選擇時,是樹形控制項映像列表的索引。

如果這個成員是值I_IMAGECALLBACK,父視窗為儲存索引負責。既然這樣,當樹形視控制項需要顯示這個映像時,向父視窗發送TVN_GETDISPINFO通知訊息來獲得索引。
cChildren
標記指出哪一個項有關聯的子項。這個成員可以是下列值之一。

zero 這個項沒有子項。
one 這個項有一個或更多的子項。
I_CHILDRENCALLBACK The parent window keeps track of whether the item has child items. In this case, when the tree view control needs to display the item, the control sends the parent a
TVN_GETDISPINFO
notification message to determine whether the item has child items.

If the tree view control has the
TVS_HASBUTTONS style, it
uses this member to determine whether to display the button indicating the presence of child items. You can use this member to force the control to display the button even though the item does not have any child items inserted. This allows you to display the
button while minimizing the control's memory usage by inserting child items only when the item is visible or expanded.
lParam
與這項相關的32位值。
需要   Windows NT/2000:需要Windows NT 3.51或更高版本。
   Windows 95/98:需要Windows 95或更高版本。
   Header:定義在commctrl.h。NMTREEVIEW
包含關於樹形視通知訊息的資訊。這個結構與 NM_TREEVIEW結構一樣,但它已經用當前的命名規則進行了重新命名。
typedef struct tagNMTREEVIEW {    NMHDR hdr;     UINT action;     TVITEM itemOld;     TVITEM itemNew;     POINT ptDrag; } NMTREEVIEW, FAR *LPNMTREEVIEW; 
成員
hdr
NMHDR結構,包含了關於這個通知訊息的資訊
action
通知指定的動作標記。
itemOld
包含關於舊項狀態資訊的TVITEM結構。通知訊息沒有使用它時,這個成員為0。
itemNew
包含關於新項狀態資訊的TVITEM結構。通知訊息沒有使用它時,這個成員為0。
ptDrag
包含引起通知訊息發送的事件資訊的POINT結構。
參見WM_NOTIFY***********************************************************************************************************************************樹形控制項是用於構造樹形的結構,其中有一個根接點(Root)然後下面有許多子結點,而每個子結點上有允許有一個或多個或沒有子結點。MFC中使用CTreeCtrl類來封裝樹形控制項的各種操作。通過調用
BOOL Create( DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID );
建立一個視窗,dwStyle中可以使用以下一些樹形控制項的專用風格:TVS_HASLINES 在父/子結點之間繪製連線
TVS_LINESATROOT 在根/子結點之間繪製連線
TVS_HASBUTTONS 在每一個結點前添加一個按鈕,用於表示當前結點是否已被展開
TVS_EDITLABELS 結點的顯示字元可以被編輯
TVS_SHOWSELALWAYS 在失去焦點時也顯示當前選中的結點
TVS_DISABLEDRAGDROP 不允許Drag/Drop
TVS_NOTOOLTIPS 不使用ToolTip顯示結點的顯示字元在樹形控制項中每一個結點都有一個控制代碼(HTREEITEM),同時添加結點時必須提供的參數是該結點的父結點控制代碼,(其中根Root結點只有一個,既不可以添加也不可以刪除)利用
HTREEITEM InsertItem( LPCTSTR lpszItem, HTREEITEM hParent = TVI_ROOT, HTREEITEM hInsertAfter = TVI_LAST );
可以添加一個結點,pszItem為顯示的字元,hParent代表父結點的控制代碼,當前添加的結點會排在hInsertAfter表示的結點的後面,傳回值為當前建立的結點的控制代碼。下面的代碼會建立一個如下形式的樹形結構:+--- Parent1
    +--- Child1_1
    +--- Child1_2
    +--- Child1_3
+--- Parent2
+--- Parent3/*假設m_tree為一個CTreeCtrl對象,而且該視窗已經建立*/
HTREEITEM hItem,hSubItem;
hItem = m_tree.InsertItem("Parent1",TVI_ROOT);在根結點上添加Parent1
hSubItem = m_tree.InsertItem("Child1_1",hItem);//在Parent1上添加一個子結點
hSubItem = m_tree.InsertItem("Child1_2",hItem,hSubItem);//在Parent1上添加一個子結點,排在Child1_1後面
hSubItem = m_tree.InsertItem("Child1_3",hItem,hSubItem);hItem = m_tree.InsertItem("Parent2",TVI_ROOT,hItem);   
hItem = m_tree.InsertItem("Parent3",TVI_ROOT,hItem);   如果你希望在每個結點前添加一個小表徵圖,就必需先調用
CImageList* SetImageList( CImageList * pImageList, int nImageListType );
指明當前所使用的ImageList,nImageListType為TVSIL_NORMAL。在調用完成後控制項中使用圖片以設定的ImageList中圖片為準。然後調用
HTREEITEM InsertItem( LPCTSTR lpszItem, int nImage, int nSelectedImage, HTREEITEM hParent = TVI_ROOT, HTREEITEM hInsertAfter = TVI_LAST);
添加結點,nImage為結點沒被選中時所使用圖片序號,nSelectedImage為結點被選中時所使用圖片序號。下面的代碼示範了ImageList的設定。/*m_list 為CImageList對象
IDB_TREE 為16*(16*4)的位元影像,每個圖片為16*16共4個表徵圖*/
m_list.Create(IDB_TREE,16,4,RGB(0,0,0));
m_tree.SetImageList(&m_list,TVSIL_NORMAL);
m_tree.InsertItem("Parent1",0,1);//添加,選中時顯示表徵圖1,未選中時顯示表徵圖0此外CTreeCtrl還提供了一些函數用於得到/修改控制項的狀態。
HTREEITEM GetSelectedItem( );將返回當前選中的結點的控制代碼。
BOOL SelectItem( HTREEITEM hItem );將選中指明結點。
BOOL GetItemImage( HTREEITEM hItem, int& nImage, int& nSelectedImage ) / BOOL SetItemImage( HTREEITEM hItem, int nImage, int nSelectedImage )用於得到/修改某結點所使用表徵圖索引。

CString GetItemText( HTREEITEM hItem ) /BOOL SetItemText( HTREEITEM hItem, LPCTSTR lpszItem );用於得到/修改某一結點的顯示字元。

BOOL DeleteItem( HTREEITEM hItem );用於刪除某一結點,
BOOL DeleteAllItems( );將刪除所有結點。此外如果想遍曆樹可以使用下面的函數:
HTREEITEM GetRootItem( );得到根結點。
HTREEITEM GetChildItem( HTREEITEM hItem );得到子結點。

HTREEITEM GetPrevSiblingItem/GetNextSiblingItem( HTREEITEM hItem );得到指明結點的上/下一個兄弟結點。

HTREEITEM GetParentItem( HTREEITEM hItem );得到父結點。樹形控制項的訊息映射使用ON_NOTIFY宏,形式如同:ON_NOTIFY( wNotifyCode, id, memberFxn ),wNotifyCode為通知代碼,id為產生該訊息的視窗ID,memberFxn為處理函數,函數的原型如同void OnXXXTree(NMHDR* pNMHDR, LRESULT* pResult),其中pNMHDR為一資料結構,在具體使用時需要轉換成其他類型的結構。對於樹形控制項可能取值和對應的資料結構為:TVN_SELCHANGED 在所選中的結點發生改變後發送,所用結構:NMTREEVIEW
TVN_ITEMEXPANDED 在某結點被展開後發送,所用結構:NMTREEVIEW
TVN_BEGINLABELEDIT 在開始編輯結點字元時發送,所用結構:NMTVDISPINFO
TVN_ENDLABELEDIT 在結束編輯結點字元時發送,所用結構:NMTVDISPINFO
TVN_GETDISPINFO 在需要得到某結點資訊時發送,(如得到結點的顯示字元)所用結構:NMTVDISPINFO
關於ON_NOTIFY有很多內容,將在以後的內容中進行詳細講解。關於動態提供結點所顯示的字元:首先你在添加結點時需要指明lpszItem參數為:LPSTR_TEXTCALLBACK。在控制項顯示該結點時會通過發送TVN_GETDISPINFO來取得所需要的字元,在處理該訊息時先將參數pNMHDR轉換為LPNMTVDISPINFO,然後填充其中item.pszText。但是我們通過什麼來知道該結點所對應的資訊呢,我的做法是在添加結點後設定其lParam參數,然後在提供資訊時利用該參數來尋找所對應的資訊。下面的代碼說明了這種方法:char szOut[8][3]={"No.1","No.2","No.3"};//添加結點
HTREEITEM hItem = m_tree.InsertItem(LPSTR_TEXTCALLBACK,...)
m_tree.SetItemData(hItem, 0 );
hItem = m_tree.InsertItem(LPSTR_TEXTCALLBACK,...)
m_tree.SetItemData(hItem, 1 );
//處理訊息
void CParentWnd::OnGetDispInfoTree(NMHDR* pNMHDR, LRESULT* pResult)
{
TV_DISPINFO* pTVDI = (TV_DISPINFO*)pNMHDR;
pTVDI->item.pszText=szOut[pTVDI->item.lParam];//通過lParam得到需要顯示的字元在數組中的位置
*pResult = 0;
}關於編輯結點的顯示字元:首先需要設定樹形控制項的TVS_EDITLABELS風格,在開始編輯時該控制項將會發送TVN_BEGINLABELEDIT,你可以通過在處理函數中返回TRUE來取消接下來的編輯,在編輯完成後會發送TVN_ENDLABELEDIT,在處理該訊息時需要將參數pNMHDR轉換為LPNMTVDISPINFO,然後通過其中的item.pszText得到編輯後的字元,並重設顯示字元。如果編輯在中途中取消該變數為NULL。下面的代碼說明如何處理這些訊息://處理訊息 TVN_BEGINLABELEDIT
void CParentWnd::OnBeginEditTree(NMHDR* pNMHDR, LRESULT* pResult)
{
TV_DISPINFO* pTVDI = (TV_DISPINFO*)pNMHDR;
if(pTVDI->item.lParam == 0);//判斷是否取消該操作
*pResult = 0;
else
*pResult = 1;
}
//處理訊息 TVN_BEGINLABELEDIT
void CParentWnd::OnBeginEditTree(NMHDR* pNMHDR, LRESULT* pResult)
{
TV_DISPINFO* pTVDI = (TV_DISPINFO*)pNMHDR;
if(pTVDI->item.pszText != NULL);//判斷是否已經取消取消編輯
m_tree.SetItemText(pTVDI->item.hItem,pTVDI->pszText);//重設顯示字元
*pResult = 0;
}上面講述的方法所進行的訊息映射必須在父視窗中進行(同樣WM_NOTIFY的所有訊息都需要在父視窗中處理)。
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.