MFC控制項篇之TreeCtrl

2021-08-22 10:42:18 字數 4429 閱讀 1018

tree ctrl

樹形控制項treectrl和下節要講的列表控制項 listctrl在系統中大量被使用,例如windows資源管理器就是乙個典型的例子。

樹形控制項可以用於樹形的結構,其中有乙個根接點(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 on***tree(nmhdr* pnmhdr, lresult* presult),其中pnmhdr為一資料結構,在具體使用時需要轉換成其他型別的結構。對於樹形控制項可能取值和對應的資料結構為:

tvn_selchanged 在所選中的結點發生改變後傳送,所用結構:nmtreeview

tvn_itemexpanded 在某結點被展開後傳送,所用結構:nmtreeview

tvn_getdispinfo 在需要得到某結點資訊時傳送,(如得到結點的顯示字元)所用結構:nmtvdispinfo 關於on_notify有很多內容,將在以後的內容中進行詳細講解。

關於動態提供結點所顯示的字元:首先你在新增結點時需要指明lpszitem引數為:lpstr_textcallback。在控制項顯示該結點時會通過傳送tvn_getdispinfo來取得所需要的字元,在處理該訊息時先將引數pnmhdr轉換為lpnmtvdispinfo,然後填充其中item.psztext。但是我們通過什麼來知道該結點所對應的資訊呢,我的做法是在新增結點後設定其lparam引數,然後在提供資訊時利用該引數來查詢所對應的資訊。下面的**說明了這種方法: char szout[8][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)

關於編輯結點的顯示字元:首先需要設定樹形控制項的tvs_editlabels風格,在開始編輯時該控制項將會傳送tvn_beginlabeledit,你可以通過在處理函式中返回true來取消接下來的編輯,在編輯完成後會傳送tvn_endlabeledit,在處理該訊息時需要將引數pnmhdr轉換為lpnmtvdispinfo,然後通過其中的item.psztext得到編輯後的字元,並重置顯示字元。如果編輯在中途中取消該變數為null。下面的**說明如何處理這些訊息: //處理訊息 tvn_beginlabeledit void cparentwnd::onbeginedittree(nmhdr* pnmhdr, lresult* presult) //處理訊息 tvn_beginlabeledit void cparentwnd::onbeginedittree(nmhdr* pnmhdr, lresult* presult) 上面講述的方法所進行的訊息對映必須在父視窗中進行(同樣wm_notify的所有訊息都需要在父視窗中處理)。

MFC控制項篇之StatusBar

status bar 狀態條用於顯示一些提示字元。mfc中使用cstatusbar類來封裝狀態條控制項的各種操作。通過呼叫 bool create cwnd pparentwnd,dword dwstyle ws child ws visible cbrs bottom,uint nid afx i...

MFC之TreeCtrl遍歷所有節點

這個例子,主要是查詢樹上的某個節點,並展開選中它。採用來了遞迴方法來實現。主要用到的方法 ctreectrl getchilditem htreeitem getchilditem htreeitem hitem 返回值 如果成功則返回該子項的控制代碼 否則返回null。採用遞迴的思想,把每個遍歷到...

MFC使用TreeCtrl控制項實現樹型列表(二)

treectrl控制項的新增 控制項的在該view新增的類裡面建立 public afx msg void oninitialupdate virtual void myexpandtree htreeitem htreeitem ctreectrl m treectrl 控制項的相關功能的實現 v...