Drag and drop is a general purpose transfer model, not exclusive to Explorer directories


If you've designed your program so that it assumes that the the only thing a user can use drag/drop for is dropping your object into a file system directory, then you've already lost.

piers wants to be able to determine the destination of a drag/drop operation. From the description, it appears that what piers really wants is the destination path, but who says that the drop destination is a directory? The user might have dropped the item into an email message, onto an FTP site, onto a Web site (via Web Folders), or even a directory on an operating system running inside a virtual machine!

The follow-up question makes things even more confusing. If the user drops the files into an FTP site or some other virtual folder, how is your program supposed to be able to restart the transfer? You don't know the user's password on that FTP site. You don't know how to restart that virtual machine and log the user on. And even if you did, you don't know how to write to a directory on a virtual machine; only the virtual machine manager knows how to do that. There are an infinite variety of potential virtual folders out there; I doubt you know how to (or even have the ability to) push your data into each one.

Once the user drops the data object, the remainder of the transfer is a private matter between the data source and the drop target. It's not like a data source can tell all drop targets, "I want to take over the transfer," because even if the drop target agreed to it, that still leaves the data source the problem of figuring out how to carry out that take-over.

What is my recommendation?‡

The data object in the drag/drop loop should follow the standard shell data object transfer protocol so that users can drop the object into an email message, onto an FTP site, etc.°

For the special bonus behavior, I would create a drag/drop hook. A user that wants to do a transfer mediated by your program can use the right mouse button† to drag. When the drop occurs, a context menu will appear, including the drag/drop hook you created. That hook would create a new item called something like "Copy with CoolProgram". (Of course, the hook adds this item only if the data object identifiers itself as coming from CoolProgram.) If the user selects "Copy with CoolProgram", then you can do your CoolProgram-mediated copy.

Nitpicker's corner

†More properly, the secondary mouse button, since you may have swapped buttons.

Notice that I do not assert that all Microsoft products follow my recommendation. Note also that this is my personal recommendation, not the official position of Microsoft Corporation.

°And you should already understand the standard shell data object transfer protocol before you go off and design a nonstandard one.

Comments (15)
  1. Spire says:

    More properly, the secondary mouse button, since you may have swapped buttons.

    Trivia: The Windows 95 online help actually used the words "primary" and "secondary" when referring to the mouse buttons. I thought that was pretty cool. However, by Windows 98 (IIRC), the words were changed back to "left" and "right", presumably because users found "primary" and "secondary" too confusing.

  2. dsn says:

    I don’t know about the rest of you  guys, but I find the nitpickers corner the best part of the posts.  It always makes me laugh, or at least smile.

  3. C Gomez says:

    @dsn: agreed, it’s become a game of guessing what the nitpickers will say. They are funny people, those nitpickers.

    That said, this was valuable.  It makes me want to go back and revisit every drag/drop functionality I’ve ever implemented.

  4. Steve says:

    Is it just me or does it seem that the number of comments on one if Raymond’s is reduced in direct proportion† to the number of nitpickers clarifications?

    †No, I have not validated this assertion mathmatically it just feels that way to ME.

  5. Josh says:

    @Steve: there does seem to be a direct – if unfortunate – relationship.

  6. Starfish says:

    Thanks for this, too often people think too narrowly and forget the OS lets you do unusual things that most programmers fail to expect. Unfortunately if you’re on a deadline "add drag-and-drop support" turns into "add support for drag-and-drop to Explorer windows since that’s all we’re testing", but that’s the same for much more than this situation…

    @Steve: there does seem to be a direct – if unfortunate – relationship.

    I doubt it is unfortunate for Raymond :)

  7. Dean Harding says:

    I doubt it is unfortunate for Raymond

    It’s unfortunate that he NEEDS a nitpicker’s corner. Ideally, people would be able to figure out the nitpicks on their own…

  8. WikiServerGuy says:

    Google doesn’t know what "shell data object transfer protocol" is… anyone know of a good msdn link or something :)?

  9. Tanveer Badar says:

    I was disconnected. Sorry about the twin comments and this apology.

  10. Jules says:

    WikiServerGuy: the best place to start is probably <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/programmersguide/shell_basics/shell_basics_programming/transferring/transfer.asp">here</a&gt;.  Note that having read that and most of the pages linked from it, however, I still find shell drag & drop handling confusing, and tend to stick to the most basic possible method (i.e., put the data I want to drop into a temporary file and just give the shell the filename).

  11. Tanveer Badar says:

    I am guessing he goes by the name of D**n H*. :)

  12. Tanveer Badar says:

    I am guessing he goes by the name of D**n H*. :)

  13. UnitOOPS says:

    Best to think about it the other way around.

    Don’t worry about where it dropped – give the D&D the data and let the shell or other target do what it wants.  Just give the shell item array and FileContents for each item.  You can delay-render so you get called at drop-time.

  14. ChrisG says:

    here are the most recent docs on this topic… (note MSDN keeps old versions of the SDK so you want to avoid those, always prefer "msdn2.microsoft.com" results over "msdn.microsoft.com")

    http://msdn2.microsoft.com/en-us/library/bb267299.aspx

  15. If you want multiple files, then drag multiple objects.

Comments are closed.