Register and Revoke the Drop Target Object

The last step for making Cosmo a full target is to register the drop target object to associate it with the document window. Cosmo both creates and registers the object in CCosmoDoc::Init:


m_pDropTarget=new CDropTarget(this);

if (NULL!=m_pDropTarget)
{
m_pDropTarget->AddRef();
CoLockObjectExternal(m_pDropTarget, TRUE, FALSE);
RegisterDragDrop(m_hWnd, m_pDropTarget);
}

The hWnd passed to RegisterDragDrop identifies the target window for the drop target object. If creation of the object fails or if registration fails, Cosmo does without drag and drop.

But what in tarnation is CoLockObjectExternal here for? RegisterDragDrop is another example of a weak registration function—OLE will create a stub that holds the IDropTarget pointer but does not call AddRef through it. Without CoLockObjectExternal, when DoDragDrop accesses the target pointer from the source's process, everything works fine until DoDragDrop releases the pointer. This destroys the proxy in the source process and also destroys the stub in the target's process. The next time you drag into the same target window, no stub is available, so DoDragDrop quits—it doesn't simply ignore the window; it fails with an error. As we learned in Chapter 6, CoLockObjectExternal will force a strong lock and keep a stub in memory, so Cosmo needs to call this function here. It is unfortunate that RegisterDragDrop doesn't do this itself.

Of course, the process must be reversed when the document isn't a target any longer. This means removing the strong lock, revoking the registration, and releasing the target object, which happens in the processing for the WM_DESTROY case in CCosmoDoc::FMessageHook:


if (NULL!=m_pDropTarget)
{
RevokeDragDrop(m_hWnd);
CoLockObjectExternal(m_pDropTarget, FALSE, TRUE);
ReleaseInterface(m_pDropTarget);
}

Cosmo removes the strong lock on WM_DESTROY and not in the document destructor because by the time the destructor is called, the window is long gone and RevokeDragDrop cannot remove its property from that window.