Chapter 13 OLE Drag and Drop

When I first began looking for OLE enlightenment, I watched a number of videotapes from early OLE seminars and demonstrations (early as in 1991). At one point, bored out of my skull, I decided to fast-forward through some of them. I noticed during that fit of impatience how often the presenter would select data in some application, pull down the Edit menu to choose Cut or Copy, switch to another application, and then pull down the Edit menu and choose Paste. This is to be expected: the clipboard is a great way to transfer data between a source and a consumer. It is a protocol that works.

I realized at that time, as did other designers, that a drag-and-drop technique would streamline many of these Cut/Copy and Paste operations. In drag and drop, the end user selects some data in the source, picks it up by clicking and holding down a mouse button in a specific region of that data, drags that data from the source's window to the consumer's window, and drops it into the consumer by releasing the mouse button. Keys such as Ctrl and Shift determine whether the operation moves, copies, or links the data, as you can accomplish through the clipboard. Move, copy, link, and even no-drop are each called an effect of the drag-and-drop operation.

This pick-drag-drop sequence, with its keyboard modifiers, has the same result as using the clipboard. The big difference is that drag and drop is direct and immediate—the entire data transfer operation happens in one swift stroke of the mouse, making drag and drop more efficient and easier to understand. The clipboard is most useful for storing data for an undetermined amount of time and pasting it repeatedly or not at all. With drag and drop, the source and the consumer perform a single transfer without touching the clipboard at all—that is, the clipboard contents remain intact.

OLE Drag and Drop, like the OLE Clipboard, is a transfer protocol that involves moving an IDataObject pointer from a source to a consumer. As part of the protocol, the source implements a simple object (no CLSID, no persistence, and so on) called the drop source, which implements the interface IDropSource. The consumer, which in the drag-and-drop context is called a target, implements a drop target object with the IDropTarget interface. Through these two objects, the source and the target communicate various events that occur from the pick to the drop.

This chapter first explains how OLE Drag and Drop works through source and target objects to communicate with a data object. As a demonstration, we'll add simple drag-and-drop support to Cosmo to show how easy it is to support this feature. In fact, OLE Drag and Drop can be so simple for certain applications that you can implement and test the feature in a day—and gain quite a lot of power and flexibility for your customers. A more complex implementation that involves additional user interface elements, mouse debouncing, and scrolling during a drag-and-drop operation will take longer, and we'll see why as we add drag and drop to Patron. These features are useful not only in exchanging data with other applications (such as a metafile from Cosmo) but also for simply moving tenants around on the same page—all with the same code. This is the power of OLE Drag and Drop: with one implementation, you can move data within an application, between documents or windows in that application, and between different applications.

Let me again stress that by implementing OLE Clipboard support and the "[query] paste from data" functions, as we saw in Chapter 11, you build a code base that makes for a fast implementation of drag and drop. The time you take to work with data objects and the clipboard will reduce a drag- and-drop implementation to perhaps only a few hours or a few days, depending on the level of complexity you want. (C'mon, Kraig, you think we want complexity?) If you do this, customers watching your video demonstrations on fast-forward won't know what hit them.