我要从我的列表控件中把所显示的文件拖放到比如桌面上,但当我的拖放函数如begindrag()中操作时间较长时就无法完成拖动,我用的是即使方式,函数是CacheGlobalData(),查了一下资料好象要用延迟方式DelayRenderData(),但具体怎么做小弟还是无从下手,哪位兄弟有这方面的经验不吝赐教,小弟万分感激!!!!!!!
解决方案 »
- 打印视图上控件中的内容
- CTimeSpan难道只有一种赋值方法吗?
- 对Tls了解的兄弟进来看看
- smtp怎样发送附件
- 获得另一对话框的数据???
- #import "C:\\Program Files (x86)\\Microsoft Office..." 能动态处理么
- 如何将程序传送到另一台机,并自动运行?(我可不是要做病毒)
- OnTimer()只要按到20多次都出错了!!!!有哪位高手能帮助解决一下吗?谢谢
- 怎样写调用回调函数的DLL?
- 我想开一家软件公司,寻志同道合的计算机高手???
- 请问十六进制的数如何转化为字符型数据,如果说0x5A 转为Z
- 有谁做过wavecom gprs模块的stk(sim toolkit)的开发
不过,你要拖放到桌面上,那么是否有一定的剪贴版格式呢?
UINT uBuffSize = 0; char sFile[MAX_PATH];
memset(sFile,'\0',MAX_PATH); m_ctrl.GetItemText(0,0,sFile,MAX_PATH);
uBuffSize += lstrlen(sFile) + 1; int n=sizeof(DROPFILES);
uBuffSize = sizeof(DROPFILES) + (uBuffSize + 1); HANDLE hData = ::GlobalAlloc(GHND, uBuffSize);
LPDROPFILES pDropFiles = (LPDROPFILES)::GlobalLock(hData);
pDropFiles->pFiles = sizeof(DROPFILES);
pDropFiles->fWide = FALSE;
char *pData = (char*)((LPBYTE)pDropFiles + sizeof(DROPFILES));
lstrcpy(pData, sFile);
// ppData = 1 + _tcschr(ppData, '\0');
::GlobalUnlock(hData); COleDataSourceEx src;
src.CacheGlobalData(CF_HDROP, hData); DROPEFFECT de = src.DoDragDrop(DROPEFFECT_COPY); //实现拖入回收站
IDataObject *piDataObject = (IDataObject*)src.GetInterface(&IID_IDataObject); IEnumFORMATETC *piefEtc;
HRESULT hr = piDataObject->EnumFormatEtc(DATADIR_GET, &piefEtc);
if(SUCCEEDED(hr))
{
hr = piefEtc->Reset();
if(SUCCEEDED(hr))
{
FORMATETC fEtc;
ULONG ulFetched = 0L;
while(1)
{
hr = piefEtc->Next(DATADIR_GET, &fEtc, &ulFetched);
if(FAILED(hr) || ulFetched <= 0)
break;
CString sFormat;
if(GetClipboardFormatName(fEtc.cfFormat, sFormat.GetBuffer(60), 60) && sFormat == CFSTR_TARGETCLSID)
{
STGMEDIUM sm;
hr = piDataObject->GetData(&fEtc, &sm);
if(SUCCEEDED(hr))
{
CLSID clsid;
BYTE *pData = (BYTE*)::GlobalLock(sm.hGlobal);
memcpy(&clsid, pData, 16);
::GlobalUnlock(sm.hGlobal);
if(clsid == CLSID_RecycleBin)
{
UINT uuBuffSize;
uuBuffSize = strlen(sFile) + 1; char *ppData = new char[uuBuffSize];
lstrcpy(ppData,sFile); SHFILEOPSTRUCT op;
op.wFunc = FO_DELETE;
op.hwnd = NULL;
op.pFrom = ppData;
op.pTo = NULL;
op.fFlags = FOF_ALLOWUNDO|FOF_NOCONFIRMATION;
int nResult = SHFileOperation(&op);
delete ppData;
} }
}
}
}
piefEtc->Release();
}
while(src.m_dwRef > 1)
src.InternalRelease();比如上面写的程序可以完成拖放,但当我加上 Sleep(5000);就不能拖动文件,这是为什么呢,望高手指点,谢谢!!!!
void CListCtrlEx::OnBegindrag(NMHDR* pNMHDR, LRESULT* pResult)
{
int nItem = 0;
int nSize = sizeof(DROPFILES);
UINT uBufferSize = 0;
char* pszStart = NULL; //存放文件名的起始位置
HGLOBAL hMemData = NULL;
POSITION pItemPos = NULL;
DROPEFFECT DropResult = DROPEFFECT_NONE;
CStringList strSelectedList;
LPDROPFILES lpDropFiles = NULL;
Sleep(5000); //获取当前选定的项
pItemPos = GetFirstSelectedItemPosition();
if(pItemPos == NULL)
{
TRACE0("No items were selected!");
return;
}
else
{
while(pItemPos)
{
nItem = GetNextSelectedItem(pItemPos);
strSelectedList.AddTail(GetItemText(nItem,0));
uBufferSize += lstrlen(GetItemText(nItem,0))+1; //累加每个Item长度
}
}
uBufferSize = sizeof(DROPFILES) + uBufferSize + 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 = strSelectedList.GetHeadPosition();
pszStart = (char*)((LPBYTE)lpDropFiles + sizeof(DROPFILES));
while(pItemPos != NULL)
{
lstrcpy(pszStart, (LPCTSTR)strSelectedList.GetNext(pItemPos));
pszStart = strchr(pszStart,'\0') + 1; //下次的起始位置是上一次结尾+1
}
//用COleDataSource缓存数据,启动拖放
m_oleDataSource.Empty();
m_oleDataSource.CacheGlobalData(CF_HDROP, hMemData);
DropResult = m_oleDataSource.DoDragDrop(DROPEFFECT_MOVE|DROPEFFECT_COPY);
switch(DropResult)
{
case DROPEFFECT_MOVE:
case DROPEFFECT_COPY:
break; //注意在NT/2000中,DROPEFFECT_MOVE会返回DROPEFFECT_NONE,参见Q182219
case DROPEFFECT_NONE:
//如果是NT,就删除Item,否则表明失败
break; default:
break;
}
GlobalUnlock(hMemData);
*pResult = 0;
}
另外,Windows有一个小bug,使用OLE拖放的时候,如果调用 COleDataSource::DelayRenderFileData()而没有制定第二个参数(为NULL),则OleDataSource::OnRenderFileData()将不会被调用来得到实际的数据。
详情和解决方案请看MS知识库:Q185675