Dragging a shell object, part 3: Detecting an optimized move

Raymond Chen

We were considering how to detect that the drag/drop operation resulted in a conceptual Move even if the DROPEFFECT_MOVE was optimized away.

If the drop target is the shell, you can query the data object for CFSTR_PERFORMEDDROPEFFECT to see what the performed effect was.

void OnLButtonDown(HWND hwnd, BOOL fDoubleClick,
                   int x, int y, UINT keyFlags)
        if (dwEffect & DROPEFFECT_MOVE) {
        CheckPerformedEffect(hwnd, pdto);

Of course, we need that CheckPerformedEffect function too.

void CheckPerformedEffect(HWND hwnd, IDataObject *pdto)
  FORMATETC fe = {
  if (SUCCEEDED(pdto->GetData(&fe, &stgm))) {
    if ((stgm.tymed & TYMED_HGLOBAL) &&
        GlobalSize(stgm.hGlobal) >= sizeof(DWORD)) {
       DWORD *pdw = (DWORD*)GlobalLock(stgm.hGlobal);
       if (pdw) {
         if (*pdw == DROPEFFECT_MOVE) {
            MessageBox(hwnd, TEXT(“Moved”), TEXT(“Scratch”), MB_OK);

If the item is dropped on a shell window, the drop target will set data into the data object under the clipboard format name CFSTR_PERFORMEDDROPEFFECT. The data takes the form of a DWORD in an HGLOBAL, and the value is the actual drop effect before any optimizations kicked in.

Here, we check whether it was a DROPEFFECT_MOVE and display a special message if so.