树控件的单击展开和虚列表的使用

在使用树控件时,想要实现单击展开,结果单击时的确可以展开了,但是随机而来的BUG多多。。

例如单击ITEM前面的+号展开不了,而且是展开一下然后立即收回,而且已经单击展开后的ITEM再也不能展开了。

由于树控件插入项时对子项个数使用了I_CHILDRENCALLBACK,类似于虚列表的方法,所以怀疑是否是虚列表的BUG,经过仔细的跟踪,终于找到结决办法。

在建树时,不要对根结点作插入,只是展开它就可以了,否则会因为使用虚列表的动态插入在根结点下插入两次重复的项目。

 HTREEITEM hRoot = InsertItem(strName, nImage, nSel);
 SetItemData(hRoot,(DWORD)lpidl);
 
 TV_ITEM tv;
 tv.mask = TVIF_CHILDREN ;
 tv.hItem = hRoot;
 tv.cChildren = I_CHILDRENCALLBACK;
 SetItem( &tv);

 Expand(hRoot, TVE_EXPAND);
 Expand(GetChildItem(hRoot), TVE_EXPAND); 

展开时,判断展开要求,是展开时则插入子目录,插子目录时如果该目录下有子目录则将 tv.cChildren 设为I_CHILDRENCALLBACK,是收拢时则删除所有子结点并将tv.cChildren 设为I_CHILDRENCALLBACK,


void CExpTree::OnItemexpanding(NMHDR* pNMHDR, LRESULT* pResult)
{
 NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
 if(pNMHDR->code == TVN_ITEMEXPANDING )
 {

  NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
  // TODO: Add your control notification handler code here
  HTREEITEM hItemNew = pNMTreeView->itemNew.hItem;
  BOOL bExpand = GetItemState(hItemNew, TVIS_EXPANDED ) & TVIS_EXPANDED;
  
  if(hItemNew != NULL &&
   pNMTreeView->action  == TVE_EXPAND &&
   lpMalloc != NULL
   && !bExpand
   )
  {
   
   SetRedraw(FALSE);
   this->LockWindowUpdate();
   InsertChildItem(hItemNew);
   UnlockWindowUpdate();
   SetRedraw(TRUE);
  }
  else if(pNMTreeView->action == TVE_COLLAPSE && bExpand)
  {
   DeleteTree(hItemNew);
   TV_ITEM tv;
   tv.mask = TVIF_CHILDREN ;
   tv.hItem = hItemNew;
   tv.cChildren = I_CHILDRENCALLBACK;
   SetItem( &tv);
  }
 } 
 *pResult = 0;
}

在单击时不能仅仅根据结点就展开,还应判断单击的位置是否在结点前面的+号上,如果在加号上就不要展开了,因为加号也会触发一个expand事件,这个两个expand会使用结点先展开,再合拢,出现前面所说的BUG。(让我小郁闷了两天,一直没空解决的,终于干掉它了)

void CExpTree::OnClick(NMHDR* pNMHDR, LRESULT* pResult)
{
 // TODO: Add your control notification handler code here
 POINT point;
 GetCursorPos(&point);
 ::ScreenToClient(m_hWnd, &point);
 UINT Flags = 0;
 HTREEITEM hItemNew   =  this->HitTest(CPoint(point), &Flags);
 if(hItemNew != NULL && !(Flags & TVHT_ONITEMBUTTON ) )//不是在+号上时
 {
  if(!(GetItemState(hItemNew, TVIS_EXPANDED ) & TVIS_EXPANDED))
  {
   Expand(hItemNew, TVE_EXPAND);
  }
 }
 *pResult = 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值