How to Use OLE Drag & Drop from the Taskbar Notification Area

ID: Q139408

2.00 WINDOWS kbole kbhowto

The information in this article applies to:

SUMMARY

The Windows 95 user interface includes a notification area on the system taskbar where applications can install an icon for providing visual feedback to the user. This article describes how to use such an icon as a source for dragging objects to other applications.

MORE INFORMATION

For general information on using the taskbar notification area, look up "Taskbar Notification Area" in the "Programmer's Guide to Windows 95" included with the Win32 SDK documentation.

When the user clicks a notification icon, the shell sends an application- defined message to the application window associated with the icon. If the application calls DoDragDrop at this time, the mouse pointer will not change to indicate a dragging operation and the drag operation will fail. This is because DoDragDrop calls SetCapture to associate mouse input with a hidden OLE window owned by the calling application, but the mouse click happened over a window (the taskbar) not owned by the application.

NOTE: The Windows 95 and Windows NT environments differ from Windows 3.x in that each thread of execution has its own message queue. This change affects window focus and mouse capture. For more information on this, look up "Mouse Capture" in the Win32 SDK documentation.

To perform a drag and drop operation from a taskbar notification icon, you need to temporarily combine the taskbar's input queue with the input queue of the calling application. The following function demonstrates how this can be done:

   HRESULT DoSpecialDragDrop(LPDATAOBJECT pDataObject,
                          LPDROPSOURCE pDropSource,
                          DWORD dwOKEffect,
                          DWORD *pdwEffect)
   {
    POINT pt;
    HWND hwndAttach;
    DWORD dwAttachThreadID;
    DWORD dwCurrentThreadID;
    HRESULT hr = E_FAIL;

    // Find the window under the mouse pointer.
    // This window might not be owned by the current thread, which
    // means you need to use AttachThreadInput in order for mouse
    // capture (and drag and drop) to work correctly.
    GetCursorPos(&pt);
    hwndAttach = WindowFromPoint(pt);
    if (!hwndAttach)
        return hr;

    // Get thread ID's
    dwAttachThreadID = GetWindowThreadProcessId(hwndAttach, NULL);
    dwCurrentThreadID = GetCurrentThreadId();

    // Attach input queues if necessary
    if (dwAttachThreadID != dwCurrentThreadID)
        AttachThreadInput(dwAttachThreadID, dwCurrentThreadID, TRUE);

    // Do the drag and drop
    hr = DoDragDrop(pDataObject, pDropSource, dwOKEffect, pdwEffect);

    // Detach input queues
    if (dwAttachThreadID != dwCurrentThreadID)
        AttachThreadInput(dwAttachThreadID, dwCurrentThreadID, FALSE);

    return hr;
   }

DoSpecialDragDrop is called in the same way as DoDragDrop, except that it should not be called while processing the taskbar notification message because the shell sends this message with SendMessage. Because shell interaction may be required during the drag and drop operation, the application should delay the drag and drop by posting itself another message, allowing the shell to continue execution as in this example:

   #define WM_MYNOTIFICATIONMESSAGE    WM_APP      // app-defined messages
   #define WM_MYDODRAGDROP             WM_APP + 1

   case WM_MYNOTIFICATIONMESSAGE:      // icon notification message
       if (lParam == WM_LBUTTONDOWN && wParam == idMyNotificationIcon)
       {
           // Give control back to the taskbar and do Drag/Drop later.
           // This way the shell won't be blocked on a SendMessage call
           // while we are trying to do the drag/drop.
           PostMessage(hwnd, WM_MYDODRAGDROP, wParam, lParam);
       }
       break;

   case WM_MYDODRAGDROP:
       {
           LPDATAOBJECT pDataObject;
           LPDROPSOURCE pDropSource;
           DWORD dwEffect;

           // Initialize IDataObject and IDropSource objects
           :
           // This drag source only allows Copy, not Move or Link.
           DoSpecialDragDrop(pDataObject,
                             pDropSource,
                             DROPEFFECT_COPY,
                             &dwEffect);

           // Clean up IDataObject and IDropSource objects
           :
        }
   break;

Additional reference words: 2.00 tray Shell_TrayWnd TrayNotifyWnd KBCategory: kbole kbhowto KBSubcategory: LeTwoDdc
Keywords          : kbcode LeTwoDdc 
Version           : 2.00
Platform          : WINDOWS

Last Reviewed: May 22, 1998