CTreeCtrl中拖曳(drag)

高人请进:请教如何实现在CTreeCtrl中的项目可以通过拖曳(drag)来改变排序(暂时只考虑一层节点)。

[问题点数:100分,结帖人:ilovesnow]

  • ilovesnow
  • (草根)
  • 等 级:
  • 结帖率:
楼主发表于:2004-05-11 17:12:04
如题:我定义了一个变量m_tree,它对应一个对话框中的Tree控件

请教如何实现在CTreeCtrl中的项目可以通过拖曳来改变排序(暂时只考虑一层节点)。
 
 
回复次数: 12

 

  • ugg用户头像
  • ugg
  • (逸学堂(hehexiao.co)
  • 等 级:
  • 3

#1楼 得分:14回复于:2004-05-11 17:35:53
自己写一个类吧。这是我下载的一个你看看吧
。h
class   CXTreeCtrl   :   public   CTreeCtrl
{
//   Construction
public:
CXTreeCtrl();

//   Attributes
public:

//   Operations
public:

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

//   Implementation
public:
virtual   ~CXTreeCtrl();

//   Generated   message   map   functions
protected:
UINT                     m_TimerTicks;             //´¦Àí¹ö¶¯µÄ¶¨Ê±Æ÷Ëù¾­¹ýµÄʱ¼ä
UINT                     m_nScrollTimerID;     //´¦Àí¹ö¶¯µÄ¶¨Ê±Æ÷
CPoint                 m_HoverPoint;             //Êó±êλÖÃ
UINT                     m_nHoverTimerID;       //Êó±êÃô¸Ð¶¨Ê±Æ÷
DWORD                   m_dwDragStart;           //°´ÏÂÊó±ê×ó¼üÄÇÒ»¿ÌµÄʱ¼ä
BOOL                     m_bDragging;               //±êʶÊÇ·ñÕýÔÚÍ϶¯¹ý³ÌÖÐ
CImageList*       m_pDragImage;             //Í϶¯Ê±ÏÔʾµÄͼÏóÁбí
HTREEITEM           m_hItemDragS;             //±»Í϶¯µÄ±êÇ©
HTREEITEM           m_hItemDragD;             //½ÓÊÜÍ϶¯µÄ±êÇ©
//{{AFX_MSG(CXTreeCtrl)
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   void   OnLButtonDown(UINT   nFlags,   CPoint   point);
afx_msg   void   OnTimer(UINT   nIDEvent);
//}}AFX_MSG

DECLARE_MESSAGE_MAP()
private:
HTREEITEM   CopyBranch(HTREEITEM   htiBranch,HTREEITEM   htiNewParent,HTREEITEM   htiAfter);
HTREEITEM   CopyItem(HTREEITEM   hItem,HTREEITEM   htiNewParent,HTREEITEM   htiAfter);
};
 
  • ugg用户头像
  • ugg
  • (逸学堂(hehexiao.co)
  • 等 级:
  • 3

#2楼 得分:14回复于:2004-05-11 17:37:01
。cpp如下
#include   "stdafx.h "
#include   "XTreeCtrl.h "

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

#define       DRAG_DELAY       60
/
//   CXTreeCtrl

CXTreeCtrl::CXTreeCtrl()
{
m_bDragging   =   false;
}

CXTreeCtrl::~CXTreeCtrl()
{
}


BEGIN_MESSAGE_MAP(CXTreeCtrl,   CTreeCtrl)
//{{AFX_MSG_MAP(CXTreeCtrl)
ON_NOTIFY_REFLECT(TVN_BEGINDRAG,   OnBegindrag)
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONUP()
ON_WM_LBUTTONDOWN()
ON_WM_TIMER()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/
//   CXTreeCtrl   message   handlers

void   CXTreeCtrl::OnBegindrag(NMHDR*   pNMHDR,   LRESULT*   pResult)  
{
NM_TREEVIEW*   pNMTreeView   =   (NM_TREEVIEW*)pNMHDR;
*pResult   =   0;

//Èç¹ûÊÇÎÞÒâÍÏÒ·£¬Ôò·ÅÆú²Ù×÷
if(   (GetTickCount()   -   m_dwDragStart)   <   DRAG_DELAY   )
return;

m_hItemDragS   =   pNMTreeView-> itemNew.hItem;
m_hItemDragD   =   NULL;

//&micro;&Atilde;&micro;&frac12;&Oacute;&Atilde;&Oacute;&Uacute;&Iacute;&Iuml;&para;&macr;&Ecirc;±&Iuml;&Ocirc;&Ecirc;&frac34;&micro;&Auml;&Iacute;&frac14;&Iuml;ó&Aacute;&ETH;±í
m_pDragImage   =   CreateDragImage(   m_hItemDragS   );
if(   !m_pDragImage   )
return;

m_bDragging   =   true;
m_pDragImage-> BeginDrag   (   0,CPoint(8,8)   );
CPoint     pt   =   pNMTreeView-> ptDrag;
ClientToScreen(   &pt   );
m_pDragImage-> DragEnter   (   this,pt   );     // "this "&frac12;&laquo;&Iacute;&Iuml;&Ograve;·&para;&macr;×÷&Iuml;&THORN;&Ouml;&AElig;&Ocirc;&Uacute;&cedil;&Atilde;&acute;°&iquest;&Uacute;
SetCapture();

m_nScrollTimerID   =   SetTimer(   2,40,NULL   );
}

void   CXTreeCtrl::OnMouseMove(UINT   nFlags,   CPoint   point)  
{
HTREEITEM     hItem;
UINT               flags;

//&frac14;ì&sup2;&acirc;&Ecirc;ó±ê&Atilde;&ocirc;&cedil;&ETH;&para;¨&Ecirc;±&AElig;÷&Ecirc;&Ccedil;·&ntilde;&acute;&aelig;&Ocirc;&Uacute;,&Egrave;&ccedil;&sup1;&ucirc;&acute;&aelig;&Ocirc;&Uacute;&Ocirc;ò&Eacute;&frac34;&sup3;&yacute;,&Eacute;&frac34;&sup3;&yacute;&ordm;ó&Ocirc;&Ugrave;&para;¨&Ecirc;±
if(   m_nHoverTimerID   )
{
KillTimer(   m_nHoverTimerID   );
m_nHoverTimerID   =   0;
}
m_nHoverTimerID   =   SetTimer(   1,800,NULL   );     //&para;¨&Ecirc;±&Icirc;&ordf;   0.8   &Atilde;&euml;&Ocirc;ò×&Ocirc;&para;&macr;&Otilde;&sup1;&iquest;&ordf;
m_HoverPoint   =   point;

if(   m_bDragging   )
{
CPoint     pt   =   point;
CImageList::DragMove(   pt   );

//&Ecirc;ó±ê&frac34;&shy;&sup1;&yacute;&Ecirc;±&cedil;&szlig;&Aacute;&Aacute;&Iuml;&Ocirc;&Ecirc;&frac34;
CImageList::DragShowNolock(   false   );     //±&Uuml;&Atilde;&acirc;&Ecirc;ó±ê&frac34;&shy;&sup1;&yacute;&Ecirc;±&Aacute;&ocirc;&Iuml;&Acirc;&Auml;&Ntilde;&iquest;&acute;&micro;&Auml;&ordm;&Ucirc;&frac14;&pound;
if(   (hItem   =   HitTest(point,&flags))   !=   NULL   )
{
SelectDropTarget(   hItem   );
m_hItemDragD   =   hItem;
}
CImageList::DragShowNolock(   true   );

//&micro;±&Igrave;&otilde;&Auml;&iquest;±&raquo;&Iacute;&Iuml;&Ograve;·&micro;&frac12;×ó±&szlig;&Ocirc;&micro;&Ecirc;±&pound;&not;&frac12;&laquo;&Igrave;&otilde;&Auml;&iquest;·&Aring;&Ocirc;&Uacute;&cedil;ù&Iuml;&Acirc;
CRect     rect;
GetClientRect(   &rect   );
if(   point.x   <   rect.left   +   20   )
m_hItemDragD   =   NULL;
}

CTreeCtrl::OnMouseMove(nFlags,   point);
}

 
  • ugg用户头像
  • ugg
  • (逸学堂(hehexiao.co)
  • 等 级:
  • 3

#3楼 得分:8回复于:2004-05-11 17:37:14
void   CXTreeCtrl::OnLButtonUp(UINT   nFlags,   CPoint   point)  
{
CTreeCtrl::OnLButtonUp(nFlags,   point);

if(   m_bDragging   )
{
m_bDragging   =   FALSE;
CImageList::DragLeave(   this   );
CImageList::EndDrag();
ReleaseCapture();
delete   m_pDragImage;

SelectDropTarget(   NULL   );

if(   m_hItemDragS   ==   m_hItemDragD   )
{
KillTimer(   m_nScrollTimerID   );
return;
}

Expand(   m_hItemDragD,TVE_EXPAND   );

HTREEITEM     htiParent   =   m_hItemDragD;
while(   (htiParent   =   GetParentItem(htiParent))   !=   NULL   )
{
if(   htiParent   ==   m_hItemDragS   )
{
HTREEITEM     htiNewTemp   =   CopyBranch(   m_hItemDragS,NULL,TVI_LAST   );
HTREEITEM     htiNew   =   CopyBranch(   htiNewTemp,m_hItemDragD,TVI_LAST   );
DeleteItem(   htiNewTemp   );
SelectItem(   htiNew   );
KillTimer(   m_nScrollTimerID   );
return;
}
}

HTREEITEM     htiNew   =   CopyBranch(   m_hItemDragS,m_hItemDragD,TVI_LAST   );
DeleteItem(   m_hItemDragS   );
SelectItem(   htiNew   );
KillTimer(   m_nScrollTimerID   );
}
}

//&iquest;&frac12;±&acute;&Igrave;&otilde;&Auml;&iquest;
HTREEITEM   CXTreeCtrl::CopyItem(HTREEITEM   hItem,   HTREEITEM   htiNewParent,   HTREEITEM   htiAfter)
{
TV_INSERTSTRUCT     tvstruct;
HTREEITEM                 hNewItem;
CString                     sText;

//&micro;&Atilde;&micro;&frac12;&Ocirc;&acute;&Igrave;&otilde;&Auml;&iquest;&micro;&Auml;&ETH;&Aring;&Iuml;&cent;
tvstruct.item.hItem   =   hItem;
tvstruct.item.mask     =   TVIF_CHILDREN|TVIF_HANDLE|TVIF_IMAGE|TVIF_SELECTEDIMAGE;
GetItem(   &tvstruct.item   );
sText   =   GetItemText(   hItem   );
tvstruct.item.cchTextMax   =   sText.GetLength   ();
tvstruct.item.pszText         =   sText.LockBuffer   ();

//&frac12;&laquo;&Igrave;&otilde;&Auml;&iquest;&sup2;&aring;&Egrave;&euml;&micro;&frac12;&ordm;&Iuml;&Ecirc;&Ecirc;&micro;&Auml;&Icirc;&raquo;&Ouml;&Atilde;
tvstruct.hParent                   =   htiNewParent;
tvstruct.hInsertAfter         =   htiAfter;
tvstruct.item.mask               =   TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_TEXT;
hNewItem   =   InsertItem(   &tvstruct   );
sText.ReleaseBuffer   ();

//&Iuml;&THORN;&Ouml;&AElig;&iquest;&frac12;±&acute;&Igrave;&otilde;&Auml;&iquest;&Ecirc;&yacute;&frac34;&Yacute;&ordm;&Iacute;&Igrave;&otilde;&Auml;&iquest;×&acute;&Igrave;&not;
SetItemData(   hNewItem,GetItemData(hItem)   );
SetItemState(   hNewItem,GetItemState(hItem,TVIS_STATEIMAGEMASK),TVIS_STATEIMAGEMASK);

return   hNewItem;
}

//&iquest;&frac12;±&acute;·&Ouml;&Ouml;§
HTREEITEM   CXTreeCtrl::CopyBranch(HTREEITEM   htiBranch,   HTREEITEM   htiNewParent,   HTREEITEM   htiAfter)
{
HTREEITEM     hChild;
HTREEITEM     hNewItem   =   CopyItem(   htiBranch,htiNewParent,htiAfter   );
hChild   =   GetChildItem(   htiBranch   );

while(   hChild   !=   NULL   )
{
CopyBranch(   hChild,hNewItem,htiAfter   );
hChild   =   GetNextSiblingItem(   hChild   );
}

return     hNewItem;
}

void   CXTreeCtrl::OnLButtonDown(UINT   nFlags,   CPoint   point)  
{
//&acute;&brvbar;&Agrave;í&Icirc;&THORN;&Ograve;&acirc;&Iacute;&Iuml;&Ograve;·
m_dwDragStart   =   GetTickCount();

CTreeCtrl::OnLButtonDown(nFlags,   point);
}

void   CXTreeCtrl::OnTimer(UINT   nIDEvent)  
{
//&Ecirc;ó±ê&Atilde;&ocirc;&cedil;&ETH;&frac12;&Uacute;&micro;&atilde;
if(   nIDEvent   ==   m_nHoverTimerID   )
{
KillTimer(   m_nHoverTimerID   );
m_nHoverTimerID   =   0;
HTREEITEM     trItem   =   0;
UINT     uFlag   =   0;
trItem   =   HitTest(   m_HoverPoint,&uFlag   );
if(   trItem   &&   m_bDragging   )
{
SelectItem(   trItem   );
Expand(   trItem,TVE_EXPAND   );
}
}
//&acute;&brvbar;&Agrave;í&Iacute;&Iuml;&Ograve;·&sup1;&yacute;&sup3;&Igrave;&Ouml;&ETH;&micro;&Auml;&sup1;&ouml;&para;&macr;&Icirc;&Ecirc;&Igrave;&acirc;
else   if(   nIDEvent   ==   m_nScrollTimerID   )
{
m_TimerTicks++;
CPoint     pt;
GetCursorPos(   &pt   );
CRect     rect;
GetClientRect(   &rect   );
ClientToScreen(   &rect   );

HTREEITEM     hItem   =   GetFirstVisibleItem();

if(   pt.y   <   rect.top   +10   )
{
//&Iuml;ò&Eacute;&Iuml;&sup1;&ouml;&para;&macr;
int     slowscroll   =   6   -   (rect.top   +   10   -   pt.y   )/20;
if(   0   ==   (m_TimerTicks   %   ((slowscroll   >   0)   ?   slowscroll   :   1))   )
{
CImageList::DragShowNolock   (   false   );
SendMessage(   WM_VSCROLL,SB_LINEUP   );
SelectDropTarget(   hItem   );
m_hItemDragD   =   hItem;
CImageList::DragShowNolock   (   true   );
}
}
else   if(   pt.y   >   rect.bottom   -   10   )
{
//&Iuml;ò&Iuml;&Acirc;&sup1;&ouml;&para;&macr;
int     slowscroll   =   6   -   (pt.y   -   rect.bottom   +   10)/20;
if(   0   ==   (m_TimerTicks   %   ((slowscroll   >   0)   ?   slowscroll   :   1))   )
{
CImageList::DragShowNolock   (   false   );
SendMessage(   WM_VSCROLL,SB_LINEDOWN   );
int     nCount   =   GetVisibleCount();
for(   int   i=0   ;   i <nCount-1   ;   i++   )
hItem   =   GetNextVisibleItem(   hItem   );
if(   hItem   )
SelectDropTarget(   hItem   );
m_hItemDragD   =   hItem;
CImageList::DragShowNolock   (   true   );
}
}
}
else
CTreeCtrl::OnTimer(nIDEvent);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值