CTreeCtrl重载时若干个技巧

当标准的CTreeCtrl不能符合我们的使用要求时,通常会对它进行重载,下面列出若干个技巧。

1,使用Vista的风格

#pragma comment(lib,"UxTheme.lib")

::SetWindowTheme(m_hWnd,L"Explorer", NULL);

 

2,改变checkbox的图标

新建一个CImageList之后,将自己需要的图标添加进去,然后设置一下

this->SetImageList(&m_iStateIconList,TVSIL_STATE);

前提是,CTreeCtrl的属性中有TVS_CHECKBOXES

 

3,区分checkbox图标点击和文字被点击的方法

 UINT nState; UINT uFlags = 0; HTREEITEM selectItem = HitTest(point, &uFlags); if(selectItem == NULL) { return; } if(!(uFlags & TVHT_ONITEMSTATEICON)) { //item clicked //you want do } else { //nState: 0->No ChenckBox // 1->No Select State // 2->Some Select // 3->All Select nState = GetItemState(selectItem,TVIS_STATEIMAGEMASK) >>12; nState=(nState==3)?1:3; }

 

注意,如果处理中发生了展开或者收缩的情况的话,hittest有错的时候。

 

4,更改树显示的背景以及文字颜色

 void CTreeCtrlEx::OnNMCustomdraw(NMHDR *pNMHDR, LRESULT *pResult) { LPNMTVCUSTOMDRAW pNMCD = reinterpret_cast(pNMHDR); switch (pNMCD->nmcd.dwDrawStage) { case CDDS_PREPAINT: *pResult = CDRF_NOTIFYITEMDRAW; return; case CDDS_ITEMPREPAINT: HTREEITEM parentitem=GetParentItem((HTREEITEM)pNMCD->nmcd.dwItemSpec); if(parentitem == NULL) { pNMCD->clrText =RGB(0, 255, 255); pNMCD->clrTextBk =RGB(0, 0, 255); } break; } *pResult = 0; }

 

5,遍历修改checkbox的状态

重载SetItemState函数之后,调用下面2个遍历函数。

  BOOL CTreeCtrlEx::SetItemState(HTREEITEM hItem, UINT nState,UINT nStateMask, BOOL bSearch) { BOOL bReturn=CTreeCtrl::SetItemState( hItem, nState, nStateMask ); UINT iState = nState >> 12; if(iState!=0) { if(bSearch) TravelChild(hItem, iState); TravelSiblingAndParent(hItem,iState); } return bReturn; } void CTreeCtrlEx::TravelSiblingAndParent(HTREEITEM hItem, int nState) { HTREEITEM hNextSiblingItem,hPrevSiblingItem,hParentItem; //Find parent node if not exists return; hParentItem=GetParentItem(hItem); if(hParentItem!=NULL) { int nState1=nState; //Find The Node State after Currently node hNextSiblingItem=GetNextSiblingItem(hItem); while(hNextSiblingItem!=NULL) { nState1 = GetItemState( hNextSiblingItem, TVIS_STATEIMAGEMASK ) >> 12; if(nState1!=nState && nState1!=0) break; else hNextSiblingItem=GetNextSiblingItem(hNextSiblingItem); } if(nState1==nState) { //Find The Node State before Currently node hPrevSiblingItem=GetPrevSiblingItem(hItem); while(hPrevSiblingItem!=NULL) { nState1 = GetItemState(hPrevSiblingItem,TVIS_STATEIMAGEMASK)>> 12; if(nState1!=nState && nState1!=0) break; else hPrevSiblingItem=GetPrevSiblingItem(hPrevSiblingItem); } } if(nState1==nState || nState1==0) { nState1 = GetItemState( hParentItem, TVIS_STATEIMAGEMASK ) >> 12; if(nState1!=0) { CTreeCtrl::SetItemState( hParentItem,INDEXTOSTATEIMAGEMASK(nState), TVIS_STATEIMAGEMASK ); } TravelSiblingAndParent(hParentItem,nState); } else { //third state hParentItem=GetParentItem(hItem); while(hParentItem!=NULL) { nState1 = GetItemState( hParentItem, TVIS_STATEIMAGEMASK ) >> 12; if(nState1!=0) { CTreeCtrl::SetItemState( hParentItem, INDEXTOSTATEIMAGEMASK(2), TVIS_STATEIMAGEMASK ); } hParentItem=GetParentItem(hParentItem); } } } } void CTreeCtrlEx::TravelChild(HTREEITEM hItem, int nState) { HTREEITEM hChildItem,hBrotherItem; hChildItem=GetChildItem(hItem); if(hChildItem!=NULL) { CTreeCtrl::SetItemState(hChildItem,INDEXTOSTATEIMAGEMASK(nState), TVIS_STATEIMAGEMASK ); TravelChild(hChildItem, nState); hBrotherItem=GetNextSiblingItem(hChildItem); while (hBrotherItem) { int nState1 = GetItemState( hBrotherItem, TVIS_STATEIMAGEMASK ) >> 12; if(nState1!=0) { CTreeCtrl::SetItemState( hBrotherItem, INDEXTOSTATEIMAGEMASK(nState),TVIS_STATEIMAGEMASK ); } TravelChild(hBrotherItem, nState); hBrotherItem=GetNextSiblingItem(hBrotherItem); } } }

你可能感兴趣的:(Windows编程)