What a drag: Dragging a Uniform Resource Locator (URL) and text

We've learned how to drag text and how to drag a uniform resource locator, but what if want to drag both? Well, it's actually a simply matter of saying that you have both (and actually producing it on demand).

Start by extending the enumeration of data types to include both URL and text:

  enum {
    DATA_INVALID = -1,

There is a subtlety in the way we set up this enumeration: We put DATA_URL ahead of DATA_TEXT so that the clipboard formats that are produced by SHCreateStdEnumFormatEtc are generated in priority order (highest quality first). By enumerating URL first, a program that understands both URL and text formats will know to prefer URL. In this particular case, it's not that critical since most text editors do URL auto-detection (at least if the URL begins with "http:"), but in the more general case, enumerating the formats in priority order can make a big difference. For example, your data object might provide text in both Rich Text Format as well as plain text, and it would probably be better if a program that understood both formats used the rich text version by default rather than the plain text version.

Once we have both formats available, we need to respond to both of them. In our constructor, we have to describe both of these formats so that GetDataIndex and EnumFormatEtc know about them.

CTinyDataObject::CTinyDataObject() : m_cRef(1)

And then the change to the heart of the data object, the IDataObject::GetData method, is anticlimactic:

HRESULT CTinyDataObject::GetData(FORMATETC *pfe, STGMEDIUM *pmed)
  ZeroMemory(pmed, sizeof(*pmed));

  switch (GetDataIndex(pfe)) {
  case DATA_URL:
  case DATA_TEXT:
    pmed->tymed = TYMED_HGLOBAL;
    return CreateHGlobalFromBlob(c_szURL, sizeof(c_szURL),
                              GMEM_MOVEABLE, &pmed->hGlobal);

  return DV_E_FORMATETC;

Whether the caller asks for either text or a URL, we give them the same string back.

When you run this program, observe that it has the combined functionality of the two previous programs. You can drag text into Wordpad, drop an URL onto Firefox, and drop an URL onto Internet Explorer.

These were all just warm-ups. After a short break, we'll roll up our sleeves and begin providing more complicated data in our data object.

Comments (25)
  1. James Kilner says:

    Just nit-picking about your use of ‘URL’.  In one place you wrote "Whether the caller asks for either text or a URL", in another place you wrote "drop an URL onto Firefox".  The correct way of writing about URLs is "a URL".

  2. Ian says:

    Please forgive me if this is a little off-topic.

    I’ve noticed that some applications do not consume clipboard formats in the order they are given. Microsoft Excel for example prefers plain text to CSV, even when you offer it CSV as a higher-priority format. If you offer it CSV only then it accepts it and splits the text into columns as expected. But if you offer it plain-text then it puts each complete line in a single cell. The trouble is if you offer CSV only then other lesser applications won’t accept the format.

    Is there any general way out of this dilemma?

  3. Ian says:

    Just to preempt the inevitable comments, I know that what Excel does with the clipboard is up to Excel and is outside the control of my application. I also realise that Raymond is not personally responsible for how Excel handles the Windows clipboard.

  4. Gabe says:

    James: Raymond may be one of those folks that pronounces URL like the name "Earl" instead of the initials U.R.L., so he says "an Earl" instead of "a U.R.L.".

  5. Krenn says:

    Just wondering… when you drag a link in IE7, what is it that gets dragged? It doesn’t appear to be a URL or text, and the only things that I can find that accept it are Windows Explorer and IE7 itself (the tabs bar, links, or Favorites sidebar – not the address bar though).

    I’ve written an application that accepts drag & drop of URLs and text, and then parses it, but was never able to get this to work – I had to add a text box and use "Copy Shortcut" in the end.

  6. KenW says:

    James: Who cares?

    Grammar and spelling Nazis need to get a life.

  7. Joe says:

    BTW, MSDN says the CFSTR_SHELLURL format identifier is deprectated.

    "CFSTR_SHELLURL (deprecated)

    This format identifier is the deprecated identifier for transferring a single URL. … Note  This format identifier has been deprecated; use CFSTR_INETURL instead."


  8. Keithius says:

    Another enlightening series, as always Raymond.

    Though where’d our "Pre-emptive Igor Levicki" comments go? ;-)

  9. Sys64738 says:

    I agree with Keithius: very interesting series, thanks for sharing Raymond.

    I just don’t like one thing: why do you use these "strange" names like m_cRef o m_rgfe or c_szURL, or why do you put the C before class names?

    IMHO, identifiers like e.g. "m_referenceCount" (or "m_refCount") are better than "m_cRef" (more cryptic…).

    Was Hungarian notation deprecated?

    Fortunately, latest DirectX SDK stopped using prefixes like "cb", "dw", etc. in data structures.

    Also .NET framework uses clear names.

    Why should we "uglify" identifiers storing type information in them? The compiler can do a good job for type checking…

    Thanks again for your blog.

  10. Josh says:

    We uglify the names mostly for the benefit of the code maintainers, not the compiler.  IT was more important earlier on, because C++ is a notoriously awful language for IDEs to develop a parse chain for, and you might not always be able to find the definition (and therefore type) of a variable.  C# by contrast has a much more restrictive syntax, so finding the definition of a variable is trivial.

    I’ve found in day to day work as MS that the Hungarian notation is incredibly useful, at least if it’s used appropriately.  My team has literally tens of millions of lines of code in thousands of files and only a few dozen actual developers; anything that makes it easier to understand the code faster speeds bug fixes and feature work immeasurably.

  11. Reginald Wellington III says:

    Can we just stop the (anti-)Hungarian notation argument before it starts?  If you really want to argue about programming style, just search google and find one of the billion other times this discussion has occurred on the internet, and join one or more of those.

    I like to pretend that this blog speaks to an audience that’s more sophisticated.


  12. Starfish says:

    Windows API documentation has used Hungarian for a long time. Doesn’t matter what .NET does ("not actually a .NET blog"), for the Win32 developers this is aimed at, it’s typical code, and hardly worth complaining about for such small snippets. Do what you know best, Raymond!

    I like to pretend that this blog speaks to an audience that’s more sophisticated.

    I like to pretend I’m sophisticated, but I know it’s not true :(

  13. mattd says:


    Along the line of drag and drop, I was listening to your DotNetRocks show where you claim to have removed the ‘scraps’ feature. Which OS was this for? ‘Scraps’ works fine for me in both XP and Server 2003. I tested by opening wordpad and dragging text onto the desktop. Any thoughts? Why was this featured added back in after you removed it?

  14. scorpion007 says:

    Small typo:

    “One we have both formats available”

    should be

    “Once we have both formats available”

    Great article, BTW.

    [Fixed, thanks. -Raymond]
  15. Anonymous says:

    James Kilner: you’re a twit.  Many people use both, just as SQL/sequel.  You’d use SQL if you need to be precise, but sequel otherwise.  Here, Raymond forcing you to say URL helps make that sentence a climax.

  16. Anon says:

    This series is good stuff. I’ve never coded drag and drop before and it’s good to have it explained by someone that really understands it and doesn’t use some library to do all the work.


    Who? ;-) It’s cool how even though the these articles are planned out months in advance and he presumably has lots of other things to do Raymond still has time to deal with hecklers. It’s like standup comedy for nerds.

  17. Worf says:

    Ian: that is why Excel offers stuff like paste special.

    It knows it may interpret stuff badly, so it lets you force how you want Excel to interpret it. Later versions let you do it after the operation.

    Not an ideal solution, but does help.

  18. Dan says:

    Krenn: You should use a tool that lets you spy on clipboard formats.  I made one in .NET and it might help:


    Not sure if it’s OK that I link to binaries off-site in this blog. :(  If not you can just censor it Raymond.

  19. GregM says:

    Matt, scraps were removed for Vista.

  20. Igor Levicki says:

    Sorry for the off-topic.

    >>I notice that you don’t have comments on your own blog

    It is not a blog but a website and it has contact form.

    >>I notice that you hide behind an email whitelist

    I am not hiding. There is no whitelist/blacklist.

    >>how horrible Microsoft is

    I never criticized Microsoft or Raymond personally, just some bad ideas or bad products. Some people can accept criticism and actually benefit from it, others cannot. Those who cannot are the crybabies, not me.

    [That’s right, because writing things like “written without adult supervision” is not a criticism of Microsoft or specific individuals. -Raymond]

    If anyone else wants to discuss something with me please do so via the contact form on my website so I don’t have to reply here anymore.

  21. Rick C says:

    Igor, you’re a crybaby.  I notice that you don’t have comments on your own blog, so nobody can criticize *you*.  I notice that you hide behind an email whitelist, too, and I won’t use those, which is why I’m responding here not directly to you.

    This is Ray’s personal blog.  It’s not an appropriate place for your vitriol about how horrible Microsoft is.  Grow up.

  22. Rick C says:

    "Oh, and if some of you decide to contact me to discuss this post — remember that validating your email and clicking on a hyperlink in the message you receive once is enough."

    So if I email you, you don’t see it right away, until I click a link in an automatically-generated message, to validate I’m not a spammer?  Are you not clear on what whitelisting is?

  23. cat says:

    Ladies, please! Take your arguing elsewhere, this is not the place. You’re most welcome to comment on the clipboard/dnd API and in particular the example presented in TFA.

  24. Guest says:

    "I never criticized Microsoft or Raymond personally, just some bad ideas or bad products. Some people can accept criticism and actually benefit from it, others cannot." Raymond used to investigate criticisms. For example, look how much effort he went through to try and investigate an IE/explorer issue with ndmiamond here:


    But you’ll notice that around the time Raymonds’ writing tone became more cynical, he started replying to comments inline instead of in seperate posts, and he started with his nitpickers corner (Around 2004-2005) he also started paying less attention to criticisms in the comments.

Comments are closed.