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: December 18, 2014 The Internet of Things (IoT) incorporates physical devices into business processes using predictive analytics. While it relies heavily on existing Internet technologies, it differs by including physical devices, specialized protocols, physical analytics, and a unique partner network. To capture the real business value of IoT, the industry must move beyond customized projects to general patterns and platforms. Check out this webcast and join industry experts as …

  • The hard facts on SaaS adoption in over 80,000 enterprises: Public vs. private companies Mid-market vs. large enterprise GoogleApps, Office365, Salesforce & more Why security is a growing concern Fill out the form to download the full cloud adoption report.

Most Popular Programming Stories

More for Developers

RSS Feeds