如何将程序中的内容“拖”到桌面或文件夹中(DoDragDrop高难度高分问题) 实现拖出,现在程序的“拖”数据源是Listview,具体的内容根据Listview选中的文件从ftp下载(这个无所谓,反正从其他地方来的,数据库的stream等等都可以,不同于普通文本拖放),希望拖放完毕,鼠标放开以后开始下载ftp的内容,并保存到本地,(从程序窗口中的listview拖到桌面等地方) 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 http://community.csdn.net/Expert/topic/5319/5319586.xml?temp=6.657046E-02 DoDragDrop好像是要本地文件夹存在,而且DoDragDrop本身好像是阻塞的方式。 如果能在DoDragDrop之后才开始下载数据,或者获得数据就比较好了,取巧的办法是先给个临时文件,然后再填充,但是总感觉应该有比较正统的做法,msdn上的做法是先到临时文件夹的 如果能在DoDragDrop之后得到目的文件夹,那就好办了,不知道有头绪么? 做法其实有了,但是想讨论更深入点,1、拖放前先建立临时文件,这个临时文件可以是很小的,做个样子而已,拖放结束以后开始下载,然后填充这个文件。一个小小的障眼法2、考虑不使用DoDragDrop,其实用DoDragDrop的目的很简单,主要是考虑两个,它能处理鼠标,比如说鼠标移动时候的光标不同,鼠标移过时对窗口的激活,最后就是判断拖放结束后鼠标所在位置是否可接收拖放等,这里可能需要用到不止一个API,而DoDragDrop就一个api搞定了,复杂度不用说,有点感觉本末倒置楼下继续 如果能在DoDragDrop之后得到目的文件夹,那就好办了,不知道有头绪么?获得鼠标起点的窗体句柄,可能是shell或者其他 仔细看了一下WinRar的拖放过程,应该是先拖放(至少看起来效果是这样的),然后读取数据到临时文件夹,最后真正拷贝到目的地 获得鼠标起点的窗体句柄,不太通用。我觉得应该有Shell的COM接口,但是没有找到是哪个…… 现在想起来,其实和rar一样就可以了,Delphi有套组件TDragDrop,它里面有个虚拟文件的示例,原理还没弄明白,感觉应该用DoDragDrop,其他的方式有点取巧的感觉,不知道是不是这样 我用DoDragDrop没有返回的时候(比如,正在下载文件到临时文件夹中等操作),接受拖动的Explorer窗口消息被阻塞。此时如果点击Explorer窗口就会发现提示忙碌。实在是……一直没有找出解决的方法(获得鼠标起点的窗体句柄,不太通用,不采用)。 如果有什么办法延迟就好了,让DoDragDrop先不要取数据,或者本身提供了这种机制? DoDragDrop先不要取数据?本身好像不提供这个机制吧?这个东东如果是异步就好了…… mfc倒是有这样的方法,不过不知道不用mfc怎么实现,纯api呢 顶下没错,COLEDataSource有Delay提交的方法,不知道api怎么实现,没看董源码 winrar 可能是先建立临时文件夹,那么拖放时可以提供一个对应的文件名 NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; *pResult = 0; if(GetSelectedCount()>0){ int iSels=GetSelectedCount(),iLen; LPTSTR pszFiles=new TCHAR[MAX_PATH*iSels]; if(pszFiles==NULL) return; GetSelItemPaths(pszFiles,&iLen); DROPFILES df; ZeroMemory(&df,sizeof(DROPFILES)); df.fWide=FALSE; df.pFiles=sizeof(DROPFILES); HGLOBAL hGlobal=GlobalAlloc(GMEM_FIXED,iLen+sizeof(DROPFILES)); memcpy(hGlobal,&df,sizeof(DROPFILES)); memcpy(((LPBYTE)hGlobal+sizeof(DROPFILES)),pszFiles,iLen); delete[] pszFiles; m_DragSource.CacheGlobalData(CF_HDROP,hGlobal); SetMiscFlag(MISC_SELFDRAG); SetMiscFlag(MISC_DRAGGING); DROPEFFECT rdf=m_DragSource.DoDragDrop(DROPEFFECT_COPY|DROPEFFECT_MOVE|DROPEFFECT_LINK|DROPEFFECT_SCROLL); CheckSelAvailable(); m_DragSource.Empty(); SetMiscFlag(MISC_DRAGGING,FALSE); } *pResult = 1; void CFileListCtrl::OnBegindrag(NMHDR* pNMHDR, LRESULT* pResult){ NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; *pResult = 0; if(GetSelectedCount()>0){ int iSels=GetSelectedCount(),iLen; LPTSTR pszFiles=new TCHAR[MAX_PATH*iSels]; if(pszFiles==NULL) return; GetSelItemPaths(pszFiles,&iLen); DROPFILES df; ZeroMemory(&df,sizeof(DROPFILES)); df.fWide=FALSE; df.pFiles=sizeof(DROPFILES); HGLOBAL hGlobal=GlobalAlloc(GMEM_FIXED,iLen+sizeof(DROPFILES)); memcpy(hGlobal,&df,sizeof(DROPFILES)); memcpy(((LPBYTE)hGlobal+sizeof(DROPFILES)),pszFiles,iLen); delete[] pszFiles; m_DragSource.CacheGlobalData(CF_HDROP,hGlobal); SetMiscFlag(MISC_SELFDRAG); SetMiscFlag(MISC_DRAGGING); DROPEFFECT rdf=m_DragSource.DoDragDrop(DROPEFFECT_COPY|DROPEFFECT_MOVE|DROPEFFECT_LINK|DROPEFFECT_SCROLL); CheckSelAvailable(); m_DragSource.Empty(); SetMiscFlag(MISC_DRAGGING,FALSE); } *pResult = 1;} void CFileListCtrl::OnDrop(COleDataObject *pDataObj,BOOL* pbRet){ CWaitCursor Cursor; CWnd* pWnd=GetParent(); if(pWnd==NULL) return; pWnd->KillTimer(2); *pbRet=FALSE; SetMiscFlag(MISC_DRAGGING,FALSE); if(ReadMiscFlag(MISC_SELFDRAG)&&GetSelectedCount()==0){ SetMiscFlag(MISC_SELFDRAG,FALSE); return; } SetMiscFlag(MISC_SELFDRAG,FALSE); if(m_pidlfItem==NULL) return; TCHAR szDst[MAX_PATH],szCurAddr[MAX_PATH]; SHGetPathFromIDList(m_pidlfItem,szCurAddr); if(GetSelectedCount()==1) GetSelItemPath(szDst); else _tcscpy(szDst,szCurAddr); CStringArray FileArray; FileArray.RemoveAll(); BOOL bMove=IsStatekeyPressed(VK_SHIFT),bCtrl=IsStatekeyPressed(VK_CONTROL); CMyOleDragDrop::GetFileData(pDataObj,FileArray); if(bMove&&bCtrl){ for(int i=0;i<FileArray.GetSize();i++) AddFileLinkItem(FileArray.GetAt(i),szDst,szCurAddr); }else{ if(FileArray.GetSize()>0) CopyFileItem(FileArray,szDst,szCurAddr,bMove); } FileArray.RemoveAll(); *pbRet=TRUE;} 谢谢楼上的兄弟COleDataSource 有延迟的方法,在codeproject有示例代码,但是现在要在其他语言,比如delphi和vb里面实现,所以最好用api的方式,没看懂mfc的原理,谢谢 改成用API应该不难吧,把MFC类的方法改成API调用就行了~ 谢谢楼上的兄弟COleDataSource 有延迟的方法,在codeproject有示例代码,但是现在要在其他语言,比如delphi和vb里面实现,所以最好用api的方式,没看懂mfc的原理,谢谢//////////////////////用VC做COM dll在Delphi或者VB中调用这个dll好了 不能用API,那样整个系统都被占用了,其他什么都干不成. TO chenybinCOleDataSource 有延迟的方法,在codeproject有示例代码==================指哪个链接?你看的是http://www.codeproject.com/shell/dropsourcehelpermfc.asp ? 自已处理吧,用SetCapture,然后用WindowFromPoint判断是桌面还是文件夹,再获取路径 看我的blog吧,这个拖放很容易的。http://blog.csdn.net/codewarrior/archive/2004/06/15/12039.aspxhttp://blog.csdn.net/codewarrior/archive/2004/06/15/12040.aspxhttp://blog.csdn.net/codewarrior/archive/2004/06/15/12041.aspx to codewarrior :非常感谢,这些文章已经看了很多次了,拖出去内容,如果本地不存在,确实有那么点难度,如果能借鉴rar的方式也可以,不过现在没搞定 继续迷茫中,主要还是想在Delphi中实现 windows的分配粒度是64k,为什么vc分配内存是连续的? 这个问题 搞的我郁闷几天了 高手来看看啊 请问用API方法怎样读取显卡、主板、硬盘的型号及网卡的MAC地址? 关于textout()输出,在线 关于installshield制作安装程序简单问题! 托盘图标为何一碰就消失?(在线!!!!!!) VB中调用VC的ACTIVEX出错(HELP!!!)! dbgrid的问题!我没分了,但你的回答对我狠重要! c++如何实现激活宽带连接的界面 菜鸟苯问题!着急的滋味不好受!! AppFace使用问题 求好用异步串口通信代码
1、拖放前先建立临时文件,这个临时文件可以是很小的,做个样子而已,拖放结束以后开始下载,然后填充这个文件。一个小小的障眼法2、考虑不使用DoDragDrop,其实用DoDragDrop的目的很简单,主要是考虑两个,它能处理鼠标,比如说鼠标移动时候的光标不同,鼠标移过时对窗口的激活,最后就是判断拖放结束后鼠标所在位置是否可接收拖放等,这里可能需要用到不止一个API,而DoDragDrop就一个api搞定了,复杂度不用说,有点感觉本末倒置楼下继续
一直没有找出解决的方法(获得鼠标起点的窗体句柄,不太通用,不采用)。
那么拖放时可以提供一个对应的文件名
*pResult = 0; if(GetSelectedCount()>0){
int iSels=GetSelectedCount(),iLen;
LPTSTR pszFiles=new TCHAR[MAX_PATH*iSels];
if(pszFiles==NULL)
return;
GetSelItemPaths(pszFiles,&iLen);
DROPFILES df;
ZeroMemory(&df,sizeof(DROPFILES));
df.fWide=FALSE;
df.pFiles=sizeof(DROPFILES); HGLOBAL hGlobal=GlobalAlloc(GMEM_FIXED,iLen+sizeof(DROPFILES));
memcpy(hGlobal,&df,sizeof(DROPFILES));
memcpy(((LPBYTE)hGlobal+sizeof(DROPFILES)),pszFiles,iLen);
delete[] pszFiles; m_DragSource.CacheGlobalData(CF_HDROP,hGlobal);
SetMiscFlag(MISC_SELFDRAG);
SetMiscFlag(MISC_DRAGGING);
DROPEFFECT rdf=m_DragSource.DoDragDrop(DROPEFFECT_COPY|DROPEFFECT_MOVE|DROPEFFECT_LINK|DROPEFFECT_SCROLL);
CheckSelAvailable();
m_DragSource.Empty();
SetMiscFlag(MISC_DRAGGING,FALSE);
}
*pResult = 1;
{
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
*pResult = 0; if(GetSelectedCount()>0){
int iSels=GetSelectedCount(),iLen;
LPTSTR pszFiles=new TCHAR[MAX_PATH*iSels];
if(pszFiles==NULL)
return;
GetSelItemPaths(pszFiles,&iLen);
DROPFILES df;
ZeroMemory(&df,sizeof(DROPFILES));
df.fWide=FALSE;
df.pFiles=sizeof(DROPFILES); HGLOBAL hGlobal=GlobalAlloc(GMEM_FIXED,iLen+sizeof(DROPFILES));
memcpy(hGlobal,&df,sizeof(DROPFILES));
memcpy(((LPBYTE)hGlobal+sizeof(DROPFILES)),pszFiles,iLen);
delete[] pszFiles; m_DragSource.CacheGlobalData(CF_HDROP,hGlobal);
SetMiscFlag(MISC_SELFDRAG);
SetMiscFlag(MISC_DRAGGING);
DROPEFFECT rdf=m_DragSource.DoDragDrop(DROPEFFECT_COPY|DROPEFFECT_MOVE|DROPEFFECT_LINK|DROPEFFECT_SCROLL);
CheckSelAvailable();
m_DragSource.Empty();
SetMiscFlag(MISC_DRAGGING,FALSE);
}
*pResult = 1;
}
{
CWaitCursor Cursor;
CWnd* pWnd=GetParent();
if(pWnd==NULL)
return;
pWnd->KillTimer(2);
*pbRet=FALSE;
SetMiscFlag(MISC_DRAGGING,FALSE);
if(ReadMiscFlag(MISC_SELFDRAG)&&GetSelectedCount()==0){
SetMiscFlag(MISC_SELFDRAG,FALSE);
return;
}
SetMiscFlag(MISC_SELFDRAG,FALSE);
if(m_pidlfItem==NULL)
return;
TCHAR szDst[MAX_PATH],szCurAddr[MAX_PATH];
SHGetPathFromIDList(m_pidlfItem,szCurAddr);
if(GetSelectedCount()==1)
GetSelItemPath(szDst);
else
_tcscpy(szDst,szCurAddr);
CStringArray FileArray;
FileArray.RemoveAll();
BOOL bMove=IsStatekeyPressed(VK_SHIFT),bCtrl=IsStatekeyPressed(VK_CONTROL); CMyOleDragDrop::GetFileData(pDataObj,FileArray);
if(bMove&&bCtrl){
for(int i=0;i<FileArray.GetSize();i++)
AddFileLinkItem(FileArray.GetAt(i),szDst,szCurAddr);
}else{
if(FileArray.GetSize()>0)
CopyFileItem(FileArray,szDst,szCurAddr,bMove);
}
FileArray.RemoveAll();
*pbRet=TRUE;
}
COleDataSource 有延迟的方法,在codeproject有示例代码,但是现在要在其他语言,比如delphi和vb里面实现,所以最好用api的方式,没看懂mfc的原理,谢谢
谢谢楼上的兄弟
COleDataSource 有延迟的方法,在codeproject有示例代码,但是现在要在其他语言,比如delphi和vb里面实现,所以最好用api的方式,没看懂mfc的原理,谢谢
//////////////////////
用VC做COM dll
在Delphi或者VB中调用这个dll好了
==================
指哪个链接?你看的是
http://www.codeproject.com/shell/dropsourcehelpermfc.asp ?
http://blog.csdn.net/codewarrior/archive/2004/06/15/12039.aspx
http://blog.csdn.net/codewarrior/archive/2004/06/15/12040.aspx
http://blog.csdn.net/codewarrior/archive/2004/06/15/12041.aspx
非常感谢,这些文章已经看了很多次了,拖出去内容,如果本地不存在,确实有那么点难度,如果能借鉴rar的方式也可以,不过现在没搞定