Раскрытие ветвей во время
перетаскивания
Здесь приводится пример элемента управления,
который раскрывает ветвь через две секунды после
того, как над ним завис курсор с перетаскиваемым
элементом.
Члены-перемнные, которые должны быть объявлены:
CImageList* m_pDragImage;
HTREEITEM m_htiDrag, m_htiDrop, m_htiOldDrop;
bool m_bLDragging;
UINT m_idTimer;
Код включенный в обработчик OnMouseMove():
if( m_idTimer && hti == m_htiOldDrop )
{
KillTimer( m_idTimer );
m_idTimer = 0;
}
if( !m_idTimer )
m_idTimer = SetTimer( 1000, 2000, NULL );
Теперь в ответе на сообщение таймера, мы
подсвечиваем элемент и проверяем нет ли у него
разветвлений. Если есть, разворачиваем их.
void CDragView::OnTimer(UINT nIDEvent)
{
if( nIDEvent == m_idTimer )
{
CTreeCtrl& theTree = GetTreeCtrl();
HTREEITEM htiFloat = theTree.GetDropHilightItem();
if( htiFloat && htiFloat == m_htiDrop )
{
if( theTree.ItemHasChildren( htiFloat ) )
theTree.Expand( htiFloat, TVE_EXPAND );
}
}
CTreeView::OnTimer(nIDEvent);
}
Приведенный ниже код поможет Вам более полно
оценить метод:
void CDragView::OnBeginDrag(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
m_htiDrag = pNMTreeView->itemNew.hItem;
m_htiDrop = NULL;
m_pDragImage = GetTreeCtrl().CreateDragImage( m_htiDrag );
if( !m_pDragImage )
return;
m_bLDragging = true;
CPoint pt(0,0);
IMAGEINFO ii;
m_pDragImage->GetImageInfo( 0, &ii );
pt.x = (ii.rcImage.right - ii.rcImage.left) / 2;
pt.y = (ii.rcImage.bottom - ii.rcImage.top) / 2;
m_pDragImage->BeginDrag( 0, pt );
pt = pNMTreeView->ptDrag;
ClientToScreen( &pt );
m_pDragImage->DragEnter(NULL,pt);
SetCapture();
*pResult = 0;
}
void CDragView::OnLButtonUp(UINT nFlags, CPoint point)
{
CTreeView::OnLButtonUp(nFlags, point);
if( m_bLDragging )
{
CTreeCtrl& theTree = GetTreeCtrl();
m_bLDragging = false;
CImageList::DragLeave(this);
CImageList::EndDrag();
ReleaseCapture();
delete m_pDragImage;
theTree.SelectDropTarget(NULL);
m_htiOldDrop = NULL;
if( m_htiDrag == m_htiDrop )
return;
HTREEITEM htiParent = m_htiDrop;
while( (htiParent = theTree.GetParentItem(htiParent)) != NULL )
{
if( htiParent == m_htiDrag ) return;
}
theTree.Expand( m_htiDrop, TVE_EXPAND );
HTREEITEM htiNew = CopyBranch( m_htiDrag, m_htiDrop, TVI_LAST );
theTree.DeleteItem(m_htiDrag);
theTree.SelectItem( htiNew );
if( m_idTimer )
{
KillTimer( m_idTimer );
m_idTimer = 0;
}
}
}
void CDragView::OnMouseMove(UINT nFlags, CPoint point)
{
CTreeView::OnMouseMove(nFlags, point);
HTREEITEM hti;
UINT flags;
if( m_bLDragging )
{
CTreeCtrl& theTree = GetTreeCtrl();
POINT pt = point;
ClientToScreen( &pt );
CImageList::DragMove(pt);
hti = theTree.HitTest(point,&flags);
if( hti != NULL )
{
CImageList::DragShowNolock(FALSE);
if( m_htiOldDrop == NULL )
m_htiOldDrop = theTree.GetDropHilightItem();
theTree.SelectDropTarget(hti);
m_htiDrop = hti;
if( m_idTimer && hti == m_htiOldDrop )
{
KillTimer( m_idTimer );
m_idTimer = 0;
}
if( !m_idTimer )
m_idTimer = SetTimer( 1000, 2000, NULL );
CImageList::DragShowNolock(TRUE);
}
}
}
HTREEITEM CDragView::CopyItem
(
HTREEITEM hti,
HTREEITEM htiNewParent,
HTREEITEM htiAfter // = TVI_LAST
)
{
CTreeCtrl& theTree = GetTreeCtrl();
TVINSERTSTRUCT insert;
::ZeroMemory(&insert, sizeof(TVINSERTSTRUCT));
HTREEITEM htiNew = NULL;
CString text;
insert.item.hItem = hti;
insert.item.mask = TVIF_CHILDREN|TVIF_HANDLE|TVIF_IMAGE|TVIF_SELECTEDIMAGE;
theTree.GetItem(&(insert.item));
text = theTree.GetItemText( hti );
insert.item.cchTextMax = text.GetLength();
insert.item.pszText = text.LockBuffer();
insert.hParent = htiNewParent;
insert.hInsertAfter = htiAfter;
insert.item.mask = TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_TEXT;
htiNew = theTree.InsertItem(&insert);
text.UnlockBuffer();
theTree.SetItemData( htiNew, theTree.GetItemData( hti ) );
theTree.SetItemState( htiNew, theTree.GetItemState( hti,
TVIS_STATEIMAGEMASK ), TVIS_STATEIMAGEMASK );
return htiNew;
}
HTREEITEM CDragView::CopyBranch
(
HTREEITEM hti,
HTREEITEM htiNewParent,
HTREEITEM htiAfter // = TVI_LAST
)
{
CTreeCtrl& theTree = GetTreeCtrl();
HTREEITEM htiChild = NULL;
HTREEITEM htiNew = CopyItem( hti, htiNewParent, htiAfter );
htiChild = theTree.GetChildItem( hti );
while( htiChild != NULL )
{
CopyBranch( htiChild, htiNew );
htiChild = theTree.GetNextSiblingItem( htiChild );
}
return htiNew;
}
void CDragView::OnDestroy()
{
CImageList* pImage = GetTreeCtrl().GetImageList( TVSIL_NORMAL );
delete pImage;
if( m_idTimer )
{
KillTimer( m_idTimer );
m_idTimer = 0;
}
CTreeView::OnDestroy();
}
Источник: ProtoSphere
|