如何将TreeView中的Item拖拽到视图中去 如何将TreeView中的Item拖拽到视图中去(在视图显示相应字符也可) 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 使用drag drop技术,在view中实现ondrop方法接收即可.参考dev.csdn.net/article/29/29185.shtmdev.csdn.net/article/29/29187.shtm 或者是左边有一个TreeView列出了一个目录下的文本文件,然后选中,拖拽到右边的视图上显示。 dev.csdn.net/article/29/29185.shtmdev.csdn.net/article/29/29187.shtmWWW.VCKBASE.COM//这查CREEVIEW会有例子程序 实在没有时间写一个例子,给你一些我的源码,你参考一下吧!主要有以下要点: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. }} OnMouseMove上面的注释。//必须使用OnMouseMove函数,才能保证LButtonUP函数能够在任何位置上都被响应。 呵呵,还是我自己来说吧。第一,在你view里面重载OnDragDrop,OnDragOver,OnDrop三个虚函数,用于处理接受拖放的操作。第二,在你的treectrl里面映射消息TVN_BEGINDRAG,在这里,你要完成的动作是:1,分析当前被拖动的是哪个item2,取得该item的数据,就是你想要拖动的数据,比如,你想把该item的名称拖过去,就取得该item名称。3,new一个COleDataSource对象,用该对象的CacheGlobalData函数把数据存进去,之后调用COleDataSource的DoDragDrop函数启动拖放。最后,在你的View里面刚刚重载的那三个函数里面处理接受拖放的动作。别忘记View要先向OLE注册可以接受拖放。 我的三篇文章在这里:dev.csdn.net/article/29/29185.shtmdev.csdn.net/article/29/29186.shtmdev.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;} 不过是关于ListCtrl的,你将就看吧,呵呵。 在View里 m_OleDropTarget.Register(this);我注册了呀,怎么oleDataSource->DoDragDrop(DROPEFFECT_MOVE|DROPEFFECT_COPY);View接受不到??? m_OleDropTarget.Register(this); 返回值为0 ,注册不成功 VS2010 字符集的问题 大神请指点一下关于网络编程服务器和客户端连接的问题 请教通过RTP和RTCP协议转发语音包问题。。。。。。 庆祝,终于完成对SOCKET的封装(Select模型)! 在线等,如果是高手,请帮我解决一个关于包含别人工程中类的问题。 如何判断一个进程没有响应和出现内存错? VC++中的一个困惑 MFC新手发问 Vector定义的二维数组应怎样遍历? 属性表单问题(急,在线等呀!!!!!!!!!) 新手:为什么VC的控件不可以在属性窗口里设置初始值呢? 超级郁闷的问题!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
参考
dev.csdn.net/article/29/29185.shtm
dev.csdn.net/article/29/29187.shtm
dev.csdn.net/article/29/29187.shtm
WWW.VCKBASE.COM//这查CREEVIEW会有例子程序
主要有以下要点:
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.
}
}
//必须使用OnMouseMove函数,才能保证LButtonUP函数能够在任何位置上都被响应。
第一,在你view里面重载OnDragDrop,OnDragOver,OnDrop三个虚函数,用于处理接受拖放的操作。
第二,在你的treectrl里面映射消息TVN_BEGINDRAG,在这里,你要完成的动作是:
1,分析当前被拖动的是哪个item
2,取得该item的数据,就是你想要拖动的数据,比如,你想把该item的名称拖过去,就取得该item名称。
3,new一个COleDataSource对象,用该对象的CacheGlobalData函数把数据存进去,之后调用COleDataSource的DoDragDrop函数启动拖放。最后,在你的View里面刚刚重载的那三个函数里面处理接受拖放的动作。别忘记View要先向OLE注册可以接受拖放。
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;
}
m_OleDropTarget.Register(this);
我注册了呀,怎么oleDataSource->DoDragDrop(DROPEFFECT_MOVE|DROPEFFECT_COPY);
View接受不到???