VC中樹形控制項(CTreeCtrl)的使用

2021-05-22 08:15:18 字數 4558 閱讀 3171

樹形控制項可以用於樹形的結構,其中有乙個根接點(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_beginlabeledit 在開始編輯結點字元時傳送,所用結構:nmtvdispinfo

tvn_endlabeledit 在結束編輯結點字元時傳送,所用結構:nmtvdispinfo

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的所有訊息都需要在父視窗中處理)。

VC中的樹形控制項

樹形控制項可以顯示出各項之間的層次關係,因此在vc中很常用。tvs hasbuttons 在父專案前顯示 使用者可以通過點選該符號來開啟或收起子項 tvs haslines 在層次中用線條來連線各個專案名稱。tvs linesatroot 在根目錄下的專案也用線連線。1.htreeitem控制代碼 ...

樹形控制項QTreeWidget

1 import sys2 from pyqt5.qtcore importqt3 from pyqt5.qtwidgets import qlabel,qhboxlayout45 6class demo qwidget 7def init self 8 super demo,self init 9...

VC中edit控制項使用

setsel start,end 作用 定製edit的所選擇內容.間接地可以用於定位游標位置.使用例子 exp1 設定游標 cedit pedit cedit getdlgitem idc edit1 pedit setsel 2,2 pedit setfocus exp2 選擇內容 cedit p...