Source and Target Responsibilities

From the previous discussion, we can identify specific responsibilities for the source and the target in a drag-and-drop relationship. The source has the following responsibilities:

Provide a data object with the selected data.

Provide an object with IDropSource, which need not be instantiated until immediately before calling DoDragDrop and can be deleted after the operation is finished.

Call DoDragDrop to start the operation, debouncing the mouse if necessary, and control its duration through IDropSource::QueryContinueDrag.

Control the mouse cursor and end-user feedback through IDropSource::GiveFeedback.

The target's responsibilities consist of the following:

Implement an object with IDropTarget.

Associate the object with a target window with RegisterDragDrop, usually when creating the window or making it visible. Disassociate the object when the window is destroyed or hidden with RevokeDragDrop. The object also requires a strong lock, which is not created in RegisterDragDrop, so the target must also call CoLockObjectExternal before registering or revoking the object.

Check for usable data in IDropTarget::DragEnter and IDropTarget::DragOver and determine the effect (which may be "no drop allowed").

Provide optional end-user feedback in the target within DragEnter and DragOver. The implementation of this can be done after the other steps have been completed.

Scroll the target window as appropriate, using the inset region, scroll delay, and scroll rate. This step is also optional and can be postponed until other parts of the implementation are complete.

Perform a Paste operation in IDropTarget::Drop.

These two lists define all that sources and targets must do to support OLE Drag and Drop. In many cases, you will need to implement only a subset of these responsibilities.