树形控件TreeCtrl,第1张

树形控件TreeCtrl,第2张

树形控件可以用在树形结构中,有一个根,根下有很多子节点,每个子节点允许有一个或多个子节点,也可以没有子节点。MFC中使用CTreeCtrl类来封装树控件的各种操作。通过调用boolcreate (dword dwstyle,constrect & rect,cwnd * pparentwnd,uintnid);创建一个窗口。dwStyle中可以使用以下特殊样式的树控件:

TVS_HASLINES在父/子节点之间画一条线
TVS _ lines在根/子节点之间画一条线
TVS_HASBUTTONS在每个节点前添加一个按钮,用于指示当前节点是否已展开的显示字符
TVS_EDITLABELS节点可编辑
TVS_SHOWSELALWAYS在失去焦点时也显示当前选定的节点
TVS_DISABLEDRAGDROP不允许拖放
TVS_NOTOOLTIPS不使用工具提示在树控件中,每个节点都有一个句柄(HTREEITEM)。同时,添加节点时必须提供的参数是该节点的父节点的句柄(在只有一个根节点的情况下,既不能添加也不能删除)使用htree item insert item(lpctstr lpszitem,htree item hparet = tvi _ root,htree item hinserttafter = tvi _ last);可以添加一个节点,pszItem是显示的字符,hParent表示父节点的句柄,当前添加的节点会排在hInsertAfter表示的节点之后,返回值是当前创建的节点的句柄。下面的代码将建立如下形式的树形结构:+-parent 1+-child 1 _ 1+-child 1 _ 2+-child 1 _ 3+-parent 2+-parent 3/*假设m_tree是一个CTreeCtrl对象,窗口已经创建*/ hItem = m_tree。InsertItem("Parent1 ",TVI _根);在根节点上添加parent 1 hsubitem = m _ tree . insert item(" child 1 _ 1 ",hitem);//在Parent1上添加子节点hsubi item = m _ tree . insert item(" child 1 _ 2 ",hitem,hsubi item);//在Parent1上添加一个子节点,该子节点在Child1_1之后,hsubitem = m _ tree . insert item(" child 1 _ 3 ",hitem,hsubitem);hItem = m_tree。InsertItem("Parent2 ",TVI _根,hItem);hItem = m_tree。InsertItem("Parent3 ",TVI _根,hItem);如果要在每个节点前面添加一个小图标,必须先调用cimagelist * set imagelist(cimagelist * p imagelist,int nimagelisttype);表示当前使用的ImageList,nImageListType为TVSIL_NORMAL。调用完成后控件中使用的图片以设置的ImageList中的图片为准。然后调用
htree item insert item(lpctstr lpszitem,int nimage,int nselectedimage,htree item HPARENT = TVI _根,htree item hinserttafter = TVI _最后);添加一个节点,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,TV sil _ NORMAL);m_tree。InsertItem("Parent1 ",0,1);//Add,选中时显示图标1,不选中时显示图标0
此外,CTreeCtrl还提供了一些获取/修改控件状态的函数。
HTREEITEM GetSelectedItem();将返回当前选定节点的句柄。BOOL SelectItem(HTREEITEM hItem);将选择指示的节点。
Bool GetItem Image(htree item hitem,int & nimage,int & nselected Image)/Bool SetItem Image(htree item hitem,int nimage,int nselectedimage)用于获取/修改节点使用的图标索引。
CString getitem text(HTREEITEM hItem)/BOOL setitem text(HTREEITEM hItem,LPCTSTR lpszItem);用于获取/修改一个节点的显示字符。
BOOL delete item(HTREEITEM hItem);用于删除一个节点,BOOL DeleteAllItems();所有节点都将被删除。
另外,如果要遍历树,可以使用下面的函数:
HTREEITEM GetRootItem();获取根节点。
HTREEITEM get child item(HTREEITEM hItem);获取子节点。
HTREEITEM GetPrevSiblingItem/GetNextSiblingItem(HTREEITEM hItem);获取指定节点的上一个/下一个同级节点。
HTREEITEM get parentitem(HTREEITEM hItem);获取父节点。
树控件的消息映射使用ON_NOTIFY宏,形式如下:on _ notify (wNotifyCode,id,MemberFXN),其中wNotifyCode是通知代码,ID是生成消息的窗口ID,memberFxn是处理函数。函数的原型就像void onxxxtree (NMHDR * pNMHDR,LRESULT * PRESULT),其中pNMHDR是一个数据结构,在具体使用时需要转换成其他类型的结构。树控件可能值和相应的数据结构是:

TVN_SELCHANGED在所选节点更改后发送。结构:nm treeview
Tvn _ item expanded在节点展开后发送。结构:nm treeview
Tvn _ beginlabeledit在编辑节点字符时发送。使用结构:NMTVDISINFO
TVN _结束标签编辑在编辑节点字符时发送。使用的结构:NMTVDISINFO
TVN _ GetDISINFO在你需要获取一些节点信息的时候发送。用过的结构:NMTVDISINFO有很多关于ON_NOTIFY的内容,以后会详细讲解。

关于动态提供节点显示的字符:首先需要在添加节点时指明lpszItem参数为:LPSTR_TEXTCALLBACK。当控件显示此节点时,它将通过发送TVN _获取调度信息来获取所需的字符。在处理这个消息的时候,它先把参数pNMHDR转换成LPNMTVDISPINFO,然后用item.pszText填充但是我们怎么知道这个节点对应的信息呢?我的做法是在添加一个节点后设置它的lParam参数,然后在提供信息时使用这个参数查找相应的信息。下面的代码说明了这个方法:charszout[8][3]= { " 1号"," 2号"," 3号" };//添加节点htree item hitem = m _ tree . insert item(lpstr _ text callback,...)m _ tree.setitemdata (hitem,0);hItem = m_tree。InsertItem(LPSTR_TEXTCALLBACK,...)m_tree。SetItemData(hItem,1);//处理消息void cparentwnd::ongetdispinfotree(nm HDR * pnm HDR,lresult * preset){ TV _ dispinfo * ptvdi =(TV _ dispinfo *)pnm HDR;pTVDI-> item . PSZ text = SZ out[pTVDI-> item . lparam];//通过lParam * preset = 0获取要显示的字符在数组中的位置;}

关于编辑节点的显示字符:首先需要设置树形控件的TVS_EDITLABELS样式。在编辑开始时,控件将发送TVN _ beginlabelite。可以通过在处理函数中返回TRUE来取消后续的编辑,编辑完成后发送TVN_ENDLABELEDIT。在处理这条消息时,需要将参数pNMHDR转换成LPNMTVDISPINFO,然后通过item.pszText获取编辑后的字符,并进行重置。如果编辑器中途取消,这个变量为NULL。下面的代码演示了如何处理这些消息://处理消息TVN _ beginlabeledit void cparentwnd::Onbeginedittree(nm HDR * pnm HDR,LRESULT * PREULT){ TV _ dispinfo * ptvdi =(TV _ dispinfo *)pnm HDR;if(pTVDI-> item . lparam = = 0);//确定是否取消操作* preset = 1;else * pResult = 0;}//处理消息TVN _ beginlabeledit void cparentwnd::Onbeginedittree(nm HDR * pnm HDR,LRESULT * PRESULT){ TV _ dispinfo * pt VDI =(TV _ dispinfo *)pnm HDR;if(pTVDI-> item . psztext = = NULL);//确定m _ tree . setitemtext(pt VDI-> item . hitem,ptvdi-> psztext)的编辑是否已经取消;//重置显示字符* preset = 0;}上述方法执行的消息映射必须在父窗口中执行(同样,WM_NOTIFY的所有消息都需要在父窗口中处理)。

位律师回复
DABAN RP主题是一个优秀的主题,极致后台体验,无插件,集成会员系统
白度搜_经验知识百科全书 » 树形控件TreeCtrl

0条评论

发表评论

提供最优质的资源集合

立即查看 了解详情