ID: Q139408
2.00 WINDOWS kbole kbhowto
The information in this article applies to:
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.
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