树形控件TreeCtrl的用法

来源:互联网 发布:boox和kindle对比 知乎 编辑:程序博客网 时间:2024/05/16 06:00
树形控件TreeCtrl的用法作者:idol 2007-11-23 15:15:17 树形控件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/DropTVS_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+--- Parent3HTREEITEM hItem,hSubItem;hItem = m_tree.InsertItem("Parent1",TVI_ROOT);在根结点上添加Parent1hSubItem = 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.Create(IDB_TREE,16,4,#000000);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 在所选中的结点发生改变后发送,所用结构:NMTREEVIEWTVN_ITEMEXPANDED 在某结点被展开后发送,所用结构:NMTREEVIEWTVN_BEGINLABELEDIT 在开始编辑结点字符时发送,所用结构:NMTVDISPINFOTVN_ENDLABELEDIT 在结束编辑结点字符时发送,所用结构:NMTVDISPINFOTVN_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_BEGINLABELEDITvoid CParentWnd::OnBeginEditTree(NMHDR* pNMHDR, LRESULT* pResult){TV_DISPINFO* pTVDI = (TV_DISPINFO*)pNMHDR;if(pTVDI->item.lParam==0);//判断是否取消该操作*pResult = 1;else*pResult = 0;}//处理消息 TVN_BEGINLABELEDITvoid 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的所有消息都需要在父窗口中处理)。
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 铁锅手柄上的铆钉拧不动怎么办 喂完鱼鱼缸上边飘着一层油膜怎么办 铸铁管道横着排的结口漏水怎么办 缤智行李架免打孔螺丝款怎么办 前保险杠和叶子板缝隙大怎么办 新奥拓的大灯调节螺丝滑丝了怎么办 小米手环2计步不准怎么办 小米手环3计步不准怎么办 眼镜用洗发水洗了后模糊怎么办 雷朋近视镜眼镜腿折了怎么办 近视镜眼镜腿断了该怎么办 老师把学生的眼镜打坏了怎么办 生死狙击忘了密保改不了密码怎么办 我叫mt狂猎之弓怎么办 你能利用你的弱点打击你怎么办 研控两相混合伺服电机反转怎么办? 战地一要我升级显卡驱动怎么办 刺客信条兄弟会存档损坏了怎么办 电脑上所有软件和文件被删了怎么办 电脑显示文件已打开无法删除怎么办 金立手机桌面停止运行黑屏怎么办 苹果平板电脑玩游戏黑屏闪退怎么办 电脑开机时显示无法找到入口怎么办 我的世界显示网络玩不了的怎么办啊 网页被设置成不可以到下一页怎么办 小天鹅热水器排污螺丝拧不动怎么办 葡萄霜霉严重叶片开始发焦了怎么办 上海高架gps定位信号差怎么办 老公开车技术不行还非要开怎么办 我偷了同学手机被发现应该怎么办 没满月孩孑4天没大便了怎么办 电机轴总是从皮带轮处断裂怎么办 天花板吊顶里的热水管经常坏怎么办 摩托车油箱下面的废油管漏油怎么办 大修机械压力机轴取不下来怎么办 萌侠传说账号密码没了怎么办 车子前保护杠塑料刮花了怎么办 糖猫电话手表关机了找不到了怎么办 小天才电话手表被洗衣机洗了怎么办 小天才电话手表放洗衣机洗了怎么办 小天才电话手表泡水了怎么办