樹控件的單擊展開和虛列表的使用

在使用樹控件時,想要實現單擊展開,結果單擊時的確可以展開了,但是隨機而來的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;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章