1、MFC 编程一个具有拖拽功能的 TreeCtrl 2011-05-07 22:37:20| 分类: MFC 编程| 举报|字号 订阅#if !defined(AFX_DRAGTREE_H_3015F03F_045E_4531_A436_E2A890F23540_INCLUDED_)#define AFX_DRAGTREE_H_3015F03F_045E_4531_A436_E2A890F23540_INCLUDED_#if _MSC_VER 1000#pragma once#endif / _MSC_VER 1000/ DragTree.h : header file/ CDragTree w
2、indowclass CDragTree : public CTreeCtrl/ Constructionpublic:CDragTree();CImageList* m_pDragImages; /拖动的图像列表BOOL m_bDrag; /是否进行拖动HTREEITEM m_hBeginDrag; /拖动的起点/ Attributespublic:/ Operationspublic:/ Overrides/ ClassWizard generated virtual function overrides/AFX_VIRTUAL(CDragTree)/AFX_VIRTUAL/ Implem
3、entationpublic:void CopyNodes(HTREEITEM hDesItem, HTREEITEM hSrcItem);virtual CDragTree();/ Generated message map functionsprotected:/AFX_MSG(CDragTree)afx_msg void OnBegindrag(NMHDR* pNMHDR, LRESULT* pResult);afx_msg void OnMouseMove(UINT nFlags, CPoint point);afx_msg void OnLButtonUp(UINT nFlags,
4、CPoint point);/AFX_MSGDECLARE_MESSAGE_MAP();/AFX_INSERT_LOCATION/ Microsoft Visual C+ will insert additional declarations immediately before the previous line.#endif / !defined(AFX_DRAGTREE_H_3015F03F_045E_4531_A436_E2A890F23540_INCLUDED_)/ DragTree.cpp : implementation file/#include “stdafx.h“#incl
5、ude “DragTreeItem.h“#include “DragTree.h“#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE = _FILE_;#endif/ CDragTreeCDragTree:CDragTree()m_pDragImages = NULL;m_bDrag = FALSE;m_hBeginDrag = NULL;CDragTree:CDragTree()BEGIN_MESSAGE_MAP(CDragTree, CTreeCtrl)/AFX_MSG_MAP(CDragTree)
6、ON_NOTIFY_REFLECT(TVN_BEGINDRAG, OnBegindrag)ON_WM_MOUSEMOVE()ON_WM_LBUTTONUP()/AFX_MSG_MAPEND_MESSAGE_MAP()/ CDragTree message handlersvoid CDragTree:OnBegindrag(NMHDR* pNMHDR, LRESULT* pResult) NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;HTREEITEM hItem = pNMTreeView-itemNew.hItem; /获取开始拖动的节点i
7、f (hItem=GetRootItem() /不允许拖动根节点*pResult = 0;return;m_hBeginDrag = hItem; /记录开始拖动的项目m_pDragImages = CreateDragImage(hItem); /创建拖动的图像列表CPoint dragPT; /记录起始点dragPT.x = pNMTreeView-ptDrag.x;dragPT.y = pNMTreeView-ptDrag.y;if (m_pDragImages != NULL)m_pDragImages-BeginDrag(0, CPoint(8, 8); /开始拖动图像ClientT
8、oScreen( /转换客户坐标到屏幕坐标m_pDragImages-DragEnter(this, dragPT); /锁定窗口更新,在拖动的过程中显示拖动的图像SetCapture(); /开始鼠标捕捉m_bDrag = TRUE;*pResult = 0;void CDragTree:OnMouseMove(UINT nFlags, CPoint point) if (m_bDrag) /处于拖动状态HTREEITEM hItem;UINT nHitFlags;CRect clientRC;GetClientRect( /获取客户区域m_pDragImages-DragMove(poin
9、t); /设置拖动的图像位置/鼠标经过时高亮显示if( (hItem = HitTest(point, /隐藏拖动的图像SelectDropTarget(hItem); /设置选中的项目CImageList:DragShowNolock(TRUE); /显示拖动的图像elseCTreeCtrl:OnMouseMove(nFlags, point);void CDragTree:OnLButtonUp(UINT nFlags, CPoint point) if (m_bDrag) /处于拖动状态m_bDrag = FALSE;CImageList:DragLeave(this); /CImage
10、List:EndDrag(); /结束图像拖动ReleaseCapture(); /释放鼠标捕捉delete m_pDragImages; /释放图像列表m_pDragImages = NULL;CRect winRC;GetWindowRect( /获取窗口区域HTREEITEM hItem;if(hItem = HitTest(point, /进行节点的复制DeleteItem(m_hBeginDrag); /删除源节点Invalidate();SelectDropTarget(NULL);m_hBeginDrag = NULL;/复制节点,将 hSrcItem 及其子项目复制到下 hDe
11、sItem 节点下void CDragTree:CopyNodes(HTREEITEM hDesItem, HTREEITEM hSrcItem)if (hDesItem=NULL | hSrcItem=NULL) /验证参数return;TVITEM tvItem; /定义项目信息tvItem.mask = TVIF_TEXT|TVIF_IMAGE; /设置返回标记tvItem.hItem = hSrcItem;char chTextMAX_PATH = 0;tvItem.pszText = chText;tvItem.cchTextMax = MAX_PATH;GetItem( /获取项目
12、信息TVINSERTSTRUCT tvInsert; /定义插入操作的数据结构tvInsert.hParent = hDesItem;tvInsert.item = tvItem;HTREEITEM hInsert = InsertItem( /插入项目HTREEITEM hChild = GetChildItem(hSrcItem); /获取子节点while (hChild != NULL) /遍历子节点tvItem.mask = TVIF_TEXT|TVIF_IMAGE;tvItem.hItem = hChild;tvItem.pszText = chText;tvItem.cchTextMax = MAX_PATH;GetItem(tvInsert.hParent = hInsert;tvInsert.item = tvItem;CopyNodes(hInsert, hChild); /递归调用hChild = GetNextSiblingItem(hChild); /查找下一个兄弟节点