Creating something from nothing [Developer-friendly virtual file implementation for .NET!]


This blog has moved to a new location and comments have been disabled.

All old posts, new posts, and comments can be found on The blog of dlaa.me.

See you there!

Comments (12)
  1. Robinson says:

    I get the following exception when I try to drag/drop anything from the demo app onto my desktop.  It's not encouraging!  The error is a failed HR in GetData at QueryGetData.  The HR is -2147221404.  OS is 64 bit W7.

    A first chance exception of type 'System.Runtime.InteropServices.COMException' occurred in VirtualFileDataObjectDemo.exe

    An exception of type 'System.Runtime.InteropServices.COMException' occurred in VirtualFileDataObjectDemo.exe but was not handled in user code

    Additional information: Invalid FORMATETC structure (Exception from HRESULT: 0x80040064 (DV_E_FORMATETC))

  2. David Anson says:

    Robinson,

    This is probably just an artifact of running under the debugger – please have a look at the following comment and my reply (search for "Tyler" if your browser doesn't scroll to it automatically): blogs.msdn.com/…/creating-something-from-nothing-asynchronously-developer-friendly-virtual-file-implementation-for-net-improved.aspx

    Hope this helps!

  3. Justin says:

    Curious as to how to know the resulting path that was created after the drop operation is complete? Possible?

  4. David Anson says:

    Justin,

    Offhand, I'm not sure that's easily available. Here's a post Raymond Chen did on the topic that may be helpful to understand why: blogs.msdn.com/…/2453927.aspx

  5. Alex Nossov says:

    Many thanks. It works for Windows Explorer. Is there somewhere to see how to process drop of the dragged file. I noticed that this way (http://www.codeproject.com/…/Outlook-Drag-and-Drop-in-C) it does not work right, although it works when drop is from Outlook.

  6. David Anson says:

    Alex Nossov,

    I don't know offhand, but if you're implementing a streaming approach, then the code that streams the file should know how far it has gone and how far it has left and may be able to communicate the progress out to someone somehow.

    Just a thought – I hope it's helpful!

  7. Alex Nossov says:

    David, thanks, my question was very simple. I am trying to figure out, why the code below works fine when drop is from MS Outlook, but it reads 26 zeros, if drop is from your test application, "Virtual File" box was dragged and droped to my application.

                   case TYMED.TYMED_ISTREAM:

                       //to handle a IStream it needs to be read into a managed byte and

                       //returned as a MemoryStream

                       IStream iStream = null;

                       System.Runtime.InteropServices.ComTypes.STATSTG iStreamStat;

                       try

                       {

                           //marshal the returned pointer to a IStream object

                           iStream = (IStream)Marshal.GetObjectForIUnknown(medium.unionmember);

                           Marshal.Release(medium.unionmember);

                           //get the STATSTG of the IStream to determine how many bytes are in it

                           iStreamStat = new System.Runtime.InteropServices.ComTypes.STATSTG();

                           iStream.Stat(out iStreamStat, 0);

                           int iStreamSize = (int)iStreamStat.cbSize;

                           //read the data from the IStream into a managed byte array

                           byte[] iStreamContent = new byte[iStreamSize];

                           iStream.Read(iStreamContent, iStreamContent.Length, IntPtr.Zero);

                           //wrapped the managed byte array into a memory stream and return it

                           return new MemoryStream(iStreamContent);

                       }

                       finally

                       {

                           //release all unmanaged objects

                           Marshal.ReleaseComObject(iStream);

                       }

    So, iStreamContent gets only 26 of 0 values, instead of "abc…. "

    I've checked that delegate code assigned to StreamContents in your app is called and generate right "var contents =…" . Please, let me know, what can help, or if I ask too much 🙂

  8. David Anson says:

    Alex Nossov,

    I'm not familiar with IStream, so I looked it up and landed here for the Read method: msdn.microsoft.com/…/aa380011(v=vs.85).aspx

    That calls out two things from your example:

    1. The pcbRead parameter is required, but the code above passes NULL

    2. The return value from the call is not checked

    My *guess* is that it's returning STG_E_INVALIDPOINTER because of the NULL – I'm not confident in that guess, but it's definitely where I'd start looking.

    Hope this helps!

  9. Sagar says:

    Hi i am getting bytes of file from database so how can i achieve this in StreamContents action?

    StreamContents = stream =>

               {

                    data=///Here i want to get the data from DB but it is not executing,any idea ??

                    stream.Write(data, 0, data.Length);

               }

  10. David Anson says:

    Sagar,

    I'm not sure what you mean by "not executing". Whatever your "data" object is needs to be able to request information from the database and then write it to the "stream" parameter of the lambda. For a similar example, have a look at the TextUrlVirtualFile_MouseButtonDown method in the sample – it downloads from a web site and streams the content.

    Hope this helps!

  11. Sagar says:

    Hi David,

    yes i have went through that TextUrlVirtualFile_MouseButtonDown method, where its downloading using webclient, but in my case when any listview item is dragged that time i have only guid of that file, then later i get that byte data of that respective file from database and the i pass this byte array to stream parameter,

    So if i perform the Getting data from Database before creating stream then cursor doesnt changes as byte are not retrieved, so i want to perform this getdatafromDB operation here in this block

    StreamContents = stream =>

              {

                   data=GetDataFromDataBase();//Is it Correct? or Is it possible to perform the operation when drop happens then get the data from DB and then pass it to stream parameter??

                   stream.Write(data, 0, data.Length);

              }

  12. David Anson says:

    Sagar,

    I'm not sure I understand your scenario/configuration, but what you show above seems right to me.

Comments are closed.