We're now ready to call DoDragDrop on the pick event, which happens in the WM_LBUTTONDOWN case of CCosmoDoc::FMessageHook:
if (WM_LBUTTONDOWN==iMsg)
{
LPDROPSOURCE pIDropSource;
LPDATAOBJECT pIDataObject;
HRESULT hr;
SCODE sc;
DWORD dwEffect;
pIDropSource=new CDropSource(this);
if (NULL==pIDropSource)
return FALSE;
pIDropSource->AddRef();
m_fDragSource=TRUE;
//Go get data and start the ball rolling.
pIDataObject=TransferObjectCreate(FALSE);
if (NULL!=pIDataObject)
{
hr=DoDragDrop(pIDataObject, pIDropSource
, DROPEFFECT_COPY ś DROPEFFECT_MOVE, &dwEffect);
pIDataObject->Release();
sc=GetScode(hr);
}
else
sc=E_FAIL;
pIDropSource->Release();
m_fDragSource=FALSE;
if (DRAGDROP_S_DROP==sc && DROPEFFECT_MOVE==dwEffect)
{
m_pPL->New();
FDirtySet(TRUE);
}
return TRUE;
}
We first instantiate the drop source object, failing to do anything more if instantiation fails. We then set the document's m_fDragSource to avoid unnecessary processing and then create the data object to use in the transfer. The CCosmoDoc::TransferObjectCreate function is the one we added for the OLE Clipboard in Chapter 12. This shows the benefit of writing such a function: it makes the initiation of a drag-and-drop operation simple because we just pass the IDataObject and IDropSource pointers as the first two arguments to DoDragDrop. The third argument to this function is a value that represents the source's allowable effects, which can be any combination of DROPEFFECT_MOVE, DROPEFFECT_COPY, and DROPEFFECT_LINK. If you don't want to allow a move, you need not include that flag. In Cosmo, we don't support linking (we don't provide CFSTR_LINKSOURCE), so we don't include the link effect.
The fourth argument to DoDragDrop is an out-parameter that will receive the final effect of the operation after DoDragDrop returns. After the operation is finished, Cosmo cleans up the data object and the drop source object and checks what happened. If the final effect was a copy, we have finished. If it was DROPEFFECT_MOVE, we have to delete the source data, which in this case means clearing the Polyline data. Remember that a move operation modifies the source document, so you should set your dirty flag.
This code in CCosmoDoc::FMessageHook, along with the drop source object, is the complete source implementation—very simple! Because Cosmo is a source of metafiles and bitmaps as well as its Polyline data, this code allows you to drag and drop a Polyline figure as a static picture into a suitable drop target. Now let's see how we can make Cosmo itself a target.