Class for drag-drop enabled TreeView

I wrote a base class from which the MFC users can derive their TreeView classes in a document-view based application instead of CTreeView. This class adds to CtreeView build-in drag-and-drop support.

All that the developer have to do is to add this class to the AppWizard generated project (with CTreeView as a View base class) and to replace the base of the view class from CTreeView to CTreeViewExt. After that, he/she has to overwrite the virtual functions of the base, which interface is self explantory.

That's all, the drag-and-drop tree view will be up and running !

Header file

#if !defined(AFX_TREEVIEWEXT_H__99D8F6F8_79F0_11D1_8DC6_0000E8125FE5__INCLUDED_)
#define AFX_TREEVIEWEXT_H__99D8F6F8_79F0_11D1_8DC6_0000E8125FE5__INCLUDED_

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
// TreeViewExt.h : header file
//

/////////////////////////////////////////////////////////////////////////////
// CTreeViewExt view

class CTreeViewExt : public CTreeView
{
protected:
	CTreeViewExt();           // protected constructor used by dynamic creation
	DECLARE_DYNCREATE(CTreeViewExt)

// Attributes
public:

// Operations
public:

// Overrides
	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CTreeViewExt)
	protected:
	virtual void OnDraw(CDC* pDC);      // overridden to draw this view
	//}}AFX_VIRTUAL

// Implementation
protected:
	HTREEITEM m_hDraggedItem;
	BOOL m_bDraggingNow;
	CImageList *m_pDragImageList;
	virtual ~CTreeViewExt();
#ifdef _DEBUG
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif

	// Generated message map functions
protected:
	virtual void CopyItemProperties(HTREEITEM hNewItem, HTREEITEM hDraggedItem);
	virtual BOOL IsItemCanBeDroppedOn(HTREEITEM hSource, HTREEITEM hTarget);
	virtual BOOL ItemCanBeDragged(HTREEITEM hItem);
	//{{AFX_MSG(CTreeViewExt)
	afx_msg void OnBegindrag(NMHDR* pNMHDR, LRESULT* pResult);
	afx_msg void OnMouseMove(UINT nFlags, CPoint point);
	afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_TREEVIEWEXT_H__99D8F6F8_79F0_11D1_8DC6_0000E8125FE5__INCLUDED_)

Implementation file

// TreeViewExt.cpp : implementation file
//

#include "stdafx.h"
#include "TreeViewExt.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CTreeViewExt

IMPLEMENT_DYNCREATE(CTreeViewExt, CTreeView)

CTreeViewExt::CTreeViewExt()
{
	m_bDraggingNow		= FALSE;
	m_hDraggedItem		= NULL;
	m_pDragImageList	= NULL;
}

CTreeViewExt::~CTreeViewExt()
{
}


BEGIN_MESSAGE_MAP(CTreeViewExt, CTreeView)
	//{{AFX_MSG_MAP(CTreeViewExt)
	ON_NOTIFY_REFLECT(TVN_BEGINDRAG, OnBegindrag)
	ON_WM_MOUSEMOVE()
	ON_WM_LBUTTONUP()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CTreeViewExt drawing

void CTreeViewExt::OnDraw(CDC* pDC)
{
	CDocument* pDoc = GetDocument();
	// TODO: add draw code here
}

/////////////////////////////////////////////////////////////////////////////
// CTreeViewExt diagnostics

#ifdef _DEBUG
void CTreeViewExt::AssertValid() const
{
	CTreeView::AssertValid();
}

void CTreeViewExt::Dump(CDumpContext& dc) const
{
	CTreeView::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CTreeViewExt message handlers

void CTreeViewExt::OnBegindrag(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;

	if (!m_bDraggingNow)
	{
		if (ItemCanBeDragged(pNMTreeView->itemNew.hItem))
		{
			CTreeCtrl& tree = GetTreeCtrl();
			tree.SetCapture();
			m_bDraggingNow = TRUE;
			m_hDraggedItem = pNMTreeView->itemNew.hItem;
			tree.Select(m_hDraggedItem, TVGN_CARET);
			m_pDragImageList = tree.CreateDragImage(m_hDraggedItem);
			m_pDragImageList->DragEnter(&tree, pNMTreeView->ptDrag);
			m_pDragImageList->BeginDrag(0, CPoint(0, 0));
		}
	}
	
	*pResult = 0;
}

void CTreeViewExt::OnMouseMove(UINT nFlags, CPoint point) 
{
	if (m_bDraggingNow)
	{
		CTreeCtrl& tree = GetTreeCtrl();
		m_pDragImageList->DragEnter(&tree, point);
		m_pDragImageList->DragMove(point);
	}
	
	CTreeView::OnMouseMove(nFlags, point);
}

void CTreeViewExt::OnLButtonUp(UINT nFlags, CPoint point) 
{
	if (m_bDraggingNow)
	{
		ReleaseCapture();

		m_bDraggingNow = FALSE;
		m_pDragImageList->EndDrag();
		delete m_pDragImageList;
		m_pDragImageList = NULL;

		CTreeCtrl& tree = GetTreeCtrl();
		UINT flags;
		HTREEITEM hTargetItem = tree.HitTest(point, &flags);
		if (hTargetItem != NULL && IsItemCanBeDroppedOn(m_hDraggedItem, hTargetItem))
		{
			HTREEITEM hNewItem = tree.InsertItem("Untitled", hTargetItem);
			CopyItemProperties(hNewItem, m_hDraggedItem);
			if (nFlags != MK_CONTROL)
				tree.DeleteItem(m_hDraggedItem);
		}	

		m_hDraggedItem = NULL;
	}
	
	CTreeView::OnLButtonUp(nFlags, point);
}

BOOL CTreeViewExt::ItemCanBeDragged(HTREEITEM hItem)
{
	return FALSE;
}

BOOL CTreeViewExt::IsItemCanBeDroppedOn(HTREEITEM hSource, HTREEITEM hTarget)
{
	return FALSE;
}

void CTreeViewExt::CopyItemProperties(HTREEITEM hNewItem, HTREEITEM hDraggedItem)
{

}



Comments

  • why not be easier

    Posted by Legacy on 03/13/2003 12:00am

    Originally posted by: Majun

    I think you should fully use the convenience of CView'drag&drop and COleDragTarget.
    
    

    just:
    class CYourDragDropView : public CView
    {
    //....
    COleDragTarget m_DragTarget;
    //....
    }

    void CYourDragDropView::OnCreate()
    {
    //....
    m_DragTarget.Register( this );
    //....
    }

    then override some virtual functions about drag&drop
    instead process mouse event.

    Reply
  • A sample found

    Posted by Legacy on 12/08/2002 12:00am

    Originally posted by: Alon Oren

    I found a sample at http://www.fairyengine.com/articles/dragdrop.htm

    Reply
  • Demo

    Posted by Legacy on 02/06/2002 12:00am

    Originally posted by: Giacomo

    What about to setup a Demo project?

    Reply
  • Droppping prohibited

    Posted by Legacy on 05/23/2000 12:00am

    Originally posted by: Rob

    I want the DragImage automaticly updated when dropping on the underlaying item is prohibited. So when the mouse is moved over an item where the dragged item can not be dropped, the prohibitory sign should be displayed on the dragimage. How should this be implemented ?

    Reply
  • Please clarify

    Posted by Legacy on 05/18/2000 12:00am

    Originally posted by: Merlin

    This may be good but I don't see anything concrete here.I tried coding this but...what's this? It doesn't drag..it doesn't do a thing.Perhaps, a working demo should be provided. Thank you for the author.

    Reply
  • It does'nt work

    Posted by Legacy on 02/22/2000 12:00am

    Originally posted by: narayana

    Do you have the demo ? It does not give any compilation errors but the operation is not happening.If i want to drag an item from tree ctrl to edit ctrl.How to do it ?If possible mail me asap.

    regars,
    AdinarayanaK

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • On-demand Event Event Date: January 28, 2015 Check out this webcast and join Jeff Sloyer, IBM Developer Evangelist and Master Inventor, for a tutorial for building cloud-based applications. Using IBM's platform as a service, Bluemix, Jeff will show you how to architect and assemble cloud-based applications built for cloud scale. Leveraging the power of microservices, developers can quickly translate monolithic applications to a cloud-based microarchitecture. This hour-long session introduces the concepts and …

  • Live Event Date: February 11, 2015 @ 1:00 p.m. ET / 10:00 a.m. PT New computing platforms, expanding information environments, recurrent security breaches and evolving regulatory frameworks are factors that security executives must contend with and address when developing their security strategy. In response to these dynamics, security executives are seeking stronger, more nimble and more pervasive security technologies to help protect business-critical information from unauthorized disclosure, loss or …

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date