Drop Target Handlers

A drop target handler controls the action that occurs when one object is dropped on another object. For example, if you drag a Microsoft Word document and drop it on the Word icon or on a shortcut to the Word icon, Word will start and open that document. A drop target handler makes this happen.

Unlike the other user interface extensions we have discussed so far, only one drop target handler at a time is supported. In those other cases, you could register many extensions. (Note that the Registry entries refer to them as, for example, PropertySheetHandlers.)

You register a drop target handler in the Registry under the DropHandler key, with the value being the CLSID of the drop target extension:

[HKEY_CLASSES_ROOT\SampleType\shellex\DropHandler]
@="{<CLSID value>}"

A drop target handler is implemented through the IDropTarget interface and initialized with the IPersistFile interface. IDropTarget implements the DragEnter, DragOver, DragLeave, and Drop member functions as well as the standard IUnknown functions.

DragEnter

DragEnter signals the beginning of a drop. It determines both whether the target window can accept the dragged object and what effect the dragged object will have on the target window. The function is passed the state of the keyboard (whether one of the keyboard modifier keys is being pressed: MK_CONTROL, MK_SHIFT, MK_ALT, MK_LBUTTON, MK_MBUTTON, or MK_RBUTTON), the cursor point, and a pointer to which drop effect should be used. The drop effect can be DROPEFFECT_NONE, DROPEFFECT_COPY, DROPEFFECT_MOVE, DROPEFFECT_LINK, or DROPEFFECT_SCROLL.

DragOver

This member function provides feedback to the user about the state of the drag operation within a drop target application.

DragLeave

DragLeave causes the drop target to remove its feedback if the mouse leaves the drop area or if the drop is canceled.

Drop

This member function, the most interesting of the four, is responsible for effecting the drop of the object onto the target. In the following code, the data for the object is retrieved, the name of the file being dropped is queried, and the function returns S_OK for success. If the data for the object cannot be retrieved, the function returns E_FAIL.

STDMETHODIMP SampleType::Drop (IDataObject *pDataObj,
DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
{
HRESULT hres = E_FAIL;
FORMATETC fmte = {CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
STGMEDIUM medium;

if (pDataObj && SUCCEEDED (pDataObj->GetData (&fmte, &medium)))
{
char szFileDropped [MAX_PATH];

DragQueryFile ((HDROP)medium.hGlobal, 0, szFileDropped,
sizeof (szFileDropped));
TRACE ("SampleType::Drop(%s,%s)", this->szFileName, szFileDropped);
hres = S_OK;

if (medium.pUnkForRelease)
medium.pUnkForRelease->Release ();
else
GlobalFree (medium.hGlobal);
}

return hres;
}