当前位置: 首页 > news >正文

做关于车的网站好/福州百度推广开户

做关于车的网站好,福州百度推广开户,深圳微信网站公司,网站的定位示例代码运行效果图如下: 在很多情况下,我们经常需要实现树的多态选择,如上图所示,当全部子节点选中的情况下,当前节点才被选中(如图示[荆门市]节点),当子节点部分选中时&#xff0c…

示例代码运行效果图如下:

在很多情况下,我们经常需要实现树的多态选择,如上图所示,当全部子节点选中的情况下,当前节点才被选中(如图示[荆门市]节点),当子节点部分选中时,当前节点处于第三态(如图示[湖北省]节点)当全部子节点未选中时,当前节点处于未选中的状态(如图示[江苏省]节点)。本文就介绍这种三态选择树的具体实现方法。

在VC知识库第十九期中河南科技大学丛雷朋友也介绍了一种实现方法,两种方法比较,本文介绍的方法实现简单,兼容原CTreeCtrl的全部操作,CheckBox也是采用控件本身的CheckBox,只是在状态显示时重画而已。因此,本方法可以实现表示三态的情况下同时显示节点ICON图标,另增加了对CheckBox在某些节点是否显示的控制,同时增加了对键盘空格键选中、取消选中的控制。具体遍历父、子节点的方法同丛雷朋友朋友的方法类似,也是递归实现全部节点的遍历,只是优化了一些,效率更高。

下面介绍具体使用方法:

步骤一:生成一个对话框工程(示例工程CMutiTree)。

步骤二:添加树控件,按照实际需要设置所需的属性。

步骤三:做节点图标和三态选择框图标

一般情况下节点图标采用16×16,三态选择图标采用13×13大小比较合适。

三态选择图标对应: 0->无选择钮 1->没有选择 2->部分选择 3->全部选择

步骤四:将两个文件[MutiTreeCtrl.cpp ,MutiTreeCtrl.h]添加到步骤一创建的对话框

工程中,在CMutiTreeDlg类的头文件中增加对[MutiTreeCtrl.h]的包含,此时工程中增加了CMutiTreeCtrl类。

1.#include "MutiTreeCtrl.h"

步骤五:用ClassWizard在CmutiTreeDlg中创建一个树控件CTreeCtrl的对象m_TripleTree,更改该对象为上面步骤四加入的CMutiTreeCtrl类的对象。

步骤六:在CMutiTreeDlg类中定义两个CImageList 类的对象,用于加载CMutiTreeCtrl所需要的节点图标列表和三态选择框图标列表。
在CMutiTreeDlg类的头文件中:

1.CImageList m_imgList;
2.CImageList m_imgState;

在对话框的初始化函数中:

1.m_imgState.Create(IDB_BITMAP_STATE,13, 1, RGB(255,255,255));
2.m_imgList.Create(IDB_BITMAP_LIST,16, 1, RGB(255,255,255));
3. 
4.m_TripleTree.SetImageList(&m_imgList,TVSIL_NORMAL);
5.m_TripleTree.SetImageList(&m_imgState,TVSIL_STATE);

完成以上六步操作后,编译、运行,用键盘空格键或鼠标单击CheckBox改变其状态,您将看到不需要再增加任何代码,已经实现了三态选择树的功能。如果需要隐藏某些选择框,如根节点的选择框,只需要设置对应的节点状态为0即可:

1.m_TripleTree.SetItemState( hRoot, INDEXTOSTATEIMAGEMASK(0),
2.TVIS_STATEIMAGEMASK );

上述代码将设置根节点不显示三态选择框。

我具体实现的思想是以Windows标准的CTreeCtrl类为基类派生一个类CMutiTreeCtrl,截获键盘和鼠标点击CheckBox的事件,在此消息响应函数中,更改CheckBox的状态,并搜索子节点、兄弟节点和父节点,更改其状态与上述逻辑一致。方法如下介绍:

一、 CTreeCtrl类为基类派生CMutiTreeCtrl类

01.class CMutiTreeCtrl : public CTreeCtrl
02.{
03.// Construction
04.public:
05.CMutiTreeCtrl();
06.// Attributes
07.public:
08.// Operations
09.public:
10.// Overrides
11.// ClassWizard generated virtual function overrides
12.//{{AFX_VIRTUAL(CMutiTreeCtrl)
13.//}}AFX_VIRTUAL
14.// Implementation
15.public:
16.BOOL SetItemState( HTREEITEM hItem, UINT nState, UINT nStateMask, BOOLbSearch=TRUE);
17.virtual ~CMutiTreeCtrl();
18.// Generated message map functions
19.protected:
20.//{{AFX_MSG(CMutiTreeCtrl)
21.afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
22.afx_msg void OnStateIconClick(NMHDR* pNMHDR, LRESULT* pResult);
23.afx_msg void OnKeydown(NMHDR* pNMHDR, LRESULT* pResult);
24.afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
25.//}}AFX_MSG
26.DECLARE_MESSAGE_MAP()
27.private:
28.UINT m_uFlags;
29.void TravelSiblingAndParent(HTREEITEM hItem, int nState);
30.void TravelChild(HTREEITEM hItem,int nState);
31.};

二、重载CTreeCtrl的SetItemState()函数,在调用了基类的SetItemState()函数修改了节点状态以后,遍历一遍当前节点子节点、兄弟节点、父节点,按照上述逻辑修改为相应的状态,实现三态显示。调用此函数有二种情况:

①键盘或鼠标输入修改节点状态,此时要遍历全部父、兄、子节点;

②程序根据实际情况调用修改节点状态,因为修改节点状态时是判断了全部子节点的状态后得出了状态,所以此时仅需要遍历全部的兄、父节点,更改其状态符合逻辑。故在重载的函数后面加了一个缺省为TRUE的bSearch变量,当程序修改节点时请置此标志为FALSE。

01.BOOL CMutiTreeCtrl::SetItemState(HTREEITEM hItem, UINT nState,
02.UINT nStateMask, BOOL bSearch)
03.{
04.BOOL bReturn=CTreeCtrl::SetItemState( hItem, nState, nStateMask );
05. 
06.UINT iState = nState >> 12;
07.if(iState!=0)
08.{
09.if(bSearch) TravelChild(hItem, iState);
10.TravelSiblingAndParent(hItem,iState);
11.}
12.return bReturn;
13.}

三、检测鼠标单击节点CHeckBox的事件,更改对应的节点状态并遍历树的其他节点。

01.void CMutiTreeCtrl::OnLButtonDown(UINT nFlags, CPoint point)
02.{
03.HTREEITEM hItem =HitTest(point, &m_uFlags);
04.if ( (m_uFlags&TVHT_ONITEMSTATEICON ))
05.{
06.//nState: 0->无选择钮 1->没有选择 2->部分选择 3->全部选择
07.UINT nState = GetItemState( hItem, TVIS_STATEIMAGEMASK ) >> 12;
08.nState=(nState==3)?1:3;
09.SetItemState(hItem,INDEXTOSTATEIMAGEMASK(nState),TVIS_STATEIMAGEMASK);
10.}
11. 
12.CTreeCtrl::OnLButtonDown(nFlags, point);
13.}
14.void CMutiTreeCtrl::OnStateIconClick(NMHDR* pNMHDR, LRESULT* pResult)
15.{
16.if(m_uFlags&TVHT_ONITEMSTATEICON) *pResult=1;
17.else *pResult = 0;
18.}

四、检测键盘按空格键的事件,更改对应的节点状态并遍历树的其他节点。

01.void CMutiTreeCtrl::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
02.{
03.//处理空格键
04.if(nChar==0x20)
05.{
06.HTREEITEM hItem =GetSelectedItem();
07.UINT nState = GetItemState( hItem, TVIS_STATEIMAGEMASK ) >> 12;
08.if(nState!=0)
09.{
10.nState=(nState==3)?1:3;
11.SetItemState( hItem, INDEXTOSTATEIMAGEMASK(nState),
12.TVIS_STATEIMAGEMASK );
13.}
14.}
15.else CTreeCtrl::OnKeyDown(nChar, nRepCnt, nFlags);
16.}

五、树的遍历用递归的方法搜索当前节点的父、兄、子节点

①递归搜索子节点

01.void CMutiTreeCtrl::TravelChild(HTREEITEM hItem, int nState)
02.{
03.HTREEITEM hChildItem,hBrotherItem;
04. 
05.//查找子节点,没有就结束
06.hChildItem=GetChildItem(hItem);
07.if(hChildItem!=NULL)
08.{
09.//设置子节点的状态与当前节点的状态一致
10.CTreeCtrl::SetItemState(hChildItem,INDEXTOSTATEIMAGEMASK(nState),
11.TVIS_STATEIMAGEMASK );
12.//再递归处理子节点的子节点和兄弟节点
13.TravelChild(hChildItem, nState);
14. 
15.//处理子节点的兄弟节点和其子节点
16.hBrotherItem=GetNextSiblingItem(hChildItem);
17.while (hBrotherItem)
18.{
19.//设置子节点的兄弟节点状态与当前节点的状态一致
20.int nState1 = GetItemState( hBrotherItem, TVIS_STATEIMAGEMASK ) >> 12;
21.if(nState1!=0)
22.{
23.CTreeCtrl::SetItemState( hBrotherItem,
24.INDEXTOSTATEIMAGEMASK(nState),TVIS_STATEIMAGEMASK );
25.}
26.//再递归处理子节点的兄弟节点的子节点和兄弟节点
27.TravelChild(hBrotherItem, nState);
28.hBrotherItem=GetNextSiblingItem(hBrotherItem);
29.}
30.}
31.}

②递归搜索兄、父节点

01.void CMutiTreeCtrl::TravelSiblingAndParent(HTREEITEM hItem, int nState)
02.{
03.HTREEITEM hNextSiblingItem,hPrevSiblingItem,hParentItem;
04. 
05.//查找父节点,没有就结束
06.hParentItem=GetParentItem(hItem);
07.if(hParentItem!=NULL)
08.{
09.int nState1=nState;//设初始值,防止没有兄弟节点时出错
10. 
11.//查找当前节点下面的兄弟节点的状态
12.hNextSiblingItem=GetNextSiblingItem(hItem);
13.while(hNextSiblingItem!=NULL)
14.{
15.nState1 = GetItemState( hNextSiblingItem, TVIS_STATEIMAGEMASK ) >> 12;
16.if(nState1!=nState && nState1!=0) break;
17.else hNextSiblingItem=GetNextSiblingItem(hNextSiblingItem);
18.}
19. 
20.if(nState1==nState)
21.{
22.//查找当前节点上面的兄弟节点的状态
23.hPrevSiblingItem=GetPrevSiblingItem(hItem);
24.while(hPrevSiblingItem!=NULL)
25.{
26.nState1 = GetItemState(hPrevSiblingItem,TVIS_STATEIMAGEMASK)>> 12;
27.if(nState1!=nState && nState1!=0) break;
28.else hPrevSiblingItem=GetPrevSiblingItem(hPrevSiblingItem);
29.}
30.}
31. 
32.if(nState1==nState || nState1==0)
33.{
34.nState1 = GetItemState( hParentItem, TVIS_STATEIMAGEMASK ) >> 12;
35.if(nState1!=0)
36.{
37.//如果状态一致,则父节点的状态与当前节点的状态一致
38.CTreeCtrl::SetItemState( hParentItem,
39.INDEXTOSTATEIMAGEMASK(nState), TVIS_STATEIMAGEMASK );
40.}
41.//再递归处理父节点的兄弟节点和其父节点
42.TravelSiblingAndParent(hParentItem,nState);
43.}
44.else
45.{
46.//状态不一致,则当前节点的父节点、父节点的父节点……状态均为第三态
47.hParentItem=GetParentItem(hItem);
48.while(hParentItem!=NULL)
49.{
50.nState1 = GetItemState( hParentItem, TVIS_STATEIMAGEMASK ) >> 12;
51.if(nState1!=0)
52.{
53.CTreeCtrl::SetItemState( hParentItem,
54.INDEXTOSTATEIMAGEMASK(2), TVIS_STATEIMAGEMASK );
55.}
56.hParentItem=GetParentItem(hParentItem);
57.}
58.}
59.}  
60.}

好了,一切就是这么简单,如果你还不清楚的话,那就打开工程看看吧,如你有什么问题也不要忘记来信告诉我哦!最后祝大家学习愉快,多多交流,多多进步,一切顺利!


此文章来自于【http://www.vckbase.com/index.php/wv/466】

http://www.jmfq.cn/news/4798639.html

相关文章:

  • 广西梧州藤县疫情/凌云seo博客
  • 长沙房产网二手房/站长工具seo优化
  • 那种转转假网站怎么做的/长沙电商优化
  • h5手机网站模板下载/百度平台app下载
  • 新疆网站开发报价/广东短视频seo营销
  • 翻译国外网站做原创/推广计划怎么做
  • 温州做网站建设多少钱/品牌营销策略有哪些方法
  • 天津做网站企业/软文营销经典案例200字
  • 黄村做网站哪家快/推广怎么推
  • 做软装有什么网站找图片/淘宝新店怎么快速做起来
  • 南昌seo推广外包/系统优化方法
  • 江门公司建站模板/全网营销是什么
  • 国旗做网站按钮违法吗/专业的营销团队哪里找
  • 有哪些是外国人做的网站吗/西安百度竞价代运营
  • 区块链交易网站开发/找客户资源的软件
  • 软件开发平台 devcloud/免费网站seo
  • 仁寿建设局网站/农村电商平台
  • 公司网站的个人主页怎么做/武汉java培训机构排名榜
  • 怎么自己做网站空间/惠州网站制作推广
  • 广州最新封闭封控区域/网站产品怎么优化
  • 贵州网站制作品牌公司/全国各城市感染高峰进度查询
  • 小程序就是做网站/百度指数1000搜索量有多少
  • 可以做热图的工具网站/seo平台代理
  • 智能网站优化 cms 加盟/全球搜是什么公司
  • 网站策划 ppt/深圳市企业网站seo营销工具
  • 烟台做网站哪家好/小红书软文案例
  • 哪些网站可以做图片链接/文章推广平台
  • 中国中国建设银行网站首页/企业培训课程名称大全
  • 沈阳网站建设公司/企业网站建设案例
  • 呼伦贝尔网站建设平台/技能培训班