Discussion:
Does format CFSTR_FILECONTENTS will be worked for drag a virtual folder object to explorer ?
(too old to reply)
unknown
2009-11-25 14:08:18 UTC
Permalink
I've implemented a NSE for browses the content of virtual folder (virtual file system) using Windows Explorer in XP platform. To provide friendly functionality for user, Drag-And-Drop function is necessary and important feature. Format CF_HDROP can't be used for drag and drop a virtual file/folder object. Format CFSTR_SHELLIDLIST is able to use in Vista and 7 because of explorer will asks ITransferxxx interface from our NSE after explorer received IDataObject which contains CFSTR_SHELLIDLIST only, and then drop operation will be done if I implement ITransferxxx. But in XP platform, seems explorer can't accept drag operation that only CFSTR_SHELLIDLIST format in IDataObject, because of we didn't found explorer asks any extra interface from our NSE after drag some item over explorer window.
According to MSDN Library suggestion, Format CFSTR_FILECONTENTS is a standard way to drag a virtual file object to explorer, after I implement this format, explorer doing drag-drop operation very well when I drag some file item, but when I drag a folder item (tymed has assigned to TYMED_ISTORAGE and pstg points to a IStorage interface in struct STGMEDIUM), but explorer only create a new directory named same name in cFileName of struct FILEDESCRIPTORW, explorer didn't call any method which IStorage exported and it didn't copy any child item that source folder object contains.
Does format CFSTR_FILECONTENTS will be worked for drag a virtual folder object to explorer ? If it is absolutely yes, how to make it work ?

The problem about implement drag-drop function in XP platform has bother me for long time, many thanks to anybody who answer my question.

Johnny


EggHeadCafe - Software Developer Portal of Choice
Get Identity Values of Multi-row insert by using OUTPUT Clause
http://www.eggheadcafe.com/tutorials/aspnet/03c8104d-7deb-425e-beb5-dd4f996da99f/get-identity-values-of-mu.aspx
Jim Barry
2009-11-25 15:27:39 UTC
Permalink
Post by unknown
According to MSDN Library suggestion, Format CFSTR_FILECONTENTS is a standard way to drag a virtual file object to explorer, after I implement this format, explorer doing drag-drop operation very well when I drag some file item, but when I drag a folder item (tymed has assigned to TYMED_ISTORAGE and pstg points to a IStorage interface in struct STGMEDIUM), but explorer only create a new directory named same name in cFileName of struct FILEDESCRIPTORW, explorer didn't call any method which IStorage exported and it didn't copy any child item that source folder object contains.
You can't create a folder tree using IStorage - it doesn't work that
way. You can provide data via IStorage but in that case the target will
just copy the structured storage data into a file by calling
IStorage::CopyTo.

To copy a directory structure, you must provide a FILEDESCRIPTOR
structure for each file that you want created. Each FILEDESCRIPTOR
should contain a relative path in cFileName.

- Jim
unknown
2009-11-26 11:27:53 UTC
Permalink
Thanks, Jim.
I found there are pool guy struggled in same problem 2 years ago (http://www.eggheadcafe.com/software/aspnet/30091757/cfstrfilecontents-and-cf.aspx), and you still answering another pool guy like me 2 years after. Seems it is only way to implement drag virtual folder except Delay-Rendering for CF_HDROP. Thank you very much!
Now I have last thing need to figure out, I'm not sure there are something wrong in my code, after I got an IDataObject interface from CIDLData_CreateFromIDArray(in XP, I using SHCreateDataObject in Vista and 7), then I put transfer data according to CFSTR_FILEDESCRIPTOR and CFSTR_FILECONTENTS format like below:

FORMATETC formatetc;
STGMEDIUM stgmed;
for (i = 0 ......) // Loop for fill STGMEDIUM to IDataObj
{
hr = .... // Create instance of IStream associate with dragged virtual file
if (SUCCEEDED(hr))
{
stgmed.pstm = pStm;
stgmed.tymed = TYMED_ISTREAM;
stgmed.pUnkForRelease = NULL;
formatetc.cfFormat = m_formatid_FileContent;
formatetc.dwAspect = DVASPECT_CONTENT;
formatetc.lindex = -1;
formatetc.ptd = NULL;
formatetc.tymed = stgmed.tymed;

hr = pDataObj->SetData(&formatetc, &stgmed, TRUE);
}
}

That IStream is my own implementation using ATL, but I found my previous IStream will be released when next pDataObj->SetData has been called. For example, If user drag 2 files A.txt and B.txt, then first time to call SetData for put first IStream associate with A.txt will got S_OK, when second time to call SetData for put second IStream associate with B.txt also got S_OK, but first IStream(A.txt) will be released (FinalRelease has been called) in the same time. In DropTarget, either assign formatetc.lindex = 0 or 1 when call GetData will always got second IStream(B.txt) pointer from stgmed.pstm, Why? Why first IStream will be released at next SetData? Is something wrong in my code? or we can using system generated IDataObject in this way and need to implement IDataObject by myself?

Thanks again.




Jim Barry wrote:

Johnny Liu wrote:You cannot create a folder tree using IStorage - it does not
25-???-09

Johnny Liu wrote

You cannot create a folder tree using IStorage - it does not work tha
way. You can provide data via IStorage but in that case the target wil
just copy the structured storage data into a file by callin
IStorage::CopyTo

To copy a directory structure, you must provide a FILEDESCRIPTO
structure for each file that you want created. Each FILEDESCRIPTO
should contain a relative path in cFileName

- Jim

Previous Posts In This Thread:

EggHeadCafe - Software Developer Portal of Choice
.NET 2.0 Application Restart When it Goes "KABOOM"
http://www.eggheadcafe.com/tutorials/aspnet/1bad01a6-ebbb-4cb2-96c0-abf68699dcd7/net-20-application-rest.aspx
Jim Barry
2009-11-26 16:53:35 UTC
Permalink
Post by unknown
That IStream is my own implementation using ATL, but I found my previous IStream will be released when next pDataObj->SetData has been called.
Yes, it seems that the shell data object can only handle one data item
per clipboard format, so you'll have to implement your own data object.

- Jim
bviksoe
2009-11-26 20:39:51 UTC
Permalink
Post by Jim Barry
Post by unknown
That IStream is my own implementation using ATL, but I found my previous IStream will be released when next pDataObj->SetData has been called.
Yes, it seems that the shell data object can only handle one data item
per clipboard format, so you'll have to implement your own data object.
- Jim
With the SHCreateDataObject in Vista and Win7 you can still take
advantage of the "inner DataObject" feature of this call. While it
only has the usual sparsely documented mention on MSDN, this allows
you to create a minimal dataobject which responds to QueryGetData and
GetData, and can serve your indexed FILECONTENTS data. This is also
nice since you can use it to help with delay-rendering slow files.

regards
bjarke

Loading...