MFC学习之CTreeCtrl控件的使用

       树状控件CTreeCtrl主要用于树状结构的功能使用,其中树状结构有一个根接点(Root),一个根接点下可以有多个子接点或者不设置子接点,子接点也可以作为父节点,使其下也包含若干的子接点,总是可以根据接点之间的上下级关系然后设置相应的接点。
       MTreeCtrl::InsertItem 函数为为控件添加接点,其结构如下:
       HTREEITEM InsertItem(
               LPTVINSERTSRUCT lpInsertStruct
               );
       HTREEITEM InsertItem(
               LPCTSTR lpszItem,
               HTREEITEM hParent = TVI_ROOT,
               HTREEITEM hInsertAfer = TVI_LAST
               );


        当需要添加一个接点的时候,做如下操作:
HTREEITEM hTreeItem;
CTreeCtrl m_treeCtrl;
HTREEITEM hTreeSub;
hTreeItem = m_treeCtrl.InsertItem("Root");或者hTreeItem = m_treeCtrl.InsertItem("Root",TVI_Root);
        如上操作就相当于给一个树状结构添加了一个根接点。如果还想给该根接点添加一个子接点的话,则如下操作:
hTreeItem = m_treeCtrl.InsertItem("Child",hTreeItem);

         如上,这样子就创建了一个Root的子接点Child,函数InsertItem中的hTreeItem则为其父接点的句柄。
由此可以推理下去,一个树结构根接点只有一个,然后要创建子接点时,只需记住父接点的句柄,便可以获取相应的子接点,
并且在创建多个子接点的时候,可以直接模仿上面的操作,创建的新的接点直接添加到上面的接点后面。

下面贴下自己实现的代码,主要是将一些数据存到文件中,然后读取出来进行设置树结构。

FileName.txt内容:
Name:Tom,Jony,Gray
City:China,Enlish,Japanese
Data:We,Fri,Sun

initTreeCtrl()函数
void initTreeCtrl()
{
      HTREEITEM hTreeRoot;//保存根接点的句柄
      HTREEITEM hTreeSub;//保存第一层子接点的句柄
	  HTREEITEM hTreeSub1;//保存第二层子接点的句柄
	  //添加根接点,InsertItem的第二个默认为TVI_ROOT
      hTreeRoot = m_treeCtrl.InsertItem("Root");

	  char cPath[256];
	  memset(cPath,0,256);
	  HMODULE module = GetModuleHandle(0);   
	  GetModuleFileName(module,cPath,256);
 	  CString strPath(cPath);
 	  int pos = strPath.ReverseFind('\\');
 	  if(pos == 0)
 	  {
 		  MessageBox("路径为空");
 		  return;
 	  }
 	  strPath = strPath.Left(pos);
	  strPath.Format("%s\\FileName.txt",strPath);
	  std::string strPath1 = CStringA(strPath);
 	  FILE* pFile = fopen(strPath1.c_str(),"r");
 	  if (pFile == NULL)
 	  {
 		  MessageBox("文件打开失败");
 		  return;
 	  }
 	  char cData[256];
 	  memset(cData,0,256);
 	  fgets(cData,256,pFile);
 	  while (strcmp(cData,"")!=0)
 	  {
 		  CString strData(cData);
 		  if (strData.GetLength() != 0)
 		  {
 			  int pos1 = strData.Find(':');
 			  if (pos1 == 0)
 			  {
 				  hTreeSub = m_treeCtrl.InsertItem(strData,hTreeRoot);
 				  continue;
 			  }
 			  CString strTreeName = strData.Left(pos1);
 			  hTreeSub = m_treeCtrl.InsertItem(strTreeName,hTreeRoot);
 			  strData = strData.Right(strData.GetLength()-pos1-1);
 			  while ((pos1 = strData.Find(','))!=-1)
 			  {
 				  strTreeName = strData.Left(pos1);
 				  hTreeSub1 = m_treeCtrl.InsertItem(strTreeName,hTreeSub);
 				  strData = strData.Right(strData.GetLength()-pos1-1);
 			  }
 			  if (strData.GetLength()!=0)
 			  {
 				  strTreeName = strData;
 				  hTreeSub1 = m_treeCtrl.InsertItem(strTreeName,hTreeSub);
 			  }
 		  }
		  memset(cData,0,256);
		  fgets(cData,256,pFile);
 	  }
	  fclose(pFile);
	  m_treeCtrl.Expand(hTreeRoot,TVE_EXPAND);//Expand展开树状结构
}

其中接点前变成可选的状态,则是将CTreeCtrl控件的属性中的Checks Boxs的属性改为TRUE就可以了。
Name前面的加减收缩符号,则是通过将属性Has Buttons改为TRUE。

这两种可以通过相应的语言来设置。

2、当选中父接点时,该父接点下的所有子接点也被选中。
     CtreeCtrl的HitTest函数能够得到与当前鼠标位置相关的项,所以可以先获取当前鼠标的位置,然后根据鼠标坐标获取该范围内的接点句柄。CTreeCtrl的GetChildItem方法可以获取当前句柄的孩子接点的句柄,所以可以根据父子接点的上下级关系实现子接点状态的修改。首先可以添加CTreeCtrl对象的NM_CLICK方法。具体实现如下:

void CDialogStudyDlg::OnNMClickTree1(NMHDR *pNMHDR, LRESULT *pResult)
{
      UINT uFlag;
      CPoint point;
      ::GetCursorPos(&point);     
      ::ScreenToClient(m_treeCtrl.m_hWnd, &point);     
      HTREEITEM   hItem   =   m_treeCtrl.HitTest(point,&uFlag);//HitTest函数能够得到与当前鼠标位置相关的项的句柄

      //把所有的状态都随之修改
      if ( NULL != hItem )
      {
            if ( uFlag & TVHT_ONITEMSTATEICON )//若点击CHECKBOX则传递TVHT_ONITEMSTATEICON
            {
                  m_treeCtrl.SelectItem(hItem);//将当前选中的父接点或子接点高亮
                  bool ItemState = !m_treeCtrl.GetCheck( hItem );//设置树状结构的状态,当前状态取反则以
                  HTREEITEM hLayer1 = m_treeCtrl.GetChildItem( hItem );//获取当前接点的子接点第一个句柄

                  while ( NULL != hLayer1 )
                  {
                        m_treeCtrl.SetCheck( hLayer1 , ItemState );//设置当前接点的状态

                        HTREEITEM hLayer2 = m_treeCtrl.GetChildItem( hLayer1 );
                        while( NULL != hLayer2 )
                        {
                              m_treeCtrl.SetCheck( hLayer2 , ItemState );
                              hLayer2 = m_treeCtrl.GetNextItem( hLayer2 , TVGN_NEXT );
                        }

                        hLayer1 = m_treeCtrl.GetNextItem( hLayer1 , TVGN_NEXT );//获取子接点中的下一个接点的句柄
                  }
            }
      }
      *pResult = 0;
}

效果如下:




先写到这些,后续学到别的继续添加。


  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值