如何将TreeView中的Item拖拽到视图中去

popofish2002 2004-07-22 06:34:23
如何将TreeView中的Item拖拽到视图中去(在视图显示相应字符也可)
...全文
312 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
liuxianzhi 2004-07-24
  • 打赏
  • 举报
回复
codewarrior:解答的不错!
popofish2002 2004-07-24
  • 打赏
  • 举报
回复
m_OleDropTarget.Register(this); 返回值为0 ,注册不成功
popofish2002 2004-07-23
  • 打赏
  • 举报
回复
在View里
m_OleDropTarget.Register(this);
我注册了呀,怎么oleDataSource->DoDragDrop(DROPEFFECT_MOVE|DROPEFFECT_COPY);
View接受不到???
ydfok 2004-07-23
  • 打赏
  • 举报
回复
楼上的说的不错

可是别忘记了也给我三分
我还差三分 就可以长一个角了~~~~~~

接分~~~~
会思考的草 2004-07-23
  • 打赏
  • 举报
回复
不过是关于ListCtrl的,你将就看吧,呵呵。
会思考的草 2004-07-23
  • 打赏
  • 举报
回复
我的三篇文章在这里:
dev.csdn.net/article/29/29185.shtm
dev.csdn.net/article/29/29186.shtm
dev.csdn.net/article/29/29187.shtm

我的例子:
void CThumbnailListCtrl::OnBeginDrag(NMHDR* /*pNMHDR*/, LRESULT* pResult)
{
UINT uBufferSize = 0;
HGLOBAL hMemData = NULL;
POSITION pItemPos = NULL;
DROPEFFECT DropResult = 0;
CStringList strlstSelected;
LPDROPFILES lpDropFiles = NULL;

//首先取得当前选中的lvItem对应的实际文件路径,存入strlstSelected中
pItemPos = GetFirstSelectedItemPosition();
if(pItemPos == NULL)
{
TRACE0("No items were selected!\n");
}
else
{
while(pItemPos != NULL)
{
int nItem = GetNextSelectedItem(pItemPos);
PLVITEM_EXINFO pItemInfo = (PLVITEM_EXINFO)GetItemData(nItem);

strlstSelected.AddTail(CString(pItemInfo->szPath));
uBufferSize += lstrlen(pItemInfo->szPath) + 1; //累加长度
}
}

//只有拖放操作失败时,才可以在本函数内释放该内存块.如果
//拖放操作成功,该内存块将由最终接受拖放的窗口负责销毁.
uBufferSize += sizeof(DROPFILES) + 1;
hMemData = GlobalAlloc(GPTR, uBufferSize);
ASSERT(hMemData != NULL);

//设置相关成员
lpDropFiles = (LPDROPFILES)GlobalLock(hMemData);
ASSERT(lpDropFiles != NULL);
lpDropFiles->pFiles = sizeof(DROPFILES);
#ifdef _UNICODE
lpDropFiles->fWide = TRUE;
#else
lpDropFiles->fWide = FALSE;
#endif

//把选中的所有文件名依次复制到DROPFILES结构体后面(全局内存中)
pItemPos = strlstSelected.GetHeadPosition();
TCHAR* pszStart = (TCHAR*)((LPBYTE)lpDropFiles + sizeof(DROPFILES));
while(pItemPos != NULL)
{
lstrcpy(pszStart, (LPCTSTR)strlstSelected.GetNext(pItemPos));
pszStart = strchr(pszStart,'\0')+ 1; //下次的起始位置是上一次结尾+1
}

m_nLandPos = -1;
m_bDragStart = TRUE;

//缓存数据
m_DataSource.Empty();
m_DataSource.CacheGlobalData(CF_HDROP, hMemData);

//启动拖放,注意该函数是等到拖放操作结束才会返回.
DropResult = m_DataSource.DoDragDrop(DROPEFFECT_MOVE|DROPEFFECT_COPY);
GlobalUnlock(hMemData);

//注意下面这两行是不能省的.因为DoDragDrop函数并不是立即返回的,只有拖放操作结束
//之后才返回.并且在返回之前,COleDropTarge的OnDrop函数会被调用,在那里我们是用
//m_bDragStart来判断此次拖放是否是一个内部拖放操作.如果此处不把m_bDragStart
//设为FALSE,最后一次的Insertion Mark将不会被擦除.同时,也不能把这两句写在OnDrop
//里.因为一旦不是内部拖放,那么m_bDragStart和m_nLandPos就没有设置为正确的值.
m_nLandPos = -1;
m_bDragStart = FALSE;

//注意我们在OnDrop函数中处理完毕内部拖放,是返回TRUE的,亦即表示
//整个拖放操作是成功的,因此DoDragDrop函数不可能会返回DROPEFFECT_NONE
switch(DropResult)
{
case DROPEFFECT_COPY: //按下Ctrl键进行内部拖放会返回COPY
{
//注意这里无须进行处理.如果是内部拖放(m_bDropHere==TRUE),我们自不必理会,
//如果不是内部拖放,Windows已经为我们完成了复制文件的动作,所以我们也不用理会.
break;
}

case DROPEFFECT_MOVE: //不按下Ctrl键进行内部拖放会返回MOVE
{
if(!m_bDropHere) //不是内部拖放
{
CheckDragOperation();
}
break;
}

case DROPEFFECT_NONE:
{
//如前所述,返回DROPEFFECT_NONE绝不可能是内部拖放动作,在NT/2000中,
//拖放失败或者剪切操作成功,都返回DROPEFFECT_NONE(参见MS知识库Q182219),
//如果剪切成功,因为Windows已经代我们完成了删除源文件的动作,所以必须要
//通过判断源文件是否要存在来甄别剪切操作成功与否.如果成功,我们必须要删除
//源文件在ListCtrl中对应的lvItem.
if(IsNT())
{
CheckDragOperation();
}
else //在9x中,返回DROPEFFECT_NONE表示拖放失败
{
MessageBox("拖放失败!","错误", MB_OK+MB_ICONERROR);
GlobalUnlock(hMemData);
GlobalFree(hMemData);
}
break;
}

default:
{
break;
}
}

*pResult = 0;
}
会思考的草 2004-07-23
  • 打赏
  • 举报
回复
呵呵,还是我自己来说吧。
第一,在你view里面重载OnDragDrop,OnDragOver,OnDrop三个虚函数,用于处理接受拖放的操作。
第二,在你的treectrl里面映射消息TVN_BEGINDRAG,在这里,你要完成的动作是:
1,分析当前被拖动的是哪个item
2,取得该item的数据,就是你想要拖动的数据,比如,你想把该item的名称拖过去,就取得该item名称。
3,new一个COleDataSource对象,用该对象的CacheGlobalData函数把数据存进去,之后调用COleDataSource的DoDragDrop函数启动拖放。

最后,在你的View里面刚刚重载的那三个函数里面处理接受拖放的动作。别忘记View要先向OLE注册可以接受拖放。
liuxianzhi 2004-07-23
  • 打赏
  • 举报
回复
OnMouseMove上面的注释。
//必须使用OnMouseMove函数,才能保证LButtonUP函数能够在任何位置上都被响应。
liuxianzhi 2004-07-23
  • 打赏
  • 举报
回复
上面的注释都编程乱码了,没有什么用,看代码吧!
liuxianzhi 2004-07-23
  • 打赏
  • 举报
回复
实在没有时间写一个例子,给你一些我的源码,你参考一下吧!
主要有以下要点:
1.重载Tree的三个函数OnLButtonDown、OnMouseMove、OnBegindrag,拷贝我下面的函数实现方法即可。

============================
void CTaxonomyTree::OnLButtonDown(UINT nFlags, CPoint point)
{
UINT uFlags;
HTREEITEM hItem = HitTest(point, &uFlags);
m_sCurrentTaxonomyNode = "";
if ((hItem != NULL) && (TVHT_ONITEM & uFlags))
{
Select(hItem, TVGN_CARET);
CString sValue;
m_sCurrentTaxonomyNode = GetItemText(hItem);
}
SetCapture();

CTreeCtrl::OnLButtonDown(nFlags, point);
}
//±ØÐëʹÓÃOnMouseMoveº¯Êý£¬²ÅÄܱ£Ö¤LButtonUPº¯ÊýÄܹ»ÔÚÈκÎλÖÃÉ϶¼±»ÏìÓ¦¡£
void CTaxonomyTree::OnMouseMove(UINT nFlags, CPoint point)
{
CTreeCtrl::OnMouseMove(nFlags, point);
}

void CTaxonomyTree::OnBegindrag(NMHDR* pNMHDR, LRESULT* pResult)
{
if(!m_pTRSRECListView->IsWindowVisible())
{
return ;
}
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
// TODO: Add your control notification handler code here
HCURSOR hcursor;
hcursor=AfxGetApp()->LoadCursor(IDC_DRAG);
::SetCursor(hcursor);
SetCapture();

*pResult = 0;
}

2:重载Tree的OnLButtonUp,判断当前鼠标up的点是否落在你想要的view区域内。
如下面的例子中,m_pListView->m_TreeRecords是表示一个普通View里面的一个treectrl,我是要把TaxonomyTree中的节点拖放到m_pListView->m_TreeRecords树的节点。

void CTaxonomyTree::OnLButtonUp(UINT nFlags, CPoint point)
{
if(!m_pListView->IsWindowVisible())
{
return ;
}

//Ϊ¼Ç¼¸ÅÀÀ´°¿ÚÖеļǼÉ趨·ÖÀàÐÅÏ¢
CPoint pot=point;
ClientToScreen(&pot);
m_pListView->m_TreeRecords.ScreenToClient(&pot);
CRect rect;
m_pListView->GetClientRect(rect);
if(rect.PtInRect(pot)){
//do what you want here.
}
}
popofish2002 2004-07-23
  • 打赏
  • 举报
回复
有没有完整的例子阿,急~~~~~~~~~~~~~~~~~~~~~~~~~~~~
popofish2002 2004-07-22
  • 打赏
  • 举报
回复
还是不太清楚,望大家多多赐教
名牌大灰狼 2004-07-22
  • 打赏
  • 举报
回复
dev.csdn.net/article/29/29185.shtm
dev.csdn.net/article/29/29187.shtm
WWW.VCKBASE.COM//这查CREEVIEW会有例子程序
popofish2002 2004-07-22
  • 打赏
  • 举报
回复
CSDN 的"文档"我点不进去
popofish2002 2004-07-22
  • 打赏
  • 举报
回复
或者是左边有一个TreeView列出了一个目录下的文本文件,然后选中,拖拽到右边的视图上显示。
gracezhu 2004-07-22
  • 打赏
  • 举报
回复
使用drag drop技术,在view中实现ondrop方法接收即可.
参考
dev.csdn.net/article/29/29185.shtm
dev.csdn.net/article/29/29187.shtm

15,978

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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