如何在CListView和CTreeView中实现拖拽功能?

fenex 2002-07-17 02:34:16
如何在CListView和CTreeView中实现拖拽功能?
...全文
210 2 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
fenex 2002-10-08
  • 打赏
  • 举报
回复
这是我7月份的帖子,这个问题很久以前就已经解决了,不过还是要谢谢你!
shanhe 2002-10-04
  • 打赏
  • 举报
回复
可以使用Drag&Drop的CTreeView
闻怡洋译

--------------------------------------------------------------------------------

CTreeViewExt是MFC使用者可重用的类,该类由CTreeView派生,可以用在文档-视结构的应用程序中,并且支持Drag&Drop。

使用者所需要做的仅仅是将文件加到AppWizard产生的工程中,(CTreeView为基类)并且将CTreeView替换为CTreeViewExt。并重载三个Virtual Function。

WenYY:这很简单吧,下面是源代码,我会在必要的地方加上注释,但由于原作者并未加,所以如果有出入请原谅,作者定义了三处虚拟函数,其作用是让使用者重载后,加入自己的判断条件和结果处理的功能,很巧妙的思想:

CopyItemProperties
IsItemCanBeDroppedOn(HTREEITEM hSource, HTREEITEM hTarget);
BOOL ItemCanBeDragged(HTREEITEM hItem);//检查是否可以对该ITEM实施Drag&Drop


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);//检查是否可以对该ITEM实施Drag&Drop

//{{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))

{//查询条件,是否允许Drag&Drop

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))

{//查询是否可以成功完成,条件是开始时选中的Item和结束使选中的ITEM是否满足你的条件

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)
{//按照你的需要对两个ITEM进行处理。

}

16,548

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • AIGC Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧