游戏技术文章

【控件专题】一个具有拖拽功能的TreeCtrl

时间:2016-12-19 12:59:49  作者:棋牌资源网  来源:棋牌资源网  查看:7795  评论:0
内容摘要:#if !defined(AFX_DRAGTREE_H__3015F03F_045E_4531_A436_E2A890F23540__INCLUDED_)#define AFX_DRAGTREE_H__3015F03F_045E_4531_A436_E2A890F23540__I...
#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 window

class CDragTree : public CTreeCtrl
{
// Construction
public:
 CDragTree();
 
 CImageList*  m_pDragImages; //拖动的图像列表
 BOOL m_bDrag;    //是否进行拖动
 HTREEITEM  m_hBeginDrag; //拖动的起点
// Attributes
public:

// Operations
public:

// Overrides
 // ClassWizard generated virtual function overrides
 //{{AFX_VIRTUAL(CDragTree)
 //}}AFX_VIRTUAL

// Implementation
public:
 void CopyNodes(HTREEITEM hDesItem, HTREEITEM hSrcItem);
 virtual ~CDragTree();

 // Generated message map functions
protected:
 //{{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, CPoint point);
 //}}AFX_MSG

 DECLARE_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"
#include "DragTreeItem.h"
#include "DragTree.h"

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

/////////////////////////////////////////////////////////////////////////////
// CDragTree

CDragTree::CDragTree()
{
 m_pDragImages = NULL;
 m_bDrag = FALSE;
 m_hBeginDrag = NULL;
}

CDragTree::~CDragTree()
{
}


BEGIN_MESSAGE_MAP(CDragTree, CTreeCtrl)
 //{{AFX_MSG_MAP(CDragTree)
 ON_NOTIFY_REFLECT(TVN_BEGINDRAG, OnBegindrag)
 ON_WM_MOUSEMOVE()
 ON_WM_LBUTTONUP()
 //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDragTree message handlers

void CDragTree::OnBegindrag(NMHDR* pNMHDR, LRESULT* pResult) 
{
 NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
 HTREEITEM hItem = pNMTreeView->itemNew.hItem;  //获取开始拖动的节点
 if (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));  //开始拖动图像
  ClientToScreen(&dragPT);      //转换客户坐标到屏幕坐标
  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(&clientRC);      //获取客户区域
  m_pDragImages->DragMove(point);     //设置拖动的图像位置
  //鼠标经过时高亮显示
  if( (hItem = HitTest(point, &nHitFlags)) != NULL )
  {
   CImageList::DragShowNolock(FALSE);   //隐藏拖动的图像
   SelectDropTarget(hItem);     //设置选中的项目
   CImageList::DragShowNolock(TRUE);   //显示拖动的图像
  }
 }
 else
  CTreeCtrl::OnMouseMove(nFlags, point);
}

void CDragTree::OnLButtonUp(UINT nFlags, CPoint point) 
{
 if (m_bDrag)          //处于拖动状态
 {
  m_bDrag = FALSE;
  CImageList::DragLeave(this);     //
  CImageList::EndDrag();       //结束图像拖动
  ReleaseCapture();        //释放鼠标捕捉
  delete m_pDragImages;       //释放图像列表
  m_pDragImages = NULL;
  CRect winRC;
  GetWindowRect(&winRC);       //获取窗口区域
  HTREEITEM hItem;
  if((hItem = HitTest(point, &nFlags)) != NULL)
  {
   //进行拖动处理
   //如果目标项目与开始拖动的项目相同或者目标项目仍是开始项目的父节点,不进行处理
   if (m_hBeginDrag != hItem && hItem != GetParentItem(m_hBeginDrag))
   {
    CopyNodes(hItem, m_hBeginDrag);   //进行节点的复制
    DeleteItem(m_hBeginDrag);    //删除源节点
   }
   Invalidate();
   SelectDropTarget(NULL);
   m_hBeginDrag = NULL;
  }
 }
}

//复制节点,将hSrcItem及其子项目复制到下hDesItem节点下
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 chText[MAX_PATH] = {0};
 tvItem.pszText = chText;
 tvItem.cchTextMax = MAX_PATH;
 GetItem(&tvItem);         //获取项目信息
 TVINSERTSTRUCT tvInsert;       //定义插入操作的数据结构
 tvInsert.hParent = hDesItem;
 tvInsert.item = tvItem;
 HTREEITEM hInsert = InsertItem(&tvInsert);   //插入项目
 HTREEITEM hChild = GetChildItem(hSrcItem);   //获取子节点
 while (hChild != NULL)        //遍历子节点
 {
  tvItem.mask = TVIF_TEXT|TVIF_IMAGE;
  tvItem.hItem = hChild;
  tvItem.pszText = chText;
  tvItem.cchTextMax = MAX_PATH;
  GetItem(&tvItem);
  tvInsert.hParent = hInsert;
  tvInsert.item = tvItem;
  CopyNodes(hInsert, hChild);      //递归调用
  hChild = GetNextSiblingItem(hChild);   //查找下一个兄弟节点 
 }
}

标签:【控件专题】一个具有拖拽功能的TreeCtrl 

欢迎加入VIP,【VIP售价:只要288元永久VIP会员】畅享商业棋牌游戏程序下载,点击开通!

下载说明


☉本站所有源码和资源均由站长亲自测试-绝对保证都可以架设,运营!
☉如源码和资源有损坏或所有链接均不能下载,请告知管理员,

☉本站软件和源码大部分为站长独资,资源购买和收集,放心下载!

☉唯一站长QQ:1004003180  [人格担保-本站注重诚信!]

☉购买建议E-mail:1004003180@qq.com   源码收购 E-mail:1004003180@qq.com    

☉本站文件解压密码  【文章内都自带解压密码,每个密码不同!】


本站提供的所有源码,均来源站长提供,仅学习交流 浙ICP备09009969号

由此产生不良后果和法律责任与本站无关,如果侵犯了您的版权,请来信告知 1004003180@qq.com 将及时更正和删除! 

Copyright © 2008-2022 棋牌资源网,你身边的棋牌资源下载站    All Rights Reserved