treectrl:树形控件TreeCtrl来源: 发布时间:星期四, 2009年2月12日 浏览:120次 评论:0
树形Control控件可以用于树形结构其中有个根接点(Root)然后下面有许多子结点而每个子结点上有允许有个或多个或没有子结点MFC中使用CTreeCtrl类来封装树形Control控件各种操作通过BOOLCreate(DWORDdwStyle,constRECT&rect,CWnd*pParentWnd,UINTnID);创建个窗口dwStyle中可以使用以下些树形Control控件专用风格: TVS_HASLINES在父/子结点的间绘制连线 TVS_LINESATROOT在根/子结点的间绘制连线 TVS_HASBUTTONS在每个结点前添加个按钮用于表示当前结点是否已被展开 TVS_EDITLABELS结点显示可以被编辑 TVS_SHOWSELALWAYS在失去焦点时也显示当前选中结点 TVS_DISABLEDRAGDROP不允许Drag/Drop TVS_NOTOOLTIPS不使用ToolTip显示结点显示在树形Control控件中每个结点都有个句柄(HTREEITEM)同时添加结点时必须提供参数是该结点父结点句柄(其中根Root结点只有个既不可以添加也不可以删除)利用 HTREEITEMInsertItem(LPCTSTRlpszItem,HTREEITEMhParent=TVI_ROOT,HTREEITEMhInsertAfter=TVI_LAST);可以添加个结点pszItem为显示hParent代表父结点句柄当前添加结点会排在hInsertAfter表示结点后面返回值为当前创建结点句柄下面代码会建立个如下形式树形结构:+---Parent1+---Child1_1+---Child1_2+---Child1_3+---Parent2+---Parent3/*假设m_tree为个CTreeCtrl对象而且该窗口已经创建*/HTREEITEMhItem,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,nImageListType);指明当前所使用ImageListnImageListType为TVSIL_NORMAL在完成后Control控件中使用图片以设置ImageList中图片为准然后 HTREEITEMInsertItem(LPCTSTRlpszItem,nImage,nSelectedImage,HTREEITEMhParent=TVI_ROOT,HTREEITEMhInsertAfter=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 [Page] 此外CTreeCtrl还提供了些用于得到/修改Control控件状态 HTREEITEMGetSelectedItem;将返回当前选中结点句柄BOOLSelectItem(HTREEITEMhItem);将选中指明结点 BOOLGetItemImage(HTREEITEMhItem,&nImage,&nSelectedImage)/BOOLSetItemImage(HTREEITEMhItem,nImage,nSelectedImage)用于得到/修改某结点所使用图标索引 CStringGetItemText(HTREEITEMhItem)/BOOLSetItemText(HTREEITEMhItem,LPCTSTRlpszItem);用于得到/修改某结点显示 BOOLDeleteItem(HTREEITEMhItem);用于删除某结点BOOLDeleteAllItems;将删除所有结点 此外如果想遍历树可以使用下面: HTREEITEMGetRootItem;得到根结点 HTREEITEMGetChildItem(HTREEITEMhItem);得到子结点 HTREEITEMGetPrevSiblingItem/GetNextSiblingItem(HTREEITEMhItem);得到指明结点上/下个兄弟结点 HTREEITEMGetParentItem(HTREEITEMhItem);得到父结点 树形Control控件消息映射使用ON_NOTIFY宏形式如同:ON_NOTIFY(wNotyCode,id,memberFxn)wNotyCode为通知代码id为产生该消息窗口IDmemberFxn为处理原型如同voidOnXXXTree(NMHDR*pNMHDR,LRESULT*pResult)其中pNMHDR为数据结构在具体使用时需要转换成其他类型结构对于树形Control控件可能取值和对应数据结构为: TVN_SELCHANGED在所选中结点发生改变后发送所用结构:NMTREEVIEW TVN_ITEMEXPANDED在某结点被展开后发送所用结构:NMTREEVIEW TVN_BEGINLABELEDIT在开始编辑结点时发送所用结构:NMTVDISPINFO TVN_ENDLABELEDIT在结束编辑结点时发送所用结构:NMTVDISPINFO TVN_GETDISPINFO在需要得到某结点信息时发送(如得到结点显示)所用结构:NMTVDISPINFO有关ON_NOTIFY有很多内容将在以后内容中进行详细讲解 有关动态提供结点所显示:首先你在添加结点时需要指明lpszItem参数为:LPSTR_TEXTCALLBACK在Control控件显示该结点时会通过发送TVN_GETDISPINFO来取得所需要在处理该消息时先将参数pNMHDR转换为LPNMTVDISPINFO然后填充其中item.pszText但是我们通过什么来知道该结点所对应信息呢我做法是在添加结点后设置其lParam参数然后在提供信息时利用该参数来查找所对应信息下面代码介绍说明了这种思路方法:charszOut[8][3]={\"No.1\",\"No.2\",\"No.3\"};//添加结点HTREEITEMhItem=m_tree.InsertItem(LPSTR_TEXTCALLBACK,...)m_tree.SetItemData(hItem,0);hItem=m_tree.InsertItem(LPSTR_TEXTCALLBACK,...)m_tree.SetItemData(hItem,1);//处理消息voidCParentWnd::OnGetDispInfoTree(NMHDR*pNMHDR,LRESULT*pResult){TV_DISPINFO*pTVDI=(TV_DISPINFO*)pNMHDR;pTVDI->item.pszText=szOut[pTVDI->item.lParam];//通过lParam得到需要显示在中位置*pResult=0;} [Page] 有关编辑结点显示:首先需要设置树形Control控件TVS_EDITLABELS风格在开始编辑时该Control控件将会发送TVN_BEGINLABELEDIT你可以通过在处理中返回TRUE来取消接下来编辑在编辑完成后会发送TVN_ENDLABELEDIT在处理该消息时需要将参数pNMHDR转换为LPNMTVDISPINFO然后通过其中item.pszText得到编辑后并重置显示如果编辑在中途中取消该变量为NULL下面代码介绍说明如何处理这些消息://处理消息TVN_BEGINLABELEDITvoidCParentWnd::OnBeginEditTree(NMHDR*pNMHDR,LRESULT*pResult){TV_DISPINFO*pTVDI=(TV_DISPINFO*)pNMHDR;(pTVDI->item.lParam0);//判断是否取消该操作*pResult=1;*pResult=0;}//处理消息TVN_BEGINLABELEDITvoidCParentWnd::OnBeginEditTree(NMHDR*pNMHDR,LRESULT*pResult){TV_DISPINFO*pTVDI=(TV_DISPINFO*)pNMHDR;(pTVDI->item.pszTextNULL);//判断是否已经取消取消编辑m_tree.SetItemText(pTVDI->item.hItem,pTVDI->pszText);//重置显示*pResult=0;}上面讲述思路方法所进行消息映射必须在父窗口中进行(同样WM_NOTIFY所有消息都需要在父窗口中处理) 0
相关文章读者评论发表评论 |