CTreeCtrl树节点排序,节点复选

合集下载

树控件TREECTRL的使用

树控件TREECTRL的使用

树控件(TREECTRL)的使用通过“FILE->NEW->PROJECTS->MFC AppWizard(EXE)”建立名为VCTREE的工程,在建立过程中选择基于对话框(Dialog based)的应用;将对话框中的默认控件删除,并将所有对话框属性中的Language域设置为Chinese(P.R.C.),以使应用程序支持中文;建立两个图标IDI_PM和IDI_CJ,用来表示图标的选中和非选中状态,对于每个图标都应建立32X32和16X16两种大小,以保证程序的需要;在对话框窗口中添加树控制对象(TREE CONTROL),并设置五个按钮“增加|删除|查看|排序|关闭”,其对应标识分别如下:控制名称标题名称标识符号树控制IDC_TREECTRL按钮增加IDC_ADD删除IDC_DEL查看IDC_VIEW排序IDC_SORT关闭IDOK选中树控制控件,选择“VIEW->ClassWizard->Memory Variables。

IDC_TREECTRL 引入成员变量,其变量类型为:变量名种类变量类型m_TreeCtrl Control C TreeCtrl同时利用“MESSAGES MAP”为各命令按钮增加控制功能函数。

然后在代码文件VCTREEDlg.CPP中分别加入如下控制代码:(1)在文件开始处增加图像列表定义CImageList Cil1,Cil2;//大小图标像列表(2)在初始化文件开始处增加代码BOOL CVCTREEDlg::OnInitDialog(){ CDialog::OnInitDialog();......//原来其它代码// TODO: Add extra initialization here// 此处开始增加代码Cil1.Create(16,16,ILC_COLOR,2,2);Cil1.Add(AfxGetApp()->LoadIcon(IDI_PM));Cil1.Add(AfxGetApp()->LoadIcon(IDI_CJ));m_TreeCtrl.SetImageList(&Cil1,TVSIL_NORMAL); file://设置图象列表DWORDdwStyles=GetWindowLong(m_TreeCtrl.m_hWnd,GWL_STYLE);//获取树控制原风格dwStyles|=TVS_EDITLABELS|TVS_HASBUTTONS|TVS_HASLINES|TVS_L INESATROOT;SetWindowLong(m_TreeCtrl.m_hWnd,GWL_STYLE,dwStyles);//设置风格wchar_t * CJ[4]={L"玉溪卷烟厂",L"云南卷烟厂",L"沈阳卷烟厂",L"成都卷烟厂"};//根数据名称wchar_t * PM[4][5]={{L"红梅一",L"红梅二",L"红梅三",L"红梅四",L"红梅五"},//产品数据项{L"白梅一",L"白梅二",L"白梅三",L"白梅四",L"白梅五"},{L"绿梅一",L"绿梅二",L"绿梅三",L"绿梅四",L"绿梅五"},{L"青梅一",L"青梅二",L"青梅三",L"青梅四",L"青梅五"}};int i,j;HTREEITEM hRoot,hCur;//树控制项目句柄TV_INSERTSTRUCT TCItem;//插入数据项数据结构TCItem.hParent=TVI_ROOT;//增加根项TCItem.hInsertAfter=TVI_LAST;//在最后项之后TCItem.item.mask=TVIF_TEXT|TVIF_PARAM|TVIF_IMAGE|TVIF_SELE CTEDIMAGE;//设屏蔽TCItem.item.pszText="数据选择";TCItem.item.lParam=0;//序号TCItem.item.iImage=0;//正常图标TCItem.item.iSelectedImage=1;//选中时图标hRoot=m_TreeCtrl.InsertItem(&TCItem);//返回根项句柄for(i=0;i<4;i++){//增加各厂家TCItem.hParent=hRoot;TCItem.item.pszText=CJ[i];TCItem.item.lParam=(i+1)*10;//子项序号hCur=m_TreeCtrl.InsertItem(&TCItem);for(j=0;j<5;j++){//增加各产品TCItem.hParent=hCur;TCItem.item.pszText=PM[i][j];TCItem.item.lParam=(i+1)*10+(j+1);//子项序号m_TreeCtrl.InsertItem(&TCItem);}m_TreeCtrl.Expand(hCur,TVE_EXPAND);//展开树}m_TreeCtrl.Expand(hRoot,TVE_EXPAND);//展开上一级树return TRUE; // return TRUE unless you set the focus to a control}(3)增加树项功能的实现在增加树项功能时,除了需要定义和设置插入树项的数据结构之外,还需要注意的是新增树项的名称初始时均为“新增数据”,增加后允许用户给数据项设置自定义名称。

CListCtrl使用详解

CListCtrl使用详解

CListCtrl使用详解CListCtrl使用详解2009年04月07日星期二 10:56 P.M.1。

先来介绍REPORT类型的CListCtrl:首先使用下面的语句设置CListCtrl的style:DWORD SetExtendedStyle( DWORD dwNewStyle );其中LVS_EX_CHECKBOXES 表示添加CheckBoxLVS_EX_FULLROWSELECT 表示选择整行LVS_EX_GRIDLINES 表示添加表格线如果设置了LVS_EX_CHECKBOXES属性,则可以用BOOL GetCheck( int nItem ) const;来得到某一行是否Checked。

可以先用下面的语句来删除以前的东西:for(int k=2;k>=0;k--) //注意要从后往前删,否则出错m_ListCtrl.DeleteColumn(k);m_ListCtrl.DeleteAllItems();用下面的语句新建列:m_ListCtrl.InsertColumn(0,_T("文件名"),LVCFMT_IMAGE|LVCFMT_LEFT);m_ListCtrl.InsertColumn(1,_T("仪器类别"));m_ListCtrl.InsertColumn(2,_T("项目类别"));其中LVCFMT_IMAGE表示可以在第一列加入图标。

如果不要图标可以删去。

然后设置列宽:for(j=0;j<3;j++)m_ListCtrl.SetColumnWidth(j ,100);以下为列表加入图标,如果不需要图标,可以跳过这一步。

注意只在第一次加入,如果多次加入会出错!先在头文件中加入声明:CImageList m_ImageList;这是必要的,如果在cpp的某个函数中加入由于生命期结束,CImageList自动释放,则效果是列表中看不到图标,只看到一个白方块。

MFC树形控件(CTreeCtrl)用法

MFC树形控件(CTreeCtrl)用法

MFC树形控件(CTreeCtrl)用法树形控件可以用于树形的结构,其中有一个根接点(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 hInsertAf ter = TVI_LAST );可以添加一个结点,pszItem为显示的字符,hParent代表父结点的句柄,当前添加的结点会排在hInsertAf ter表示的结点的后面,返回值为当前创建的结点的句柄。

下面的代码会建立一个如下形式的树形结构:+--- Parent1+--- Child1_1+--- Child1_2+--- Child1_3+--- Parent2+--- Parent3/*假设m_tree为一个CTreeCtrl对象,而且该窗口已经创建*/HTREEITEM 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。

树形控件CTreeCtrl的使用详解(一)

树形控件CTreeCtrl的使用详解(一)

树形控件CTreeCtrl的使用详解(一)树型视的三个结构TVINSERTSTRUCT、TVITEM、NMTREEVIEWTVINSERTSTRUCT包含添加新项到树形视控件所使用的信息。

这个结构被TVM_INSERTITEM消息使用。

这个结构与TV_INSERTSTRUCT结构是一样的,但它已经按当前的命名习惯重命名了。

typedef struct tagTVINSERTSTRUCT {HTREEITEM hParent;HTREEITEM hInsertAfter;#if (_WIN32_IE >= 0x0400)union{TVITEMEX itemex;TVITEM item;} DUMMYUNIONNAME;#elseTVITEM item;#endif} TVINSERTSTRUCT, FAR *LPTVINSERTSTRUCT;成员hParent父项的句柄。

如果这个成员的值是TVI_ROOT或NULL,这项将被作为树形控件的根插入。

hInsertAfter插入的新项之后的项的句柄。

或是下列值之一:值意味TVI_FIRST在列表的开始插入项TVI_LAST在列表的最后插入项TVI_ROOT作为一个根项添加TVI_SORT以字母顺序插入项itemex版本4.71。

TVITEMEX包含关于项添加的信息。

itemTVITEM包含关于项添加的信息。

需求Windows NT/2000:需要Windows NT 3.51或更高版本。

Windows 95/98:需要Windows 95或更高版本。

Header:定义在commctrl.h。

TVITEM指定或接收树形视项的属性。

这个结构与TV_ITEM结构一样,但它已经被当前命名协议重新命名了。

新的应用程序应该使用这个结构。

typedef struct tagTVITEM{UINT mask;HTREEITEM hItem;UINT state;UINT stateMask;LPTSTR pszText;int cchTextMax;int iImage;int iSelectedImage;int cChildren;LPARAM lParam;} TVITEM, FAR *LPTVITEM;成员mask指出其它的结构成员哪些包含有效数据的标记数组。

MFC 树形控件CTreeCtrl显示文件路径及文件

MFC 树形控件CTreeCtrl显示文件路径及文件

MFC 树形控件CTreeCtrl显示文件路径及文件在上篇文章中简单讲述了"MFC单文档分割窗口显示图片",但是我想实现的是左边显示图片的路径,右边显示图片的情况,所以这里需要讲述如何使用控件List Control和Tree Control.CListCtrl(列表控件):可以用大图标、小图标、列表、报表四种不同方式显示一组信息.CTreeCtrl(树形控件):用树结构显示一组信息,并能反映这些信息的层次关系.一.CTreeCtrl显示文件路径第一部分新建项目名为"TreeShow"的MFC基于对话框的应用程序.资源视图中修改对话框IDD_TREESHOW_DIALOG,删除"TODO"和按钮,从工具箱中添加Tree Control(左)和List Control控件,设置CTreeCtrl的ID为IDC_TREE,属性Scroll(启动水平垂直滚动)、Horizontal Scroll(具有水平滚动)、Transparent(透明背景)为True.设置CListCtrl的ID为IDC_LIST.如下图:第二部分调用"项目"->"类向导"添加成员变量.在类向导中选择类名"CTreeViewDlg","成员变量"中添加变量:(控件ID-类型-成员)IDC_LIST-CListCtrl-m_list、IDC_TREE-CTreeCtrl-m_tree.添加自定义受保护变量:CImageList-m_ImageList、HTREEITEM-m_hRoot.添加后XXXDlg.h中显示如下:copy1.public:2. CListCtrl m_list; //列表控件 IDC_LIST3. CTreeCtrl m_tree; //树形控件 IDC_TREE4.protected:5. CImageList m_ImageList; //图像列表(相同大小图像集合)6. HTREEITEM m_hRoot; //句柄 CTreeCtrl的根结点"我的电脑"第三部分调用"项目"->"类向导"添加方法.1.在类导向中选择类名"CTreeShowDlg","方法"中点击"添加方法"公有函数void GetLogicalDrives(HTREEITEM hParent).具体代码如下:copy1.//函数功能:获取驱动器参数:路径名2.void CTreeShowDlg::GetLogicalDrives(HTREEITEM hParent)3.{4.//获取系统分区驱动器字符串信息5.size_t szAllDriveStrings = GetLogicalDriveStrings(0,NULL); //驱动器总长度6.char *pDriveStrings = new char[szAllDriveStrings + sizeof(_T(""))]; //建立数组7. GetLogicalDriveStrings(szAllDriveStrings,pDriveStrings);8.size_t szDriveString = strlen(pDriveStrings); //驱动大小9.while(szDriveString > 0)10. {11. m_tree.InsertItem(pDriveStrings,hParent); //在父节点hParent下添加盘符12. pDriveStrings += szDriveString + 1; //pDriveStrings即C:\ D:\ E:\盘13. szDriveString = strlen(pDriveStrings);14. }15.}其中DWORD GetLogicalDriveStrings(DWORD nBuffer,LPTSTR lpBuffer)是Win32 API中获取系统分区信息函数,获取字符,其中包含当前所有逻辑驱动器的根驱动器路径,nBuffer是缓冲区大小,lpBuffer是逻辑驱动器名称字串.该函数将所有盘符信息以lpBuffer返回,如A:\<null>C:\<null>D:\<null><null>两个NULL终止.此时如修改CTreeShowDlg::OnInitDialog()函数,添加相应代码能显示如下(该部分代码后面3将详细讲述):2.同理通过"类向导"添加公有函数void GetDriveDir(HTREEITEM hParent)具体代码如下:copy1.//函数功能:获取驱动盘符下所有子项文件夹2.void CTreeShowDlg::GetDriveDir(HTREEITEM hParent)3.{4. HTREEITEM hChild = m_tree.GetChildItem(hParent); //获取指定位置中的子项5.while(hChild)6. {7. CString strText = m_tree.GetItemText(hChild); //检索列表中项目文字8.if(strText.Right(1) != "\\") //从右边1开始获取从右向左nCount个字符9. strText += _T("\\");10. strText += "*.*";11.//将当前目录下文件枚举并InsertItem树状显示12. CFileFind file; //定义本地文件查找13.BOOL bContinue = file.FindFile(strText); //查找包含字符串的文件14.while(bContinue)15. {16. bContinue = file.FindNextFile(); //查找下一个文件17.if(file.IsDirectory() && !file.IsDots()) //找到文件为内容且不为点"."18. m_tree.InsertItem(file.GetFileName(),hChild); //添加盘符路径下树状文件夹19. }20. GetDriveDir(hChild); //递归调用21. hChild = m_tree.GetNextItem(hChild,TVGN_NEXT); //获取树形控件TVGN_NEXT下兄弟项22. }23.}其中CTreeCtrl::GetNextItem(HTREEITEM hItem,UINT nCode)是MFC中树形控件和列表控件用来获取下一项,常用来遍历.参数hItem是一个tree项的句柄,nCode一个用来指示与hItem的关系的类型的标志.上述代码用到TVGN_NEXT来获取下一个兄弟项.详见GetNextItem.通过AfxMessageBox(strText)打桩输出,可以发现它获取的路径为"C:\*.*",然后为"$360Section\*.*"依次递归遍历;再通过GetNextItem(hChild,TVGN_NEXT)循环输出下一个兄弟项"D:\*.*",递归D盘子项;再到兄弟项E盘等.这就是该部分代码实现的功能.添加相应代码显示如下(该部分代码后面3将详细讲述):3.修改TreeShowDlg.cpp中BOOL CTreeShowDlg::OnInitDialog()初始化函数才能实现显示,添加代码如下:copy1.BOOL CTreeShowDlg::OnInitDialog()2.{3. ...4.// 设置此对话框的图标。

vue+element-ui之tree树形控件有关子节点和父节点之间的各种选中关系详解

vue+element-ui之tree树形控件有关子节点和父节点之间的各种选中关系详解

vue+element-ui之tree树形控件有关⼦节点和⽗节点之间的各种选中关系详解做后端管理系统,永远是最蛋疼、最复杂也最⽋揍的事情,也永远是前端开发⼈员最苦逼、最⽆奈也最尿性的时刻。

蛋疼的是需求变幻⽆穷,如同⼆师兄的三⼗六般变化;复杂的是开发难度⼨步难⾏,如同蜀道难,难于上青天;⽋揍的是产品随⼼所欲、为所欲为,如同村霸横⾏乡⾥、只⼿遮天;苦逼的是前端苦不堪⾔,如同哑巴吃黄连,有苦说不出;⽆奈的是前端⽆可奈何花落去,如同⾄尊宝戴上⾦箍⽆法爱你,摘下⾦箍⽆法救你;尿性的是前端苦尽⽢来,如同唐僧师徒历经九九⼋⼗⼀难,终成正果的⾼光时刻!⼜特么的南辕北辙了,矫情个鸟啊!有需求,上啊,很复杂,想啊,开发周期短,撸起袖⼦加油⼲啊(真特么的下流,⼀天到晚都是上啊,⼲啊,你特么泰迪啊)!好,闲话少叙,⾔归正传,咱们上⼀次讲到⽩眉⼤侠徐良...(你给我滚犊⼦)需求是这样的,有⼀个树形控件,默认所有节点都不选中。

PS:如果贵司的需求没有那么复杂,就可以跳过以下内容,直接使⽤element-ui框架提供的tree树形控件及API即可。

要求:1、选中⽗节点,⼦节点及孙⼦节点(甭管有多少层级,兹要是⼦辈节点)可以不选中,取消选中⽗节点,⼦节点及孙⼦节点也还是没有任何变化;2、选中⼦节点或孙⼦节点,必须选中⽗节点及祖⽗节点(甭管有多少层级,兹要是祖辈节点),取消选中⼦节点或孙⼦节点,⽗节点及祖⽗节点可以不取消选中;3、基于需求2,此时⼦节点及孙⼦节点和⽗节点、祖⽗节点都已选中,那么若取消选中⽗节点,则⼦节点及孙⼦节点必须取消选中,但⽗节点的⽗节点可以不取消选中,若取消选中祖⽗节点,则其下边的所有节点都要取消选中。

看了需求,没有实操,是不是有点懵啊?第⼀次接到这样的需求且⽹上没有这样的解决⽅案,是不是⽆从下⼿啊?来看看实际的效果吧:看了效果,是不是恍然⼤悟?紧接着是不是就觉得既然在某种程度上⽗⼦节点没有关联关系,那还要这种树形控件⼲嘛?恭喜你,抓住重点了!⾸先,为什么我本⼈要⽤这种控件,因为我们的后台管理系统就是⽤的vue+element-ui框架,⽽且element-ui提供了这种树形控件的很多⽅法,⽐如选中⼦节点后要同时获取到该⼦节点的id以及其⽗节点和祖⽗节点的id,再⽐如通过接⼝返回的数据回显已经选中的所有节点,使⽤起来很⽅便的,只是需要熟悉它的API并灵活运⽤罢了。

clistctrl复选框勾选时触发的方法

clistctrl复选框勾选时触发的方法

clistctrl复选框勾选时触发的方法(最新版3篇)篇1 目录1.引言2.CListCtrl 控件简介3.CListCtrl 复选框勾选时触发的方法4.具体实现方法5.总结篇1正文【引言】本文主要介绍如何在 CListCtrl 控件中实现复选框勾选时触发的方法。

CListCtrl 是一个用于显示列表的控件,常用于 Windows 应用程序中。

当用户在 CListCtrl 中选择一个或多个项目时,如何相应地处理这些选择并执行相关操作呢?本文将详细解答这个问题。

【CListCtrl 控件简介】CListCtrl 是一个多功能的列表控件,可以用于显示项目列表,并允许用户进行选择、排序和编辑等操作。

与传统的 ListBox 控件相比,CListCtrl 提供了更多的功能和更强的自定义能力。

【CListCtrl 复选框勾选时触发的方法】在 CListCtrl 中,当用户勾选复选框时,将触发一个消息,该消息可以通过消息处理函数进行处理。

这个消息是 Windows 消息处理机制的一部分,它允许程序员在用户与控件进行交互时执行特定的操作。

【具体实现方法】为了实现 CListCtrl 复选框勾选时触发的方法,需要进行以下步骤:1.创建一个 CListCtrl 控件实例。

2.为 CListCtrl 添加消息处理函数,以便在用户勾选复选框时执行相应的操作。

3.在消息处理函数中,判断用户选择的项目,并执行相应的操作。

例如,可以遍历所选项目,并将它们添加到另一个列表中。

【总结】通过使用 CListCtrl 控件和消息处理函数,可以方便地处理用户在列表中勾选复选框时触发的操作。

篇2 目录1.CListCtrl 控件简介2.CListCtrl 复选框的勾选事件3.实现 CListCtrl 复选框勾选时触发的方法4.总结篇2正文一、CListCtrl 控件简介CListCtrl(列表控件)是 Visual Studio 中的一种常用控件,可以用来显示列表,并允许用户对列表中的项进行选择。

VCMFC中TREE树控件的使用

VCMFC中TREE树控件的使用

VC中树控件的使用树控件可以对数据进行分层显示。

在树控件中,除根节点以外,每个节点都有一个父节点,可以拥有多个兄弟节点和子节点,从而可以是数据以梳妆结构清晰的显示出来。

(树控件图标)一.创建树控件BOOL Create(DWORD dwStyle , const RECT & rect , CWnd * pParentWnd ,UINT nID);dwStyle 控件的风格rect 控件显示区域pParantWnd 父窗口指针nID 命令ID值dwStyle中可以使用以下一些树形控件的专用风格:TVS_HASLINES 在父/子结点之间绘制连线TVS_LINESATROOT 在根/子结点之间绘制连线TVS_HASBUTTONS 在每一个结点前添加一个按钮,用于表示当前结点是否已被展开TVS_EDITLABELS 结点的显示字符可以被编辑TVS_SHOWSELALWAYS 在失去焦点时也显示当前选中的结点TVS_DISABLEDRAGDROP 不允许Drag/DropTVS_NOTOOLTIPS 不使用ToolTip显示结点的显示字符树控件通常和图像列表控件一起使用,在树控件中可以显示图像列表中的图标,即为树控件添加图标。

CImageList * SetImageList(CImageList * pImageList , int nImageListType);pImageList 标识图像列表控件指针nImageListType 标识图像列表类型Eg.m_Tree.Create(TVS_LINESATROOT|TVS_HASLINES|TVS_H ASBUTTONS|WS_BORDER);......m_ImageList.Create(16,16,ILC_COLOR24|ILC_MASK,1,0);......m_Tree.SetImageList(&m_ImageList , LVSIL_NORMAL); 二.向树控件中插入数据在树形控件中每一个结点都有一个句柄(HTREEITEM),同时添加结点时必须提供的参数是该结点的父结点句柄。

mfc ctreeview用法

mfc ctreeview用法

mfc ctreeview用法MFC CTreeView 是Microsoft Foundation Classes(MFC)中的一个类,用于创建和管理树形视图控件。

树形视图控件是一种常用的界面控件,它通常用于展示层级结构的数据,如文件系统,项目组织或数据库表等。

在本文中,我们将一步一步介绍如何使用MFC CTreeView 创建和管理树形视图控件,包括创建视图类,初始化树形视图,添加节点,展开和折叠节点以及响应节点的选择事件等。

第一步:创建视图类首先,在MFC 应用程序中创建一个新的视图类,以用于展示树形视图控件。

可以使用Visual Studio IDE 中的“添加类”功能来创建视图类。

确保选择“CFormView”为基类,并为视图类命名,例如“CTreeViewDemoView”。

第二步:添加树形视图控件到视图中在视图类的头文件中声明一个CTreeView 对象,以用于管理树形视图控件。

可以使用类向导或手动添加以下代码:cppclass CTreeViewDemoView : public CFormView{...CTreeView m_treeView;...};然后,在视图类的初始化过程中,创建树形视图控件并将其添加到视图中。

可以在OnInitialUpdate 方法中添加以下代码:cppvoid CTreeViewDemoView::OnInitialUpdate(){CFormView::OnInitialUpdate();初始化树形视图控件CRect rect;GetClientRect(&rect);m_treeView.Create(WS_VISIBLE WS_CHILD TVS_HASLINES TVS_LINESATROOT TVS_HASBUTTONS, rect, this, 0);...}第三步:初始化树形视图在树形视图控件创建并添加到视图中后,我们需要初始化树形视图的数据。

QTreeWidget复选框checkbox使用

QTreeWidget复选框checkbox使用

QTreeWidget复选框checkbox使⽤使⽤QTreewidget时,⽤到复选框。

还有⼀个苛刻的要求,即在选中或取消选中时,还要做⼀些操作。

刚开始参考了⽹上的⼀些⽅法,参考了,使⽤itemChange(QTreeWidgetItem*,int)信号,可以实现,但是不满⾜我个⼈的需求:我在点选时,要在事件中做其他操作,⽽每个节点的checkbox状态改变时,itemChange都会被触发,如我的例⼦中,我选中⽬标1时,⽬标1的所有⼦节点会被选中,如果有3个⼦节点,⼀共会触发3+1次itemChange,这不是我想看到的。

所以,我尝试使⽤另⼀种⽅法,期望满⾜条件。

本⽂只是在学习的层⾯讨论,不讨论⽅法优劣。

时刻抱持实⽤主义的观点,不管⽩猫⿊猫,只要捉住⽼⿏就是好猫。

头⽂件:1 #ifndef MYDLG_H2#define MYDLG_H34 #include <QDialog>5 #include <QTreeWidget>6 #include <map>7using namespace std;89namespace Ui {10class MyDlg;11 }1213class MyDlg : public QDialog14 {15 Q_OBJECT1617public:18explicit MyDlg(QWidget *parent = 0);19 ~MyDlg();2021private slots:22void on_btnQuit_clicked();23void TreeItemClicked(QTreeWidgetItem* item, int col);24private:25 Ui::MyDlg *ui;26 map<QTreeWidgetItem*, Qt::CheckState> m_mapItemState;272829void InitTree();//初始化30//添加节点31 QTreeWidgetItem* AddTreeItem(QTreeWidget* pTree, QTreeWidgetItem* parentItem, QString itemTxt);32//获取当前的所有checkbox状态,和选中的节点33void GetCheckItem(QTreeWidget* pTree, QList<QString>& listTarget);34void ChangeChildItemState(QTreeWidgetItem* thisItem);//根据点击的节点,来改变节点的⼦节点状态35void ChangeParentItemState(QTreeWidgetItem* thisItem);//根据点击的节点,来改变节点的⽗节点状态36//获取节点的上次状态37 Qt::CheckState GetItemState(QTreeWidgetItem* item, map<QTreeWidgetItem*, Qt::CheckState>& mapItemState);3839 };4041#endif// MYDIALOG_H源⽂件:1 #include "MyDlg.h"2 #include "ui_MyDlg.h"3 #include <QDebug>45 MyDlg::MyDlg(QWidget *parent) :6 QDialog(parent),7 ui(new Ui::MyDlg)8 {9 ui->setupUi(this);10 InitTree();1112//⾸次获得节点状态13 QList<QString> list;14 GetCheckItem(ui->treeWidget, list);15 }1617 MyDlg::~MyDlg()18 {19delete ui;20 }2122void MyDlg::on_btnQuit_clicked()23 {2425 }2627void MyDlg::TreeItemClicked(QTreeWidgetItem *item, int col)28 {29if(item->checkState(0) == GetItemState(item, m_mapItemState))//item状态是否改变30return;31 ChangeChildItemState(item);32 ChangeParentItemState(item);33 QList<QString> listTarget;34 GetCheckItem(ui->treeWidget, listTarget);35 qDebug() << listTarget;3637 }3839void MyDlg::InitTree()40 {41 connect(ui->treeWidget, SIGNAL(itemClicked(QTreeWidgetItem*,int)), this, SLOT(TreeItemClicked(QTreeWidgetItem*,int)));42 ui->treeWidget->header()->setHidden(1);43 QTreeWidgetItem* topItem = new QTreeWidgetItem;44 topItem->setCheckState(0, Qt::Unchecked);45 topItem->setText(0, "⽬标列表");46 ui->treeWidget->addTopLevelItem(topItem);47 QTreeWidgetItem* item1 = AddTreeItem(ui->treeWidget, topItem, "⽬标1");48 QList<QString> listTarget;49 listTarget << "⽬标11" << "⽬标12";50for(int i = 0; i < listTarget.count(); i++){51 AddTreeItem(ui->treeWidget, item1, listTarget.at(i));52 }5354 QTreeWidgetItem* item2 = AddTreeItem(ui->treeWidget, topItem, "⽬标2");55 listTarget.clear();56 listTarget << "⽬标21" << "⽬标22" << "⽬标23";57for(int i = 0; i < listTarget.count(); i++){58 AddTreeItem(ui->treeWidget, item2, listTarget.at(i));59 }6061 QTreeWidgetItem* item3 = AddTreeItem(ui->treeWidget, topItem, "⽬标3");62 listTarget.clear();63 listTarget << "⽬标31" << "⽬标32" << "⽬标33" << "⽬标34";64for(int i = 0; i < listTarget.count(); i++){65 AddTreeItem(ui->treeWidget, item3, listTarget.at(i));66 }6768 ui->treeWidget->expandAll();69 }7071 QTreeWidgetItem *MyDlg::AddTreeItem(QTreeWidget *pTree, QTreeWidgetItem *parentItem, QString itemTxt)72 {73 QTreeWidgetItem *item = new QTreeWidgetItem(parentItem);74 item->setFlags(item->flags() | Qt::ItemIsUserCheckable);75 item->setCheckState(0, Qt::Unchecked);76 item->setText(0, itemTxt);77return item;78 }7980void MyDlg::GetCheckItem(QTreeWidget *pTree, QList<QString> &listTarget)81 {//这个本来是为了获取选中的节点⽂本。

简单但完整的树形列表+多选(复选)框实现方式

简单但完整的树形列表+多选(复选)框实现方式

简单但完整的树形列表+多选(复选)框实现⽅式多级分类通常做成树形的,如果分类是单选的,只要递归返回树形结构,⽤下拉列表显⽰就ok了。

当分类要求多选的时候,我们需要给每个分类都加上复选框。

在⾥TreeView可以显⽽易见的做到这个,然⽽TreeView服务端控件不但⽣成⽐较ugly的html代码,⽽且所需写代码的时候其实也并不是最少。

下⾯给出我的⼀个简单(代码数较少)但是完整的实现⽅式,除了显⽰,还包括取得选中值以及对树形列表赋值。

需要达到的效果如下,点击⼀个span可展开或收起树形列表。

我选择⽤ul显⽰树形列表,这也是⼀个常⽤的⽅式。

下⾯是aspx页⾯的代码,⽤jquery编写相关的脚本。

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="/1999/xhtml"><head runat="server"><title></title><style type="text/css">body { font-size: 12px; font-family: Verdana, 微软雅⿊; }ul { margin: 0px 10px; padding: 0px 10px; list-style: none; }li { line-height: 16px; }</style><script src="Scripts/jquery.js" type="text/javascript"></script><script type="text/javascript">//选中itemList⾥的保存Id的Checkboxfunction checkItems(nodeName, itemList) {var arr = itemList.split(',');$.each(arr, function (i, n) {$("#" + nodeName + "-" + arr[i]).attr("checked", "checked");});}$(function () {//点击展开或收起树形列表$("#spCategory").click(function (event) {event.stopPropagation();var offset = $(this).offset();$('#ulCategory').css({ left: offset.left, top: offset.top + 30 }).toggle();});//取消弹出层本⾝冒泡事件$("#ulCategory").click(function (event) { event.stopPropagation(); });//点击页⾯其他位置使弹出层消失$(document).click(function () { $("#ulCategory").hide(); });});</script></head><body><span id="spCategory" style="border: solid 1px silver; line-height: 25px; padding: 3px 5px; cursor: pointer; float: left;">点击这⾥展开或收起分类</span><ul id="ulCategory" style="position: absolute; background-color: ActiveCaption; display: none;"><asp:Literal ID="ltrCategory" runat="server"></asp:Literal></ul></body></html>后台cs代码如下,主要是返回树形结构。

TreeView控件实现按Ctrl和Shift键多选功能

TreeView控件实现按Ctrl和Shift键多选功能

TreeView控件实现按Ctrl和Shift键多选功能继上次后继续对TreeView控件,这次实现的功能是树节点可以按Ctrl/Shift键多选和树节点的拖动。

相对于上次的代码,这次主要新增加也以下⼏个属性和⽅法:IsMultiSelect属性:树是否需要使⽤多选功能SelectedNodeList属性:多选时被选中的节点的集合TreeNodeCanAcceptDragedHandler事件:拖动时⽤来判断⽬标节点是否接受拖动IsNodeCanAcceptDragHandler事件:拖动成功后要执⾏的事件,⼀般⽤来将新的关系持久化到数据库或其它地⽅。

实现⽐较简单,各位直接看代码吧。

扩展树的代码using System;using System.Collections.Generic;using ponentModel;using System.Drawing;using System.Windows.Forms;using GADPlatSystem.Navigate;namespace GADPlatSystem.Tools{///<summary>///导航树控件///</summary>[DesignTimeVisible(true)][Serializable]public class GTreeView : TreeView{#region成员变量///<summary>///存储多选时选择的节点///</summary>private IList<TreeNode> selectedNodeList = new List<TreeNode>();///<summary>///当前节点///</summary>private TreeNode currentNode = null;#endregion#region属性///<summary>///是否是多选///</summary>public bool IsMultiSelect { get; set; }///<summary>///选择的节点的集合///</summary>public IList<TreeNode> SelectedNodeList{get { return selectedNodeList; }}#endregion#region Delegate & Event///<summary>///节点被拖动后要处理事件的Delegate///</summary>///<param name="sourceNode">被拖动的节点</param>///<param name="targetNode">⽬标节点</param>public delegate void OnDragNodeSucceed(TreeNode sourceNode, TreeNode targetNode);///<summary>///判断⽬标节点是否接受拖动的Delegate///</summary>///<param name="targetNode"></param>///<returns></returns>public delegate bool IsNodeCanAcceptDrag(TreeNode targetNode);///<summary>///节点被拖动后要处理事件///</summary>public event OnDragNodeSucceed TreeNodeCanAcceptDragedHandler;///<summary>///判断⽬标节点是否接受拖动的事件处理///</summary>public event IsNodeCanAcceptDrag IsNodeCanAcceptDragHandler;#endregion#region类函数///<summary>///构造函数///</summary>public TreeViewExt(): base(){this.DrawMode = TreeViewDrawMode.OwnerDrawText;}///<summary>///⿏标单击事件///</summary>///<param name="e">TreeNodeMouseClickEventArgs对象类</param>protected override void OnNodeMouseClick(TreeNodeMouseClickEventArgs e){this.SelectedNode = e.Node;var isSingleSelected = false;// 如果是多选,则根据按钮情况设置节点的选择状态if (IsMultiSelect){if (!(SelectedNodeList.Count == 1 && SelectedNodeList[0] == SelectedNode)){if ((Control.ModifierKeys & Keys.Control) != 0 || e.Button == MouseButtons.Right){ctrlMultiSelectNodes(SelectedNode, e.Button == MouseButtons.Right);}else if ((Control.ModifierKeys & Keys.Shift) != 0){shiftMultiSelectNodes(SelectedNode, e.Button == MouseButtons.Right);}else{isSingleSelected = true;singleSelectNode(SelectedNode);}}isSingleSelected = true;}else{singleSelectNode(SelectedNode);setCurrentNode(SelectedNode);}this.Invalidate();}///<summary>///重绘,主要是在Checkbox/RadioButton前⾯有图⽚///</summary>///<param name="e">DrawTreeNodeEventArgs对象类</param>protected override void OnDrawNode(DrawTreeNodeEventArgs e){if (e.Bounds.X == -1)return;e.DrawDefault = false;Font font = this.Font;if (e.Node.NodeFont != null) font = e.Node.NodeFont;Color color = this.ForeColor;if (SelectedNodeList.Contains(e.Node)){color = SystemColors.HighlightText;}else if (e.Node.ForeColor != Color.Empty){color = e.Node.ForeColor;}Graphics g = e.Graphics;Rectangle textBounds = new Rectangle();GTreeNode extNode = e.Node as GTreeNode;textBounds.X = e.Bounds.X;textBounds.Y = e.Bounds.Y;textBounds.Width = e.Bounds.Width;textBounds.Height = e.Bounds.Height;// 绘制节点的⽂本if (SelectedNodeList.Contains(e.Node)){g.FillRectangle(SystemBrushes.Highlight, textBounds);ControlPaint.DrawFocusRectangle(g, textBounds, color, SystemColors.Highlight);TextRenderer.DrawText(g, e.Node.Text, font, textBounds, color, TextFormatFlags.Default); }else{g.FillRectangle(SystemBrushes.Window, textBounds);TextRenderer.DrawText(g, e.Node.Text, font, textBounds, color, TextFormatFlags.Default); }}//控件初始化private void InitializeComponent(){this.SuspendLayout();//// GTreeViewExt//this.Indent = 25;this.ItemHeight = 25;this.ResumeLayout(false);}#endregion#region⿏标拖动节点移动///<summary>///拖动节点移动,在⿏标拖放操作结束时发⽣///</summary>///<param name="drgevent">DragEventArgs对象</param>protected override void OnDragDrop(DragEventArgs drgevent){base.OnDragDrop(drgevent);var moveNode = (TreeNode)drgevent.Data.GetData(typeof(TreeNode));//根据⿏标坐标确定要移动到的⽬标节点Point point = this.PointToClient(new Point(drgevent.X, drgevent.Y));var targetNode = this.GetNodeAt(point);// 如果⽬标节点不接受拖动,则返回if (IsNodeCanAcceptDragHandler != null){if (!IsNodeCanAcceptDragHandler(targetNode)){return;}}// 确定落下的节点不是被拖拽节点本⾝或者被拖拽节点的⼦节点if (!moveNode.Equals(targetNode) && !containsNode(moveNode, targetNode)) {var newMoveNode = (TreeNode)moveNode.Clone();targetNode.Nodes.Insert(targetNode.Index, newMoveNode);//更新当前拖动的节点选择this.SelectedNode = newMoveNode;//移除拖放的节点moveNode.Remove();moveNode = newMoveNode;newMoveNode.Expand();if (TreeNodeCanAcceptDragedHandler != null){TreeNodeCanAcceptDragedHandler(moveNode, targetNode);}}}///<summary>///拖动节点移动,在⽤⿏标将某项拖动到该控件的⼯作区时发⽣///</summary>///<param name="drgevent">DragEventArgs对象</param>protected override void OnDragEnter(DragEventArgs drgevent){base.OnDragEnter(drgevent);if (drgevent.Data.GetDataPresent(typeof(TreeNode))){drgevent.Effect = DragDropEffects.Move;}else{drgevent.Effect = DragDropEffects.None;}}///<summary>///拖动节点移动,在⽤户开始拖动项时发⽣///</summary>///<param name="e">ItemDragEventArgs对象</param>protected override void OnItemDrag(ItemDragEventArgs e){base.OnItemDrag(e);if (e.Button == MouseButtons.Left){DoDragDrop(e.Item, DragDropEffects.Move);}}#endregion⿏标拖动节点移动#region Private Methods///<summary>///按ctrl键多选的⽅法///</summary>///<param name="node"></param>///<param name="mustSelect"></param>private void ctrlMultiSelectNodes(TreeNode node, bool mustSelect){if (SelectedNodeList.Contains(node) && !mustSelect){SelectedNodeList.Remove(node);setCurrentNode((TreeNode)SelectedNodeList[SelectedNodeList.Count - 1]);}else if (!mustSelect){SelectedNodeList.Add(node);setCurrentNode(node);}}///<summary>///按shift键多选的⽅法///</summary>///<param name="node"></param>///<param name="mustSelect"></param>private void shiftMultiSelectNodes(TreeNode node, bool mustSelect){if (mustSelect){return;}if (SelectedNodeList.Contains(node)){SelectedNodeList.Remove(node);setCurrentNode((TreeNode)SelectedNodeList[SelectedNodeList.Count - 1]);}else{if (node.Parent == currentNode.Parent){TreeNode addNode = node;for (int i = System.Math.Abs(currentNode.Index - node.Index); i > 0; i--){if (!SelectedNodeList.Contains(addNode)){SelectedNodeList.Add(addNode);}addNode = currentNode.Index > node.Index ? addNode.NextNode : addNode.PrevNode; }setCurrentNode(node);}else{singleSelectNode(SelectedNode);}}}///<summary>/// single select///</summary>///<param name="node"></param>private void singleSelectNode(TreeNode node){SelectedNodeList.Clear();SelectedNodeList.Add(node);setCurrentNode(node);}///<summary>/// Set current node///</summary>///<param name="node"></param>private void setCurrentNode(TreeNode node){//if (isMulSelect)// SelectedNode = null;if (currentNode != node){currentNode = node as TreeNode;}}///<summary>///确定⼀个节点是否是另⼀个节点的祖先节点///</summary>///<param name="parentNode"></param>///<param name="childNode"></param>///<returns></returns>private bool containsNode(TreeNode parentNode, TreeNode childNode){if (childNode.Parent == null) return false;if (childNode.Parent.Equals(parentNode)) return true;return containsNode(parentNode, childNode.Parent);}#endregion}}使⽤⽰例private void Form1_Load(object sender, EventArgs e){var gTreeView1 = new GTreeViewExt();gTreeView1.AllowDrop = true;gTreeView1.IsMultiSelect = true;gTreeView1.TreeNodeDragedHandler += (source, target) =>{ listBox1.Items.Add("将" + source.Text + "拖动到了" + target.Text); };for (int i = 0; i < 10; i++){var cNode = new TreeNode();cNode.Tag = i;cNode.Text = "Node" + i;cNode.ImageIndex = 0;cNode.SelectedImageIndex = 0;gTreeView1.Nodes.Add(cNode);for (int j = 0; j < i; j++){var innerNode = new TreeNode();innerNode.Tag = i;innerNode.Text = "InnerNode" + i + "-" + j; innerNode.ImageIndex = 0;innerNode.SelectedImageIndex = 0;cNode.Nodes.Add(innerNode);}}gTreeView1.ExpandAll();gTreeView1.Width = 400;gTreeView1.Dock = DockStyle.Left;Controls.Add(gTreeView1);}。

VC中使用CTreeCtrl实现目录树

VC中使用CTreeCtrl实现目录树

VC中使用CTreeCtrl实现目录树这是师姐给偶的寒假任务,前面一直没看,快开学了搞了一天也算实现了要的功能(其实就是修正别人的程序不能实现同步选取功能,选了父目录的话其他子目录也同样处于被选取状态)。

程序代码主要来自网络上的VCHelper程序。

这里还是从头叙述操作全过程,也好给自己留下深刻映像。

首先新建MFC工程,在对话框中添加CTreeCtrl控件,并关联变量CtreectrlCTreeCtrl m_treectrl;如果需要选择框,要将控件的复选框勾上。

并定义成员变量 HTREEITEM m_hTreeItemRoot,方便函数调用。

然后就是初始化目录树了。

这里主要分为三部:设置树选项添加硬盘目录添加目录文件夹SetTreeListStyle();m_hTreeItemRoot = m_treectrl.InsertItem("我的电脑",NULL,NULL);///root就是节点的标题GetLogicalDrives( m_hTreeItemRoot );GetDriveDir( m_hTreeItemRoot );m_treectrl.Expand( m_hTreeItemRoot, TVE_EXPAND );各函数代码如下:设置参数void CVctestView::SetTreeListStyle(){DWORD dwStyle = GetWindowLong( m_treectrl.m_hWnd, GWL_STYLE );dwStyle |= TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT;SetWindowLong( m_treectrl.m_hWnd, GWL_STYLE, dwStyle );}获取盘符void CVctestView::GetLogicalDrives(HTREEITEM hParent){ASSERT( hParent );DWORD dwAllDriveStrings = GetLogicalDriveStrings( 0, NULL );ASSERT( dwAllDriveStrings >= 1 );LPTSTR lpDriveStrings = NULL;lpDriveStrings = new TCHAR[ dwAllDriveStrings + sizeof( _T( "" ) ) ];ASSERT( lpDriveStrings != NULL );// Save the original address for the drive strings...LPTSTR lpTmp = lpDriveStrings;GetLogicalDriveStrings( dwAllDriveStrings, lpDriveStrings );size_t szDriveString = lstrlen( lpDriveStrings );while ( szDriveString > 1 ){HTREEITEM tHTR = m_treectrl.InsertItem( lpDriveStrings, hParent );//m_treectrl.SetCheck(tHTR, 1);lpDriveStrings += szDriveString + 1;szDriveString = lstrlen( lpDriveStrings );}lpDriveStrings = lpTmp;if ( lpDriveStrings ){delete lpDriveStrings;lpDriveStrings = NULL;}ASSERT( lpDriveStrings == NULL );}获取第一层目录void CVctestView::GetDriveDir(HTREEITEM hItem){ASSERT( hItem );HTREEITEM hChild = m_treectrl.GetChildItem( hItem );while ( hChild ){CString strDir = m_treectrl.GetItemText( hChild );if ( strDir.Right( 1 ) != _T( "\\" ) )strDir += _T( "\\" );strDir += _T( "*.*" );CFileFind file;BOOL bContinue = file.FindFile( strDir );while ( bContinue ){bContinue = file.FindNextFile();if ( file.IsDirectory() && ! file.IsDots() ){HTREEITEM tHTR = m_treectrl.InsertItem( file.GetFileName(), hChild ); m_treectrl.SetCheck( tHTR, m_treectrl.GetCheck(hChild));}}GetDriveDir( hChild );hChild = m_treectrl.GetNextItem( hChild, TVGN_NEXT );}}前面函数添加完后应该可以显示第一层目录了。

CTreeCtrl树节点排序,节点复选

CTreeCtrl树节点排序,节点复选

CTreeCtrl树节点排序,节点复选效果描述:该功能可使某义节点下的全部子节点按某种序列重新排列SortChildren是为该结点下面的所有子节点排序,注意只是子节点,不包括子节点的子节点。

SortChildrenCB是自定义排序方式。

现给出大体例子SortChildrenCB中的TVSORTCB需要用到一个回调函数常常是难点。

INT CHvrTree::SortItem(HTREEITEM hItem){BOOL bRet;CHvrTree *ptree = this;TVSORTCB sortpage;g_pLogger->Debug("<%s(%d)> SortItem():Enter",D_PC_LOG_NAME_HVRTREE, __LINE__);///////////////////////////////////////////////////////////////// /////////// ソーティング情報g_pLogger->Info("<%s(%d)> SortItem(): ソーティングノード,hItem - %08x",D_PC_LOG_NAME_HVRTREE, __LINE__,hItem );sortpage.hParent = hItem;sortpage.lpfnCompare = MyCompareProc;sortpage.lParam = (LPARAM)ptree;bRet = SortChildrenCB(&sortpage);if ( bRet ){g_pLogger->Debug("<%s(%d)> SortItem():Leave",D_PC_LOG_NAME_HVRTREE, __LINE__);return D_PC_SUCCESS;}else{g_pLogger->Debug("<%s(%d)> SortItem():Leave",D_PC_LOG_NAME_HVRTREE, __LINE__);return D_PC_FAILURE;}}入口参数是两个在要排序的序列中的无序参数INT CALLBACK CHvrTree::MyCompareProc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort){CHvrTree* pTreeCtrl = (CHvrTree*) lParamSort;HTREEITEM hItem1 = (HTREEITEM)lParam1;HTREEITEM hItem2 = (HTREEITEM)lParam2;// ノードのアイコンに付けられた固有の番号によって、ノードタイプ取得INT nKind1 = pTreeCtrl->GetItemType(hItem1);INT nKind2 = pTreeCtrl->GetItemType(hItem2);// 1.01 : カテゴリソーティングを機能修正///////////////////////////////////////////////////////////////// /////////// ノードタイプ取得チェックif ( (nKind1<0)||(nKind2<0) ){g_pLogger->Error( "<%s(%d)> MyCompareProc: 目標ノードノードタイプ情報取得できない, nType - %d",D_PC_LOG_NAME_HVRTREE, __LINE__,D_PC_FAILURE );return D_PC_ERRCODE_HVRTREE_GETTREE_FAIL;}// 1.01 - END// ノード情報取得BOOL bRet;ST_TREE_NODE *pnodeInfo1 = NULL; // ノード1の情報 ST_TREE_NODE *pnodeInfo2 = NULL; // ノード2の情報bRet = pTreeCtrl->m_mapNode.Lookup(hItem1,(void*&)pnodeInfo1); // ノード1の情報取得if(bRet == FALSE){// 目標ノード情報取得できないg_pLogger->Error( "<%s(%d)> MyCompareProc: 目標ノード情報取得できない, hItem - %08x",D_PC_LOG_NAME_HVRTREE, __LINE__, hItem1 );return D_PC_ERRCODE_HVRTREE_GETTREE_FAIL;}bRet = pTreeCtrl->m_mapNode.Lookup(hItem2,(void*&)pnodeInfo2); // ノード2の情報取得if(bRet == FALSE){// 目標ノード情報取得できないg_pLogger->Error( "<%s(%d)> MyCompareProc: 目標ノード情報取得できない, hItem - %08x",D_PC_LOG_NAME_HVRTREE, __LINE__, hItem2 );return D_PC_ERRCODE_HVRTREE_GETTREE_FAIL;}INT nRet = NULL; // 戻り値if( nKind1 == nKind2){// ノード1とノード2は同じノードタイプの場合// ノード1とノード2はカテゴリーノードの場合if( nKind1 == D_PC_NODE_CATE_1){CString strItem1,strItem2;// カテゴリー名取得strItem1 = pTreeCtrl->GetItemText(hItem1);strItem2 = pTreeCtrl->GetItemText(hItem2);// カテゴリー名比較nRet = strcmp(strItem1, strItem2);}// 1.01 : カテゴリソーティングを機能修正else if( nKind1 == D_PC_NODE_CATE_2){CString strItem1,strItem2;// カテゴリー名取得strItem1 = pTreeCtrl->GetItemText(hItem1);strItem2 = pTreeCtrl->GetItemText(hItem2);// カテゴリー名比較nRet = strcmp(strItem1, strItem2);}// 1.01 - ENDelse if( nKind1 == D_PC_NODE_CAM ){// ノード1とノード2はカメラノードの場合// カメラ番号取得INT nCamId1 = pnodeInfo1->Id;INT nCamId2 = pnodeInfo2->Id;// カメラ番号比較nRet = nCamId1 - nCamId2;}else if( nKind1 == D_PC_NODE_HVR ){// ノード1とノード2は物件ノードの場合ST_HVR_INFO hvrInfo1, hvrInfo2;CString strItem1, strItem2;// 物件番号取得INT nHvrId1 = pnodeInfo1->Id;INT nHvrId2 = pnodeInfo2->Id;// 物件情報取得g_hvrUser.GetHvrInfo(nHvrId1, &hvrInfo1);g_hvrUser.GetHvrInfo(nHvrId2, &hvrInfo2);// 1.05 : 物件の順機能修正// 物件カナ名取得strItem1.Format("%s",hvrInfo1.szKana);strItem2.Format("%s",hvrInfo2.szKana);// 物件カナ名比較nRet = CCheckWord::CompareValidKataName( strItem1, strItem2 );if (nRet == 0){if (nHvrId1 > nHvrId2){nRet = 1;}else{nRet = -1;}}// 1.05 - END}else{// 他の場合nRet = NULL;}}else{// ノード1とノード2は違いノードタイプの場合nRet = nKind1 - nKind2;}return nRet;}GetItemType是获得结点状态即它的图标,主要是利用了GetItemImage得到其图标复选重绘有时可能会用到复选操作,即点击一个结点时该结点和另一个结点同时被选中(如其父结点)可使用系统消息OnCustomDraw,该消息须手动添加该功能的实质是:先把要选则的所有节点刷上颜色,再到调用时如单击或双击事件把不需要的颜色去掉virtual void OnCustomDraw(NMHDR *pHdr, LRESULT *pResult);BEGIN_MESSAGE_MAP(CHvrTree, CTreeCtrl)ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnCustomDraw)//}}AFX_MSG_MAPEND_MESSAGE_MAP()void CHvrTree::OnCustomDraw(NMHDR *pHdr, LRESULT *pResult) {LPNMLVCUSTOMDRAW lplvcd = (LPNMLVCUSTOMDRAW)pHdr;INT nState;switch(lplvcd->nmcd.dwDrawStage){case CDDS_PREPAINT:* pResult= CDRF_NOTIFYITEMDRAW;break;// アイテムが描画される前case CDDS_ITEMPREPAINT:nState = lplvcd->nmcd.uItemState;if((nState == (CDIS_FOCUS|CDIS_SELECTED)) || (nState ==CDIS_SELECTED) ){lplvcd->clrTextBk = D_PC_DEV_ADD_BLACK_BRUSH;// アイテムの文字色を設定lplvcd->clrText = D_PC_DEV_LIST_RUN_COLOR;* pResult= CDRF_DODEFAULT;break;}else{* pResult= 0;break;}default:* pResult = 0;break;}}判断结点状态可使用GetItemState。

CTreeCtrl的用法

CTreeCtrl的用法

1.取得或设定项目的信息.BOOL CTreeCtrl::GetItem(TV_ITEM* pItem);BOOL CTreeCtrl::SetItem(TV_ITEM* pItem);BOOL CTreeCtrl::SetItem(HTREEITEM hItem,UINTnMask,LPCTSTR lpszItem,int Image,int nSelectedImage,UINT nState,UINTnStateMask,LPARAME lParam);2.取得与设定项目的状态UINT CTreeCtrl::GetItemState(HTREEITEM hItem,UINT sStateMask)const; BOOL CTree Ctrl::SetItemState(HTREEITEM hItem,UINT nState,UINT nStateMask);3.取得与设定项目的图形BOOL CTreeCtrl::GetItemImage(HTREEITEM hItem,int& nImage,int& nSelectedImage)const;BOOL CTreeCtrl::SetItemImage(HTREEITEM hItem,int nImage,int nSelectedImage);4. 取得与设定项目的文本CString CTreeCtrl::GetItemText(HTREEITEM,hItem)const;BOOL CTreeCtrl::SetItemText(HTREEITEM hItem,LPCTSTR lpszItem);5. 查询CTreeCtrl 中项目的个数UINT CTreeCtrl::GetCount();6.查询hItem 的父项目的句柄HTREEITEM CTreeCtrl::GetparenItem(HTREEITEM hItem);7.查询hItem是否有子项BOOL CTreeCtrl::ItemHasChildren(HTREEITEM hItem);8.取得hItem 第一个子项的句柄HTREEITEM CTreeCtrl::GetChildItem(HTREEITEM hItem);9.查询排在hItem前后的兄弟项HTREEITEM CTreeCtrl::GetPrevSiblingItem(HTREEITEM hItem); HTREEITEM CTreeCtrl::GetNextSiblingItem(HTREEITEM hItem);10.取得选中项的句柄取得根项的句柄HTREEITEM CTreeCtrl::GetSelectedItem();HTREEITEM CTreeCtrl::GetRootItem();HTREEITEM hItem=GetRootItem(); //获取根结点,可能会有多个根结点ItemHasChildren(hParent) //判断结点是否有孩子结点hItem=GetChildItem(hParent); //获取第一个子结点hItem=GetNextSiblingItem(hItem)); //获取下一个兄弟结点结点Expand(hItem,bExpand?TVE_EXPAND:TVE_COLLAPSE);//展开/叠起结点Select(hItem,TVGN_FIRSTVISIBLE); //设置选中结点CString str=GetItemText(hChild); //获取结点字符串信息HTREEITEM hCurrSel = GetSelectedItem(); //获取当前选中结点SelectItem(hNewSel);HTREEITEM hNewSel = HitTest(pt, &nFlags); //判断坐标是否在当前结点范围内HTREEITEM hItem=InsertItem(dlg.m_strItemText,hItemParent); //插入结点。

支持数据项查找功能的树控制(CTreeCtrl)类

支持数据项查找功能的树控制(CTreeCtrl)类

支持数据项查找功能的树控制(CTreeCtrl)类作者:许超下载本文示例源代码代码运行效果图如下:一、树控制(CTree C ontr ol)树控制用于显示具有一定层次结构的数据项。

很多应用程序都使用该控件,例如资源管理器中的磁盘目录等。

树控制中有根数据项(root item),根数据项下包含各个子数据项(c hild item)。

根数据项是所有子数据项的父亲,而这些子数据项是根数据项的孩子。

所有子数据项互为兄妹(s ibling)关系。

每个数据项包括数据项名称(文本字符串)和用于表示该数据项的图像,每个数据项下还可以包含子项,整个结构就象一棵树。

二、使用树控制在MF C中,树控制被封装成CT ree Ct rl类。

下面我们谈谈树控制的创建、属性和操作方法。

(1)树控制的创建树控制一般用于对话框程序。

创建树控制有两种方法,一种是静态创建,一种是动态创建。

静态创建是指拖放控件后声明与之相关的成员变量来操作树控制。

在对话框程序界面上拖放一个CT ree Ct rl控件,然后通过C lassW iza rd添加一个CT reeC trl类型的成员变量并在程序中使用它。

动态创建是指在程序中使用C re ate函数创建树控制对象。

本文例子采用静态创建的方法。

(2)树控制的属性树控制有很多属性操作函数。

使用这些函数可以得到树控制的各种属性信息。

例如:取得树控制中项数G etC ount、取得树控制中项相对于父项的偏移值Ge tInde nt、取得树控制图像列表控制句柄G etImageLis t等。

具体信息可以查看M SD N帮助。

(3)数控制的操作树控制的操作方法包括插入一个树项I nse rtItem、删除一个树项De leteItem、删除所有树项D e le teA llI tems、展开或合拢树项的子项Expa nd、选中特定树项Se lectIt em、选择一个树项作为第一个可视树项Se le ct SetF irs tV is ib le、编辑一个可视的树项Edit La be l和排序给定父树项的子树项SortC hildre n等。

CtreeCtrl

CtreeCtrl

CtreeCtrlCtreeCtrl树控制(CTreeCtrl)主要用来显示具有一定层次结构的数据项,如资源管理器中的磁盘目录等,以供用户在其中进行各种选择。

树控制中的每个数据项包括数据项名称的文本字符串和用于表示该数据项的图像,每个数据项下面均可包含各种子项,整个结构就象目录树一样。

对于包含各种子项的数据项,可通过鼠标双击来展开或合拢,这可以通过控制树的不同风格来实现树控制的不同显示形态。

1.树控制的建立方法CtreeCtrl&treeCtrl 建立树控制对象结构Create 建立树控制并绑定对象树控制CTreeCtrl::Create的调用格式如下:BOOL Create( DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID );其中参数dwStyle用来确定树控制的类型;rect用来确定树控制的大小和位置;pParentWnd用来确定树控制的父窗口,通用是一个对话框并且不能为NULL;nID用来确定树控制的标识。

树控制的风格可以是下列值的组合:TVS_HASLINES 表示树控制在各子项之间存在连线;TVS_LINESATROOT 表示树控制在根项之间存在连线;TVS_HASBUTTONS 表示树控制视在父项左侧存在展开合拢控制按钮;TVS_EDITLABELS 表示可以控制鼠标单击修改树项的名称;TVS_SHOWSELALWAYS 表示选中项即使在窗口失去输入焦点时仍然保持选中状态;TVS_DISABLEDRAGDROP表示禁止树控制发送TVN_BEGINDRAG消息2.树控制的属性类树控制属性类包括取得树控制中项数GetCount、取得树控制中项相对于父项的偏移值GetIndent、取得树控制图像列表控制句柄GetImageList、设置树控制图像列表控制句柄SetImageList、取得匹配下一个树项GetNextItem、判断给定树项是否包含子项ItemHasChildren、取得树项子项GetChildItem、取得下一个同属树项GetNextSiblingItem、取得前一个同属树项GetPrevSiblingItem、取得父树项GetParentItem、取得第一个可视树项GetFirstVisibleItem、取得下一个可视树项GetNextVisible Item、取得前一个可视的树项GetPrevVisibleItem、取得被选中的树GetSelectedItem、取得根树项GetRootItem、取得树项的属性GetItem、设置树项的属SetItem、取得树项的状态GetItemState、设置树项的状态SetItemState、取得与树项关联图像GetItemImage、设置与树项关联图像SetItemImage、取得树项文本GetItemText、设置树项文本SetItemText和取得树项编辑控制句柄GetEditControl等。

带复选框的CTreeCtrl响应复选消息

带复选框的CTreeCtrl响应复选消息

带复选框的CTreeCtrl响应复选消息1. 消息事件(1)鼠标点击当前ITEM的CHECKBOX:引发NM_CLICK事件并传递TVHT_ONITEMSTATEICON。

(2)鼠标点击当前ITEM的TEXT:引发NM_CLICK事件。

(3)鼠标点击新ITEM的CHECKBOX:引发TVN_SELCHANGED事件、NM_CLICK 事件并传递TVHT_ONITEMSTATEICON。

(4)鼠标点击新ITEM的TEXT:引发NM_CLICK事件、TVN_SELCHANGED事件。

2. 消息事件总结点击ITEM会引发NM_CLICK事件。

若点击CHECKBOX则传递TVHT_ONITEMSTATEICON。

因此可不处理TVN_SELCHANGED事件而只处理NM_CLICK事件。

3. 消息处理注意事项(1)点击CHECKBOX后会自动更新CheckBox的状态,因此在处理代码中不需要使用SetCheck函数设置状态,而GetCheck函数返回也是其原始状态。

(2)点击新CHECKBOX后不会自动将对应的ITEM设置为选择状态,需要使用SelectItem函数进行设置。

4. 使用方法(1)若传递TVHT_ONITEMSTATEICON获取选择ITEM的状态并取反若有子项则所有子项设置为一致若没有子项则若当前状态为TRUE则设置父项为TRUE;否则遍历所有兄弟项,若全为FALSE则设置父项为FALSE。

若选择了新ITEM则设置新ITEM为选择项(2)若未传递TVHT_ONITEMSTATEICON设置更新ITEM状态,获取选择ITEM的状态若有子项则所有子项设置为一致若没有子项则若当前状态为TRUE则设置父项为TRUE;否则遍历所有兄弟项,若全为FALSE则设置父项为FALSE。

5. 响应NM_CLICK事件的函数代码void CTestTimerDlg::OnClickTree(NMHDR* pNMHDR, LRESULT* pResult){// TODO: Add your control notification handler code hereCPoint point;UINT uFlag; //接收有关点击测试的信息的整数HTREEITEM hTree;BOOL bCheck;GetCursorPos(&amp;point); //获取屏幕鼠标坐标m_TreeCtrl.ScreenToClient(&amp;point); //转化成客户坐标hTree = m_TreeCtrl.HitTest(point,&amp;uFlag); //返回与CtreeTtrl关联的光标的当前位置和句柄if((TVHT_NOWHERE &amp; uFlag)){return;}if (hTree &amp;&amp; (TVHT_ONITEMSTATEICON &amp; uFlag)) //点中复选框{m_TreeCtrl.SelectItem(hTree);CString temp = m_TreeCtrl.GetItemText(hTree) + &quot;\r\n&quot;;TRACE(temp);bCheck = m_TreeCtrl.GetCheck(hTree); //获取当前复选状态SetChildCheck(hTree,!bCheck); //设置子项复选状态SetParentCheck(hTree, bCheck); //设置父项复选状态}*pResult = 0;}void CTestTimerDlg::SetChildCheck(HTREEITEM hTree,BOOL bCheck){m_TreeCtrl.Expand(hTree,TVE_EXPAND);hTree = m_TreeCtrl.GetChildItem(hTree); //获取子项句柄while (hTree){m_TreeCtrl.SetCheck(hTree, bCheck);SetChildCheck(hTree,bCheck); //递归调用hTree = m_TreeCtrl.GetNextSiblingItem(hTree); //获取兄弟的句柄}}void CTestTimerDlg::SetParentCheck(HTREEITEM hTree,BOOL bCheck) {HTREEITEM hParent = m_TreeCtrl.GetParentItem(hTree);if (hParent){HTREEITEM hChild = m_TreeCtrl.GetChildItem(hParent);while (hChild){if (hChild == hTree){hChild = m_TreeCtrl.GetNextSiblingItem(hChild);continue;}BOOL bflag = m_TreeCtrl.GetCheck(hChild);if (bCheck == bflag) //判断是否还有兄弟项被选择{return;}hChild = m_TreeCtrl.GetNextSiblingItem(hChild);}m_TreeCtrl.SetCheck(hParent,!bCheck);SetParentCheck(hParent,bCheck); //设置父项的状态}}。

treeset排序原理

treeset排序原理

treeset排序原理
TreeSet是一种基于红黑树的Set集合,它可以自动进行元素排序。

TreeSet的排序原理是通过对元素进行比较,将它们按照特定的顺序排列。

在创建TreeSet时,可以传入一个Comparator对象,它可以定义元素的比较规则。

如果没有传入Comparator,则元素必须实现Comparable接口,该接口中定义了一个compareTo()方法,该方法用于定义元素的自然顺序。

TreeSet使用红黑树的数据结构来存储元素。

红黑树是一种自平衡的二叉搜索树,它具有以下特点:
1. 每个节点都是红色或黑色。

2. 根节点是黑色的。

3. 每个叶子节点(NIL节点)都是黑色的。

4. 如果一个节点是红色的,则它的子节点必须是黑色的。

5. 从任意节点到其每个叶子节点的所有路径都包含相同数目的黑色节点。

由于红黑树是自平衡的,因此在插入和删除元素时,它会自动调整树的结构,以保持树的平衡。

这样可以确保元素的插入和删除操作的时间复杂度都是O(log n),其中n为树中元素的个数。

另外,由于TreeSet是一个Set集合,因此它不允许包含重复的元素。

如果试图将重复元素插入TreeSet中,它会被忽略。

总之,通过使用红黑树作为数据结构和元素比较规则,TreeSet
可以自动对元素进行排序,并且具有高效的插入和删除操作。

树的遍历(先序、中序、后序详解)

树的遍历(先序、中序、后序详解)

树的遍历(先序、中序、后序详解) 树的遍历主要有三种
1、先序遍历:先遍历根节点,再遍历左节点,最后遍历右节点;
2、中序遍历:先遍历左节点,再遍历根节点,最后遍历右节点;
3、后序遍历:先遍历左节点,再遍历右节点,最后遍历根节点;
总结:先、中、后就表⽰根节点的遍历处于哪个位置,⽰总是先左节点后右节点。

例如先序遍历,“先”表⽰根节点最先遍历,再左节点,
最后右节点。

依此类推中序遍历,后序遍历。

接下来看⽰个题⽰,看⽰下你们是怎么做的。

我们以中序遍历为例来讲(每次以三个节点为⽰个整体):
⽰先从树的根节点开始即C F E
我们再依次来看,先看C,则以C为根节点的三个节点(即A C D)按中序遍历则为A C D。

故A放在C之前,把D放在C之后。

故A C D F E
再看A,由于以A为根节点的三个节点中其他两个没有,故看下⽰个D 同理可得B D
故把B放在D之前,即A C B D F E
类似可得中序遍历为A C B D F H E M G
这样是不是再也不怕树的遍历了。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

CTreeCtrl树节点排序,节点复选效果描述:该功能可使某义节点下的全部子节点按某种序列重新排列SortChildren是为该结点下面的所有子节点排序,注意只是子节点,不包括子节点的子节点。

SortChildrenCB是自定义排序方式。

现给出大体例子SortChildrenCB中的TVSORTCB需要用到一个回调函数常常是难点。

INT CHvrTree::SortItem(HTREEITEM hItem){BOOL bRet;CHvrTree *ptree = this;TVSORTCB sortpage;g_pLogger->Debug("<%s(%d)> SortItem():Enter",D_PC_LOG_NAME_HVRTREE, __LINE__);///////////////////////////////////////////////////////////////// /////////// ソーティング情報g_pLogger->Info("<%s(%d)> SortItem(): ソーティングノード,hItem - %08x",D_PC_LOG_NAME_HVRTREE, __LINE__,hItem );sortpage.hParent = hItem;sortpage.lpfnCompare = MyCompareProc;sortpage.lParam = (LPARAM)ptree;bRet = SortChildrenCB(&sortpage);if ( bRet ){g_pLogger->Debug("<%s(%d)> SortItem():Leave",D_PC_LOG_NAME_HVRTREE, __LINE__);return D_PC_SUCCESS;}else{g_pLogger->Debug("<%s(%d)> SortItem():Leave",D_PC_LOG_NAME_HVRTREE, __LINE__);return D_PC_FAILURE;}}入口参数是两个在要排序的序列中的无序参数INT CALLBACK CHvrTree::MyCompareProc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort){CHvrTree* pTreeCtrl = (CHvrTree*) lParamSort;HTREEITEM hItem1 = (HTREEITEM)lParam1;HTREEITEM hItem2 = (HTREEITEM)lParam2;// ノードのアイコンに付けられた固有の番号によって、ノードタイプ取得INT nKind1 = pTreeCtrl->GetItemType(hItem1);INT nKind2 = pTreeCtrl->GetItemType(hItem2);// 1.01 : カテゴリソーティングを機能修正///////////////////////////////////////////////////////////////// /////////// ノードタイプ取得チェックif ( (nKind1<0)||(nKind2<0) ){g_pLogger->Error( "<%s(%d)> MyCompareProc: 目標ノードノードタイプ情報取得できない, nType - %d",D_PC_LOG_NAME_HVRTREE, __LINE__,D_PC_FAILURE );return D_PC_ERRCODE_HVRTREE_GETTREE_FAIL;}// 1.01 - END// ノード情報取得BOOL bRet;ST_TREE_NODE *pnodeInfo1 = NULL; // ノード1の情報 ST_TREE_NODE *pnodeInfo2 = NULL; // ノード2の情報bRet = pTreeCtrl->m_mapNode.Lookup(hItem1,(void*&)pnodeInfo1); // ノード1の情報取得if(bRet == FALSE){// 目標ノード情報取得できないg_pLogger->Error( "<%s(%d)> MyCompareProc: 目標ノード情報取得できない, hItem - %08x",D_PC_LOG_NAME_HVRTREE, __LINE__, hItem1 );return D_PC_ERRCODE_HVRTREE_GETTREE_FAIL;}bRet = pTreeCtrl->m_mapNode.Lookup(hItem2,(void*&)pnodeInfo2); // ノード2の情報取得if(bRet == FALSE){// 目標ノード情報取得できないg_pLogger->Error( "<%s(%d)> MyCompareProc: 目標ノード情報取得できない, hItem - %08x",D_PC_LOG_NAME_HVRTREE, __LINE__, hItem2 );return D_PC_ERRCODE_HVRTREE_GETTREE_FAIL;}INT nRet = NULL; // 戻り値if( nKind1 == nKind2){// ノード1とノード2は同じノードタイプの場合// ノード1とノード2はカテゴリーノードの場合if( nKind1 == D_PC_NODE_CATE_1){CString strItem1,strItem2;// カテゴリー名取得strItem1 = pTreeCtrl->GetItemText(hItem1);strItem2 = pTreeCtrl->GetItemText(hItem2);// カテゴリー名比較nRet = strcmp(strItem1, strItem2);}// 1.01 : カテゴリソーティングを機能修正else if( nKind1 == D_PC_NODE_CATE_2){CString strItem1,strItem2;// カテゴリー名取得strItem1 = pTreeCtrl->GetItemText(hItem1);strItem2 = pTreeCtrl->GetItemText(hItem2);// カテゴリー名比較nRet = strcmp(strItem1, strItem2);}// 1.01 - ENDelse if( nKind1 == D_PC_NODE_CAM ){// ノード1とノード2はカメラノードの場合// カメラ番号取得INT nCamId1 = pnodeInfo1->Id;INT nCamId2 = pnodeInfo2->Id;// カメラ番号比較nRet = nCamId1 - nCamId2;}else if( nKind1 == D_PC_NODE_HVR ){// ノード1とノード2は物件ノードの場合ST_HVR_INFO hvrInfo1, hvrInfo2;CString strItem1, strItem2;// 物件番号取得INT nHvrId1 = pnodeInfo1->Id;INT nHvrId2 = pnodeInfo2->Id;// 物件情報取得g_hvrUser.GetHvrInfo(nHvrId1, &hvrInfo1);g_hvrUser.GetHvrInfo(nHvrId2, &hvrInfo2);// 1.05 : 物件の順機能修正// 物件カナ名取得strItem1.Format("%s",hvrInfo1.szKana);strItem2.Format("%s",hvrInfo2.szKana);// 物件カナ名比較nRet = CCheckWord::CompareValidKataName( strItem1, strItem2 );if (nRet == 0){if (nHvrId1 > nHvrId2){nRet = 1;}else{nRet = -1;}}// 1.05 - END}else{// 他の場合nRet = NULL;}}else{// ノード1とノード2は違いノードタイプの場合nRet = nKind1 - nKind2;}return nRet;}GetItemType是获得结点状态即它的图标,主要是利用了GetItemImage得到其图标复选重绘有时可能会用到复选操作,即点击一个结点时该结点和另一个结点同时被选中(如其父结点)可使用系统消息OnCustomDraw,该消息须手动添加该功能的实质是:先把要选则的所有节点刷上颜色,再到调用时如单击或双击事件把不需要的颜色去掉virtual void OnCustomDraw(NMHDR *pHdr, LRESULT *pResult);BEGIN_MESSAGE_MAP(CHvrTree, CTreeCtrl)ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnCustomDraw)//}}AFX_MSG_MAPEND_MESSAGE_MAP()void CHvrTree::OnCustomDraw(NMHDR *pHdr, LRESULT *pResult) {LPNMLVCUSTOMDRAW lplvcd = (LPNMLVCUSTOMDRAW)pHdr;INT nState;switch(lplvcd->nmcd.dwDrawStage){case CDDS_PREPAINT:* pResult= CDRF_NOTIFYITEMDRAW;break;// アイテムが描画される前case CDDS_ITEMPREPAINT:nState = lplvcd->nmcd.uItemState;if((nState == (CDIS_FOCUS|CDIS_SELECTED)) || (nState ==CDIS_SELECTED) ){lplvcd->clrTextBk = D_PC_DEV_ADD_BLACK_BRUSH;// アイテムの文字色を設定lplvcd->clrText = D_PC_DEV_LIST_RUN_COLOR;* pResult= CDRF_DODEFAULT;break;}else{* pResult= 0;break;}default:* pResult = 0;break;}}判断结点状态可使用GetItemState。

相关文档
最新文档