C++ 在MFC应用程序中接受CFSTR_FILECONTENTS/CFSTR_FILEDESCRIPTOR int DoDrop

C++ 在MFC应用程序中接受CFSTR_FILECONTENTS/CFSTR_FILEDESCRIPTOR int DoDrop,c++,mfc,drag-and-drop,C++,Mfc,Drag And Drop,我有一个MFC应用程序(VS2010),其中包含一个CScrollView,它使用ColedopTarget将自己注册为drop目标 这是可行的,我可以在OnDrop方法中检查丢弃数据的类型: BOOL CMyClass::DoDrop(COleDataObject *pDataObject, DROPEFFECT dropEffect, CPoint point) { if (pDataObject->IsDataAvailable(CF_DIB)) {

我有一个MFC应用程序(VS2010),其中包含一个CScrollView,它使用ColedopTarget将自己注册为drop目标

这是可行的,我可以在OnDrop方法中检查丢弃数据的类型:

BOOL CMyClass::DoDrop(COleDataObject *pDataObject,  DROPEFFECT dropEffect, CPoint point)
{
    if (pDataObject->IsDataAvailable(CF_DIB))
    {
        // Do something with DIB
    }
    else if (pDataObject->IsDataAvailable(CF_ENHMETAFILE) || pDataObject->IsDataAvailable(CF_METAFILEPICT))
    {
       // Do something with Metafiles
    }
    else if (pDataObject->IsDataAvailable(CF_HDROP))
    {
        // Do something with files
    }
    return FALSE;
}
这很有效。现在,我想把“虚拟文件”放到这个CScrollView中(从另一个应用程序),但我不知道怎么做。对于虚拟文件,我的意思是使用CFSTR\u FILECONTENTS/CFSTR\u FILEDESCRIPTOR 剪贴簿格式,并在需要时提供实际的数据流

为剪贴板提供虚拟文件非常简单(有教程,例如或), 但是在接收端(我的DoDrop方法),我不知道如何检索数据

提供虚拟文件的应用程序似乎可以工作(这意味着我可以将它们放到桌面上)

那么,有人能告诉我如何用MFC DoDrop方法从虚拟文件中获取数据吗

编辑:好的,下面的代码适合我:

FORMATETC fetc;
// m_cfstrFileContents is CLIPFORMAT retrieved with RegisterClipboardFormat(_T("FileContents"))
fetc.cfFormat=m_cfstrFileContents; 
fetc.dwAspect=DVASPECT_CONTENT;
fetc.lindex=0;
fetc.ptd=NULL;
fetc.tymed=TYMED_ISTREAM;

// Get file contents.
STGMEDIUM stgm;
if (!pDataObject->GetData(m_cfstrFileContents, &stgm, &fetc))
{
    // We don't have virtual file contents in the clipbord.
    return FALSE;
}
COleStreamFile file(stgm.pstm);
DWORD dwLength=file.GetLength();
LPSTR pszString=(LPSTR)_alloca(dwLength+1);
file.Seek(0, CFile::begin);
file.Read(pszString, dwLength);
pszString[dwLength]='\0';
// Either close the stream or release the storage medium, not both!
//file.Close(); 

ReleaseStgMedium(&stgm);

因此,pszString实际上指向传输文件的数据,任务已完成。

要接收数据,您应该能够使用
CFSTR\u FILEDESCRIPTOR
CFSTR\u FILECONTENTS
的ID调用
pDataObject->GetData()
(需要调用
RegisterClipboardFormat()
来获取ID)

这将使用获取虚拟数据所需的值填充您的
STGMEDIUM
结构,虚拟数据可以作为
IStream
提供,但也可以作为
HGLOBAL
等提供

处理完数据后,调用
ReleaseStgMedium()
函数以释放
STGMEDIUM
数据

这在MSDN上有记录:


谢谢@snowdude,我几乎成功了,只是在释放STGMEDIUM残骸时出现了一个无法解释的异常,你明白我为什么要得到它了吗?(如果没有,我可以提出另一个问题,专门询问此问题的解决方案)。找到解决方案后,我不能先关闭COleStream,然后释放存储介质,其中一个就足够了。@Daniel是的,如果您查看COleStreamFile::close()的代码,它会释放IStream指针。呼叫ReleaseStgMedium应该是首选方式。@remy lebeau谢谢你整理了我的答案。