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

fenex 2002-07-17 02:34:16
如何在CListView和CTreeView中实现拖拽功能?
...全文
215 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进行处理。

}

VC++经验技巧宝典配套代码06章 包括: 6.1窗体标题栏应用 0332闪烁标题栏的窗体 0333隐藏和显示标题栏 0334拖动没有标题栏的窗体 0335获取标题栏的内容 0336滚动的窗体标题栏 0337无标题对话框的拖动方法 6.2窗体的位置和大小控制 0339不可移动的窗体 0340始终在最上面的窗体 0341跟随鼠标移动的窗体 0342控制窗体的最大化最小化 0343判断窗体是否最小化在任务栏 0345限制窗体的大小 0346使用鼠标按键调整窗体大小 0347根据图片大小显示的窗体 0348获取当前鼠标点处的控件 6.3个性化窗体 0350半透明窗体 0351透明窗体 0352字型窗体 0353圆角窗体 0354以图片的形状显示窗体 0355应用程序背景与桌面融合 0356立体窗口阴影效果 6.4动画窗体界面 0357动画显示窗体 0358淡入淡出的窗体 0359如qq般隐藏的窗体 0360可横向伸展的对话框 0361可纵向伸展的对话框 0362调用office助手 0363屏幕滚动 0364在窗体显示彩虹文字字幕 0365在窗体实现文字横拉效果 0366在窗体实现万花筒效果 0367在窗体实现动画效果 6.5实用窗体技术 0368随即更换背景的窗体 0369显示欢迎窗体 0370显示关于窗体 0371不使用ESC键关闭窗体 0372关闭窗体前弹出确认对话框 0373在窗体显示前弹出登录对话框 0374设置对话框背景色 0375使用话刷绘制背景色 0376设置窗体颜色渐变 0377将对话框以位图形式保存到磁盘 0378在对话框显示HTML文件 0379在对话框创建视图 0380如何共享对话框资源 0381如何实现窗体继承 0384在对话框使用CDialogBar 6.6光标应用 0386十字光标定位 0387获得光标的位置坐标 0388限制光标的移动范围 6.7菜单应用 0392在系统菜单添加菜单项 0393带历史信息的菜单 0394设置菜单是否可用 0395为菜单添加核对标记 0396浮动的菜单 0397单击右键弹出菜单 0398可以下拉的菜单 0399任务栏图盘弹出菜单 0400绘制渐变效果的菜单 0401将菜单项的字体设置为粗体 6.8工具栏和状态栏应用 0402带背景的工具栏 0403在工具栏添加编辑框 0404具有提示功能的工具栏 0405工具栏按钮的热点效果 0406定义XP风格的工具栏 0407带进度条的状态栏 0408显示系统时间的状态栏 0409显示滚动字幕的状态栏 0410显示动画的状态栏 0411使状态栏随对话框的改变而改变 6.9文档视图结构应用 0412向视图放置控件 0413分割窗口 0414视图窗口的任意分割 0417滚动视图CScrollView类应用 0418树形视图CTreeView类应用 0419列表视图CListView类应用 0420HTML视图CHtmlView类应用 共78个例子

16,548

社区成员

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

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

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