4 * Copyright 1995 Martin von Loewis
5 * Copyright 1999 Francis Beaudet
14 #include "wine/obj_clientserver.h"
17 /******************************************************************************
18 * These are static/global variables and internal data structures that the
19 * OLE module uses to maintain it's state.
21 typedef struct tagDropTargetNode
24 IDropTarget
* dropTarget
;
25 struct tagDropTargetNode
* prevDropTarget
;
26 struct tagDropTargetNode
* nextDropTarget
;
29 typedef struct tagTrackerWindowInfo
31 IDataObject
* dataObject
;
32 IDropSource
* dropSource
;
39 HWND curDragTargetHWND
;
40 IDropTarget
* curDragTarget
;
44 * This is the lock count on the OLE library. It is controlled by the
45 * OLEInitialize/OLEUninitialize methods.
47 static ULONG OLE_moduleLockCount
= 0;
50 * Name of our registered window class.
52 static const char OLEDD_DRAGTRACKERCLASS
[] = "WineDragDropTracker32";
55 * This is the head of the Drop target container.
57 static DropTargetNode
* targetListHead
= NULL
;
59 /******************************************************************************
60 * These are the prototypes of the utility methods used for OLE Drag n Drop
62 static void OLEDD_Initialize();
63 static void OLEDD_UnInitialize();
64 static void OLEDD_InsertDropTarget(
65 DropTargetNode
* nodeToAdd
);
66 static DropTargetNode
* OLEDD_ExtractDropTarget(
68 static DropTargetNode
* OLEDD_FindDropTarget(
70 static LRESULT WINAPI
OLEDD_DragTrackerWindowProc(
75 static void OLEDD_TrackMouseMove(
76 TrackerWindowInfo
* trackerInfo
,
79 static void OLEDD_TrackStateChange(
80 TrackerWindowInfo
* trackerInfo
,
83 static DWORD
OLEDD_GetButtonState();
86 /******************************************************************************
87 * OleBuildVersion [OLE2.1]
89 DWORD WINAPI
OleBuildVersion(void)
91 TRACE(ole
,"(void)\n");
95 /***********************************************************************
96 * OleInitialize (OLE2.2) (OLE32.108)
98 HRESULT WINAPI
OleInitialize(LPVOID reserved
)
102 TRACE(ole
, "(%p)\n", reserved
);
105 * The first duty of the OleInitialize is to initialize the COM libraries.
107 hr
= CoInitializeEx(NULL
, COINIT_APARTMENTTHREADED
);
110 * If the CoInitializeEx call failed, the OLE libraries can't be
117 * Then, it has to initialize the OLE specific modules.
121 * Object linking and Embedding
122 * In-place activation
124 if (OLE_moduleLockCount
==0)
127 * Initialize the libraries.
129 TRACE(ole
, "() - Initializing the OLE libraries\n");
138 * Then, we increase the lock count on the OLE module.
140 OLE_moduleLockCount
++;
145 /******************************************************************************
146 * CoGetCurrentProcess [COMPOBJ.34] [OLE2.2][OLE32.108]
149 * Is DWORD really the correct return type for this function?
151 DWORD WINAPI
CoGetCurrentProcess(void) {
152 return (DWORD
)PROCESS_Current();
155 /******************************************************************************
156 * OleUninitialize [OLE2.3] [OLE32.131]
158 void WINAPI
OleUninitialize(void)
163 * Decrease the lock count on the OLE module.
165 OLE_moduleLockCount
--;
168 * If we hit the bottom of the lock stack, free the libraries.
170 if (OLE_moduleLockCount
==0)
173 * Actually free the libraries.
175 TRACE(ole
, "() - Freeing the last reference count\n");
180 OLEDD_UnInitialize();
184 * Then, uninitialize the COM libraries.
189 /***********************************************************************
190 * OleFlushClipboard [OLE2.76]
192 HRESULT WINAPI
OleFlushClipboard16(void)
197 /***********************************************************************
198 * OleSetClipboard [OLE32.127]
200 HRESULT WINAPI
OleSetClipboard(LPVOID pDataObj
)
202 FIXME(ole
,"(%p), stub!\n", pDataObj
);
206 /******************************************************************************
207 * CoRegisterMessageFilter32 [OLE32.38]
209 HRESULT WINAPI
CoRegisterMessageFilter(
210 LPMESSAGEFILTER lpMessageFilter
, /* Pointer to interface */
211 LPMESSAGEFILTER
*lplpMessageFilter
/* Indirect pointer to prior instance if non-NULL */
214 if (lplpMessageFilter
) {
215 *lplpMessageFilter
= NULL
;
220 /******************************************************************************
221 * OleInitializeWOW [OLE32.109]
223 HRESULT WINAPI
OleInitializeWOW(DWORD x
) {
224 FIXME(ole
,"(0x%08lx),stub!\n",x
);
228 /***********************************************************************
229 * RegisterDragDrop16 (OLE2.35)
231 HRESULT WINAPI
RegisterDragDrop16(
233 LPDROPTARGET pDropTarget
235 FIXME(ole
,"(0x%04x,%p),stub!\n",hwnd
,pDropTarget
);
239 /***********************************************************************
240 * RegisterDragDrop32 (OLE32.139)
242 HRESULT WINAPI
RegisterDragDrop(
244 LPDROPTARGET pDropTarget
)
246 DropTargetNode
* dropTargetInfo
;
248 TRACE(ole
,"(0x%x,%p)\n", hwnd
, pDropTarget
);
251 * First, check if the window is already registered.
253 dropTargetInfo
= OLEDD_FindDropTarget(hwnd
);
255 if (dropTargetInfo
!=NULL
)
256 return DRAGDROP_E_ALREADYREGISTERED
;
259 * If it's not there, we can add it. We first create a node for it.
261 dropTargetInfo
= HeapAlloc(GetProcessHeap(), 0, sizeof(DropTargetNode
));
263 if (dropTargetInfo
==NULL
)
264 return E_OUTOFMEMORY
;
266 dropTargetInfo
->hwndTarget
= hwnd
;
267 dropTargetInfo
->prevDropTarget
= NULL
;
268 dropTargetInfo
->nextDropTarget
= NULL
;
271 * Don't forget that this is an interface pointer, need to nail it down since
272 * we keep a copy of it.
274 dropTargetInfo
->dropTarget
= pDropTarget
;
275 IDropTarget_AddRef(dropTargetInfo
->dropTarget
);
277 OLEDD_InsertDropTarget(dropTargetInfo
);
282 /***********************************************************************
283 * RevokeDragDrop16 (OLE2.36)
285 HRESULT WINAPI
RevokeDragDrop16(
288 FIXME(ole
,"(0x%04x),stub!\n",hwnd
);
292 /***********************************************************************
293 * RevokeDragDrop32 (OLE32.141)
295 HRESULT WINAPI
RevokeDragDrop(
298 DropTargetNode
* dropTargetInfo
;
300 TRACE(ole
,"(0x%x)\n", hwnd
);
303 * First, check if the window is already registered.
305 dropTargetInfo
= OLEDD_ExtractDropTarget(hwnd
);
308 * If it ain't in there, it's an error.
310 if (dropTargetInfo
==NULL
)
311 return DRAGDROP_E_NOTREGISTERED
;
314 * If it's in there, clean-up it's used memory and
317 IDropTarget_Release(dropTargetInfo
->dropTarget
);
318 HeapFree(GetProcessHeap(), 0, dropTargetInfo
);
323 /***********************************************************************
324 * OleRegGetUserType (OLE32.122)
326 HRESULT WINAPI
OleRegGetUserType(
329 LPOLESTR
* pszUserType
)
331 FIXME(ole
,",stub!\n");
335 /***********************************************************************
336 * DoDragDrop32 [OLE32.65]
338 HRESULT WINAPI
DoDragDrop (
339 IDataObject
*pDataObject
, /* ptr to the data obj */
340 IDropSource
* pDropSource
, /* ptr to the source obj */
341 DWORD dwOKEffect
, /* effects allowed by the source */
342 DWORD
*pdwEffect
) /* ptr to effects of the source */
344 TrackerWindowInfo trackerInfo
;
345 HWND hwndTrackWindow
;
348 TRACE(ole
,"(DataObject %p, DropSource %p)\n", pDataObject
, pDropSource
);
351 * Setup the drag n drop tracking window.
353 trackerInfo
.dataObject
= pDataObject
;
354 trackerInfo
.dropSource
= pDropSource
;
355 trackerInfo
.dwOKEffect
= dwOKEffect
;
356 trackerInfo
.pdwEffect
= pdwEffect
;
357 trackerInfo
.trackingDone
= FALSE
;
358 trackerInfo
.escPressed
= FALSE
;
359 trackerInfo
.curDragTargetHWND
= 0;
360 trackerInfo
.curDragTarget
= 0;
362 hwndTrackWindow
= CreateWindowA(OLEDD_DRAGTRACKERCLASS
,
365 CW_USEDEFAULT
, CW_USEDEFAULT
,
366 CW_USEDEFAULT
, CW_USEDEFAULT
,
370 (LPVOID
)&trackerInfo
);
372 if (hwndTrackWindow
!=0)
375 * Capture the mouse input
377 SetCapture(hwndTrackWindow
);
380 * Pump messages. All mouse input should go the the capture window.
382 while (!trackerInfo
.trackingDone
&& GetMessageA(&msg
, 0, 0, 0) )
384 if ( (msg
.message
>= WM_KEYFIRST
) &&
385 (msg
.message
<= WM_KEYFIRST
) )
388 * When keyboard messages are sent to windows on this thread, we
389 * want to ignore notify the drop source that the state changed.
390 * in the case of the Escape key, we also notify the drop source
391 * we give it a special meaning.
393 if ( (msg
.message
==WM_KEYDOWN
) &&
394 (msg
.wParam
==VK_ESCAPE
) )
396 trackerInfo
.escPressed
= TRUE
;
400 * Notify the drop source.
402 OLEDD_TrackStateChange(&trackerInfo
,
404 OLEDD_GetButtonState());
409 * Dispatch the messages only when it's not a keyboard message.
411 DispatchMessageA(&msg
);
416 * Destroy the temporary window.
418 DestroyWindow(hwndTrackWindow
);
420 return trackerInfo
.returnValue
;
426 /***********************************************************************
427 * OleQueryLinkFromData32 [OLE32.118]
429 HRESULT WINAPI
OleQueryLinkFromData32(
430 IDataObject
* pSrcDataObject
)
432 FIXME(ole
,"(%p),stub!\n", pSrcDataObject
);
436 /***********************************************************************
437 * OleRegGetMiscStatus32 [OLE32.121]
439 HRESULT WINAPI
OleRegGetMiscStatus32(
444 FIXME(ole
,"(),stub!\n");
445 return REGDB_E_CLASSNOTREG
;
448 /***********************************************************************
449 * OleGetClipboard32 [OLE32.105]
451 HRESULT WINAPI
OleGetClipboard32(
452 IDataObject
** ppDataObj
)
454 FIXME(ole
,"(%p),stub!\n", ppDataObj
);
462 /***********************************************************************
463 * OleCreateMenuDescriptor [OLE32.97]
465 HOLEMENU WINAPI
OleCreateMenuDescriptor(
467 LPOLEMENUGROUPWIDTHS lpMenuWidths
)
469 FIXME(ole
,"(%x,%p),stub!\n", hmenuCombined
, lpMenuWidths
);
474 /***********************************************************************
475 * OleDestroyMenuDescriptor [OLE32.99]
477 void WINAPI
OleDestroyMenuDescriptor(
478 HOLEMENU hmenuDescriptor
)
480 FIXME(ole
,"(%x),stub!\n", (unsigned int)hmenuDescriptor
);
483 /***********************************************************************
484 * OleSetMenuDescriptor [OLE32.129]
486 HRESULT WINAPI
OleSetMenuDescriptor(
487 HOLEMENU hmenuDescriptor
,
489 HWND hwndActiveObject
,
490 LPOLEINPLACEFRAME lpFrame
,
491 LPOLEINPLACEACTIVEOBJECT lpActiveObject
)
493 FIXME(ole
,"(%x, %x, %x, %p, %p),stub!\n",
494 (unsigned int)hmenuDescriptor
,
503 /***********************************************************************
504 * ReleaseStgMedium [OLE32.140]
506 void WINAPI
ReleaseStgMedium(
509 switch (pmedium
->tymed
)
513 if ( (pmedium
->pUnkForRelease
==0) &&
514 (pmedium
->u
.hGlobal
!=0) )
515 GlobalFree(pmedium
->u
.hGlobal
);
517 pmedium
->u
.hGlobal
= 0;
522 if (pmedium
->u
.lpszFileName
!=0)
524 if (pmedium
->pUnkForRelease
==0)
526 DeleteFileW(pmedium
->u
.lpszFileName
);
529 CoTaskMemFree(pmedium
->u
.lpszFileName
);
532 pmedium
->u
.lpszFileName
= 0;
537 if (pmedium
->u
.pstm
!=0)
539 IStream_Release(pmedium
->u
.pstm
);
547 if (pmedium
->u
.pstg
!=0)
549 IStorage_Release(pmedium
->u
.pstg
);
557 if ( (pmedium
->pUnkForRelease
==0) &&
558 (pmedium
->u
.hGlobal
!=0) )
559 DeleteObject(pmedium
->u
.hGlobal
);
561 pmedium
->u
.hGlobal
= 0;
566 if ( (pmedium
->pUnkForRelease
==0) &&
567 (pmedium
->u
.hMetaFilePict
!=0) )
569 DeleteMetaFile(pmedium
->u
.hMetaFilePict
);
570 GlobalFree(pmedium
->u
.hMetaFilePict
);
573 pmedium
->u
.hMetaFilePict
= 0;
578 if ( (pmedium
->pUnkForRelease
==0) &&
579 (pmedium
->u
.hEnhMetaFile
!=0) )
581 DeleteEnhMetaFile(pmedium
->u
.hEnhMetaFile
);
584 pmedium
->u
.hEnhMetaFile
= 0;
593 * After cleaning up, the unknown is released
595 if (pmedium
->pUnkForRelease
!=0)
597 IUnknown_Release(pmedium
->pUnkForRelease
);
598 pmedium
->pUnkForRelease
= 0;
605 * Initializes the OLE drag and drop data structures.
607 static void OLEDD_Initialize()
611 ZeroMemory (&wndClass
, sizeof(WNDCLASSA
));
612 wndClass
.style
= CS_GLOBALCLASS
;
613 wndClass
.lpfnWndProc
= (WNDPROC
)OLEDD_DragTrackerWindowProc
;
614 wndClass
.cbClsExtra
= 0;
615 wndClass
.cbWndExtra
= sizeof(TrackerWindowInfo
*);
616 wndClass
.hCursor
= 0;
617 wndClass
.hbrBackground
= 0;
618 wndClass
.lpszClassName
= OLEDD_DRAGTRACKERCLASS
;
620 RegisterClassA (&wndClass
);
624 * OLEDD_UnInitialize()
626 * Releases the OLE drag and drop data structures.
628 static void OLEDD_UnInitialize()
631 * Simply empty the list.
633 while (targetListHead
!=NULL
)
635 RevokeDragDrop(targetListHead
->hwndTarget
);
640 * OLEDD_InsertDropTarget()
642 * Insert the target node in the tree.
644 static void OLEDD_InsertDropTarget(DropTargetNode
* nodeToAdd
)
646 DropTargetNode
* curNode
;
647 DropTargetNode
** parentNodeLink
;
650 * Iterate the tree to find the insertion point.
652 curNode
= targetListHead
;
653 parentNodeLink
= &targetListHead
;
655 while (curNode
!=NULL
)
657 if (nodeToAdd
->hwndTarget
<curNode
->hwndTarget
)
660 * If the node we want to add has a smaller HWND, go left
662 parentNodeLink
= &curNode
->prevDropTarget
;
663 curNode
= curNode
->prevDropTarget
;
665 else if (nodeToAdd
->hwndTarget
>curNode
->hwndTarget
)
668 * If the node we want to add has a larger HWND, go right
670 parentNodeLink
= &curNode
->nextDropTarget
;
671 curNode
= curNode
->nextDropTarget
;
676 * The item was found in the list. It shouldn't have been there
684 * If we get here, we have found a spot for our item. The parentNodeLink
685 * pointer points to the pointer that we have to modify.
686 * The curNode should be NULL. We just have to establish the link and Voila!
688 assert(curNode
==NULL
);
689 assert(parentNodeLink
!=NULL
);
690 assert(*parentNodeLink
==NULL
);
692 *parentNodeLink
=nodeToAdd
;
696 * OLEDD_ExtractDropTarget()
698 * Removes the target node from the tree.
700 static DropTargetNode
* OLEDD_ExtractDropTarget(HWND hwndOfTarget
)
702 DropTargetNode
* curNode
;
703 DropTargetNode
** parentNodeLink
;
706 * Iterate the tree to find the insertion point.
708 curNode
= targetListHead
;
709 parentNodeLink
= &targetListHead
;
711 while (curNode
!=NULL
)
713 if (hwndOfTarget
<curNode
->hwndTarget
)
716 * If the node we want to add has a smaller HWND, go left
718 parentNodeLink
= &curNode
->prevDropTarget
;
719 curNode
= curNode
->prevDropTarget
;
721 else if (hwndOfTarget
>curNode
->hwndTarget
)
724 * If the node we want to add has a larger HWND, go right
726 parentNodeLink
= &curNode
->nextDropTarget
;
727 curNode
= curNode
->nextDropTarget
;
732 * The item was found in the list. Detach it from it's parent and
733 * re-insert it's kids in the tree.
735 assert(parentNodeLink
!=NULL
);
736 assert(*parentNodeLink
==curNode
);
739 * We arbitrately re-attach the left sub-tree to the parent.
741 *parentNodeLink
= curNode
->prevDropTarget
;
744 * And we re-insert the right subtree
746 if (curNode
->nextDropTarget
!=NULL
)
748 OLEDD_InsertDropTarget(curNode
->nextDropTarget
);
752 * The node we found is still a valid node once we complete
753 * the unlinking of the kids.
755 curNode
->nextDropTarget
=NULL
;
756 curNode
->prevDropTarget
=NULL
;
763 * If we get here, the node is not in the tree
769 * OLEDD_FindDropTarget()
771 * Finds information about the drop target.
773 static DropTargetNode
* OLEDD_FindDropTarget(HWND hwndOfTarget
)
775 DropTargetNode
* curNode
;
778 * Iterate the tree to find the HWND value.
780 curNode
= targetListHead
;
782 while (curNode
!=NULL
)
784 if (hwndOfTarget
<curNode
->hwndTarget
)
787 * If the node we want to add has a smaller HWND, go left
789 curNode
= curNode
->prevDropTarget
;
791 else if (hwndOfTarget
>curNode
->hwndTarget
)
794 * If the node we want to add has a larger HWND, go right
796 curNode
= curNode
->nextDropTarget
;
801 * The item was found in the list.
808 * If we get here, the item is not in the list
814 * OLEDD_DragTrackerWindowProc()
816 * This method is the WindowProcedure of the drag n drop tracking
817 * window. During a drag n Drop operation, an invisible window is created
818 * to receive the user input and act upon it. This procedure is in charge
821 static LRESULT WINAPI
OLEDD_DragTrackerWindowProc(
831 LPCREATESTRUCTA createStruct
= (LPCREATESTRUCTA
)lParam
;
833 SetWindowLongA(hwnd
, 0, (LONG
)createStruct
->lpCreateParams
);
840 TrackerWindowInfo
* trackerInfo
= (TrackerWindowInfo
*)GetWindowLongA(hwnd
, 0);
844 * Get the current mouse position in screen coordinates.
846 mousePos
.x
= LOWORD(lParam
);
847 mousePos
.y
= HIWORD(lParam
);
848 ClientToScreen(hwnd
, &mousePos
);
851 * Track the movement of the mouse.
853 OLEDD_TrackMouseMove(trackerInfo
, mousePos
, wParam
);
864 TrackerWindowInfo
* trackerInfo
= (TrackerWindowInfo
*)GetWindowLongA(hwnd
, 0);
868 * Get the current mouse position in screen coordinates.
870 mousePos
.x
= LOWORD(lParam
);
871 mousePos
.y
= HIWORD(lParam
);
872 ClientToScreen(hwnd
, &mousePos
);
875 * Notify everyone that the button state changed
876 * TODO: Check if the "escape" key was pressed.
878 OLEDD_TrackStateChange(trackerInfo
, mousePos
, wParam
);
885 * This is a window proc after all. Let's call the default.
887 return DefWindowProcA (hwnd
, uMsg
, wParam
, lParam
);
891 * OLEDD_TrackMouseMove()
893 * This method is invoked while a drag and drop operation is in effect.
894 * it will generate the appropriate callbacks in the drop source
895 * and drop target. It will also provide the expected feedback to
899 * trackerInfo - Pointer to the structure identifying the
900 * drag & drop operation that is currently
902 * mousePos - Current position of the mouse in screen
904 * keyState - Contains the state of the shift keys and the
905 * mouse buttons (MK_LBUTTON and the like)
907 static void OLEDD_TrackMouseMove(
908 TrackerWindowInfo
* trackerInfo
,
912 HWND hwndNewTarget
= 0;
916 * Get the handle of the window under the mouse
918 hwndNewTarget
= WindowFromPoint(mousePos
);
921 * If we are hovering over the same target as before, send the
922 * DragOver notification
924 if ( (trackerInfo
->curDragTarget
!= 0) &&
925 (trackerInfo
->curDragTargetHWND
==hwndNewTarget
) )
927 POINTL mousePosParam
;
930 * The documentation tells me that the coordinate should be in the target
931 * window's coordinate space. However, the tests I made tell me the
932 * coordinates should be in screen coordinates.
934 mousePosParam
.x
= mousePos
.x
;
935 mousePosParam
.y
= mousePos
.y
;
937 IDropTarget_DragOver(trackerInfo
->curDragTarget
,
940 trackerInfo
->pdwEffect
);
944 DropTargetNode
* newDropTargetNode
= 0;
947 * If we changed window, we have to notify our old target and check for
950 if (trackerInfo
->curDragTarget
!=0)
952 IDropTarget_DragLeave(trackerInfo
->curDragTarget
);
956 * Make sure we're hovering over a window.
958 if (hwndNewTarget
!=0)
961 * Find-out if there is a drag target under the mouse
963 newDropTargetNode
= OLEDD_FindDropTarget(hwndNewTarget
);
965 trackerInfo
->curDragTargetHWND
= hwndNewTarget
;
966 trackerInfo
->curDragTarget
= newDropTargetNode
? newDropTargetNode
->dropTarget
: 0;
969 * If there is, notify it that we just dragged-in
971 if (trackerInfo
->curDragTarget
!=0)
973 POINTL mousePosParam
;
976 * The documentation tells me that the coordinate should be in the target
977 * window's coordinate space. However, the tests I made tell me the
978 * coordinates should be in screen coordinates.
980 mousePosParam
.x
= mousePos
.x
;
981 mousePosParam
.y
= mousePos
.y
;
983 IDropTarget_DragEnter(trackerInfo
->curDragTarget
,
984 trackerInfo
->dataObject
,
987 trackerInfo
->pdwEffect
);
993 * The mouse is not over a window so we don't track anything.
995 trackerInfo
->curDragTargetHWND
= 0;
996 trackerInfo
->curDragTarget
= 0;
1001 * Now that we have done that, we have to tell the source to give
1002 * us feedback on the work being done by the target. If we don't
1003 * have a target, simulate no effect.
1005 if (trackerInfo
->curDragTarget
==0)
1007 *trackerInfo
->pdwEffect
= DROPEFFECT_NONE
;
1010 hr
= IDropSource_GiveFeedback(trackerInfo
->dropSource
,
1011 *trackerInfo
->pdwEffect
);
1014 * When we ask for feedback from the drop source, sometimes it will
1015 * do all the necessary work and sometimes it will not handle it
1016 * when that's the case, we must display the standard drag and drop
1019 if (hr
==DRAGDROP_S_USEDEFAULTCURSORS
)
1021 if ( (*trackerInfo
->pdwEffect
& DROPEFFECT_MOVE
) ||
1022 (*trackerInfo
->pdwEffect
& DROPEFFECT_COPY
) ||
1023 (*trackerInfo
->pdwEffect
& DROPEFFECT_LINK
) )
1025 SetCursor(LoadCursorA(0, IDC_SIZEALLA
));
1029 SetCursor(LoadCursorA(0, IDC_NOA
));
1035 * OLEDD_TrackStateChange()
1037 * This method is invoked while a drag and drop operation is in effect.
1038 * It is used to notify the drop target/drop source callbacks when
1039 * the state of the keyboard or mouse button change.
1042 * trackerInfo - Pointer to the structure identifying the
1043 * drag & drop operation that is currently
1045 * mousePos - Current position of the mouse in screen
1047 * keyState - Contains the state of the shift keys and the
1048 * mouse buttons (MK_LBUTTON and the like)
1050 static void OLEDD_TrackStateChange(
1051 TrackerWindowInfo
* trackerInfo
,
1056 * Ask the drop source what to do with the operation.
1058 trackerInfo
->returnValue
= IDropSource_QueryContinueDrag(
1059 trackerInfo
->dropSource
,
1060 trackerInfo
->escPressed
,
1064 * All the return valued will stop the operation except the S_OK
1067 if (trackerInfo
->returnValue
!=S_OK
)
1070 * Make sure the message loop in DoDragDrop stops
1072 trackerInfo
->trackingDone
= TRUE
;
1075 * Release the mouse in case the drop target decides to show a popup
1076 * or a menu or something.
1081 * If we end-up over a target, drop the object in the target or
1082 * inform the target that the operation was cancelled.
1084 if (trackerInfo
->curDragTarget
!=0)
1086 switch (trackerInfo
->returnValue
)
1089 * If the source wants us to complete the operation, we tell
1090 * the drop target that we just dropped the object in it.
1092 case DRAGDROP_S_DROP
:
1094 POINTL mousePosParam
;
1097 * The documentation tells me that the coordinate should be
1098 * in the target window's coordinate space. However, the tests
1099 * I made tell me the coordinates should be in screen coordinates.
1101 mousePosParam
.x
= mousePos
.x
;
1102 mousePosParam
.y
= mousePos
.y
;
1104 IDropTarget_Drop(trackerInfo
->curDragTarget
,
1105 trackerInfo
->dataObject
,
1108 trackerInfo
->pdwEffect
);
1112 * If the source told us that we should cancel, fool the drop
1113 * target by telling it that the mouse left it's window.
1115 case DRAGDROP_S_CANCEL
:
1116 IDropTarget_DragLeave(trackerInfo
->curDragTarget
);
1124 * OLEDD_GetButtonState()
1126 * This method will use the current state of the keyboard to build
1127 * a button state mask equivalent to the one passed in the
1128 * WM_MOUSEMOVE wParam.
1130 static DWORD
OLEDD_GetButtonState()
1132 BYTE keyboardState
[256];
1135 GetKeyboardState(keyboardState
);
1137 if ( (keyboardState
[VK_SHIFT
] & 0x80) !=0)
1138 keyMask
|= MK_SHIFT
;
1140 if ( (keyboardState
[VK_CONTROL
] & 0x80) !=0)
1141 keyMask
|= MK_CONTROL
;
1143 if ( (keyboardState
[VK_LBUTTON
] & 0x80) !=0)
1144 keyMask
|= MK_LBUTTON
;
1146 if ( (keyboardState
[VK_RBUTTON
] & 0x80) !=0)
1147 keyMask
|= MK_RBUTTON
;
1149 if ( (keyboardState
[VK_MBUTTON
] & 0x80) !=0)
1150 keyMask
|= MK_MBUTTON
;