Drag and drop | CodeGuru

Drag and drop

“An operation in which the end user uses the mouse or other pointing device to move data to another location in the same window or another window”. This is right off the glossary in the VC++ help files. Note that this statement says move data but drag and drop is commonly understood to encompass copy […]

Written By
CodeGuru Staff
CodeGuru Staff
Aug 6, 1998
3 minute read
CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More




An operation in which the end user uses the mouse or other pointing device


to move data to another location in the same window or another window

.


This is right off the glossary in the VC++ help files. Note that this statement


says move data but drag and drop is commonly understood to encompass


copy data as well. In this section we will cover drag and drop to move


data within the same window

the tree view control..



Step 0: Make sure that the control style supports drag and drop


If the control has the TVS_DISABLEDRAGDROP style then the TVN_BEGINDRAG


notification is not sent. So make sure that the control does not have the


TVS_DISABLEDRAGDROP style.



Step 1: Declare member variables


Add member variables to the CTreeCtrl derived class to track whether drag


and drop is in progress and the handle of the drag item and the drop location.


The m_pDragImage variable holds the image list used during the drag and


drop operation.



 
protected:
	CImageList*	m_pDragImage;
	BOOL		m_bLDragging;
	HTREEITEM	m_hitemDrag,m_hitemDrop;


Step 2: Add handler for TVN_BEGINDRAG


You can use the class wizard to add a handler for the TVN_BEGINDRAG notification.


The handler function has been named OnBeginDrag() in the listing below.


The code first sets up the member variables. It then creates an image that


will drag across the screen as the mouse moves. CreateDragImage() is a


member of the CTreeView class and it creates an image consisting of the


item image and the label text.

BeginDrag() function is called with an argument of zero and a point.
The zero indicates the first image, which is the only image in the image
list. The value we use for the second argument causes the image to be drawn
to the right lower side of the cursor. You may want to experiment with
this value if the image position does not suit your taste.

We call the DragEnter() to display the drag image. The first argument
is NULL so that the drag image will be visible even if the mouse is dragged
outside the treeview control.

 

void CTreeCtrlX::OnBeginDrag(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
	*pResult = 0;

	m_hitemDrag = pNMTreeView->itemNew.hItem;
	m_hitemDrop = NULL;

	m_pDragImage = CreateDragImage(m_hitemDrag);  // get the image list for dragging
	// CreateDragImage() returns NULL if no image list
	// associated with the tree view control
	if( !m_pDragImage )
		return;

	m_bLDragging = TRUE;
	m_pDragImage->BeginDrag(0, CPoint(-15,-15));
	POINT pt = pNMTreeView->ptDrag;
	ClientToScreen( &pt );
	m_pDragImage->DragEnter(NULL, pt);
	SetCapture();
}
Advertisement


Step 3: Add handler for WM_MOUSEMOVE to update drag image


In this handler we basically update the position of the drag image and


update the drop position. The DragMove() function moves the drag image.


We then update the drop target if the mouse is over a tree view item. Note


the calls to DragShowNolock(). The first call hides the drag image and


allows the tree view control to be updated. The second calls displays the


drag image again. We can also use a combination of DragLeave() and DragEnter()


but I found that using these functions causes some redraw problems.



 
void CTreeCtrlX::OnMouseMove(UINT nFlags, CPoint point) 
{
	HTREEITEM	hitem;
	UINT		flags;

	if (m_bLDragging)
	{
		POINT pt = point;
		ClientToScreen( &pt );
		CImageList::DragMove(pt);
		if ((hitem = HitTest(point, &flags)) != NULL)
		{
			CImageList::DragShowNolock(FALSE);
			SelectDropTarget(hitem);
			m_hitemDrop = hitem;
			CImageList::DragShowNolock(TRUE);
		}
	}

	CTreeCtrl::OnMouseMove(nFlags, point);
}


Step 4: Finally add handler for WM_LBUTTONUP


It is in the WM_LBUTTONUP handler that we complete the drag and drop process.


We first determine whether a drag

drop operation was in progress. This


is a good place to delete the image list object we created by calling CreateDragImage()


in OnBeginDrag() function. Before moving the branch we make sure that the


move is valid. The call to Expand() is normally not necessary, however,


if we implement dynamic loading, wherein the items are loaded only after


the parent is expanded then this call is important.



 
void CTreeCtrlX::OnLButtonUp(UINT nFlags, CPoint point) 
{
	CTreeCtrl::OnLButtonUp(nFlags, point);

	if (m_bLDragging)
	{
		m_bLDragging = FALSE;
		CImageList::DragLeave(this);
		CImageList::EndDrag();
		ReleaseCapture();

		delete m_pDragImage;

		// Remove drop target highlighting
		SelectDropTarget(NULL);

		if( m_hitemDrag == m_hitemDrop )
			return;

		// If Drag item is an ancestor of Drop item then return
		HTREEITEM htiParent = m_hitemDrop;
		while( (htiParent = GetParentItem( htiParent )) != NULL )
		{
			if( htiParent == m_hitemDrag ) return;
		}

		Expand( m_hitemDrop, TVE_EXPAND ) ;

		HTREEITEM htiNew = CopyBranch( m_hitemDrag, m_hitemDrop, TVI_LAST );
		DeleteItem(m_hitemDrag);
		SelectItem( htiNew );
	}

}
CodeGuru Logo

CodeGuru covers topics related to Microsoft-related software development, mobile development, database management, and web application programming. In addition to tutorials and how-tos that teach programmers how to code in Microsoft-related languages and frameworks like C# and .Net, we also publish articles on software development tools, the latest in developer news, and advice for project managers. Cloud services such as Microsoft Azure and database options including SQL Server and MSSQL are also frequently covered.

Property of TechnologyAdvice. © 2026 TechnologyAdvice. All Rights Reserved

Advertiser Disclosure: Some of the products that appear on this site are from companies from which TechnologyAdvice receives compensation. This compensation may impact how and where products appear on this site including, for example, the order in which they appear. TechnologyAdvice does not include all companies or all types of products available in the marketplace.