4 * Copyright 1995 Martin von Loewis
5 * Copyright 1999 Francis Beaudet
14 #include "wine/obj_clientserver.h"
18 /******************************************************************************
19 * These are static/global variables and internal data structures that the
20 * OLE module uses to maintain it's state.
22 typedef struct tagDropTargetNode
25 IDropTarget
* dropTarget
;
26 struct tagDropTargetNode
* prevDropTarget
;
27 struct tagDropTargetNode
* nextDropTarget
;
30 typedef struct tagTrackerWindowInfo
32 IDataObject
* dataObject
;
33 IDropSource
* dropSource
;
40 HWND curDragTargetHWND
;
41 IDropTarget
* curDragTarget
;
45 * This is the lock count on the OLE library. It is controlled by the
46 * OLEInitialize/OLEUninitialize methods.
48 static ULONG OLE_moduleLockCount
= 0;
51 * Name of our registered window class.
53 static const char OLEDD_DRAGTRACKERCLASS
[] = "WineDragDropTracker32";
56 * This is the head of the Drop target container.
58 static DropTargetNode
* targetListHead
= NULL
;
60 /******************************************************************************
61 * These are the prototypes of the utility methods used for OLE Drag n Drop
63 static void OLEDD_Initialize();
64 static void OLEDD_UnInitialize();
65 static void OLEDD_InsertDropTarget(
66 DropTargetNode
* nodeToAdd
);
67 static DropTargetNode
* OLEDD_ExtractDropTarget(
69 static DropTargetNode
* OLEDD_FindDropTarget(
71 static LRESULT WINAPI
OLEDD_DragTrackerWindowProc(
76 static void OLEDD_TrackMouseMove(
77 TrackerWindowInfo
* trackerInfo
,
80 static void OLEDD_TrackStateChange(
81 TrackerWindowInfo
* trackerInfo
,
84 static DWORD
OLEDD_GetButtonState();
87 /******************************************************************************
88 * OleBuildVersion [OLE2.1]
90 DWORD WINAPI
OleBuildVersion(void)
92 TRACE(ole
,"(void)\n");
96 /***********************************************************************
97 * OleInitialize (OLE2.2) (OLE32.108)
99 HRESULT WINAPI
OleInitialize(LPVOID reserved
)
103 TRACE(ole
, "(%p)\n", reserved
);
106 * The first duty of the OleInitialize is to initialize the COM libraries.
108 hr
= CoInitializeEx(NULL
, COINIT_APARTMENTTHREADED
);
111 * If the CoInitializeEx call failed, the OLE libraries can't be
118 * Then, it has to initialize the OLE specific modules.
122 * Object linking and Embedding
123 * In-place activation
125 if (OLE_moduleLockCount
==0)
128 * Initialize the libraries.
130 TRACE(ole
, "() - Initializing the OLE libraries\n");
139 * Then, we increase the lock count on the OLE module.
141 OLE_moduleLockCount
++;
146 /******************************************************************************
147 * CoGetCurrentProcess [COMPOBJ.34] [OLE2.2][OLE32.108]
150 * Is DWORD really the correct return type for this function?
152 DWORD WINAPI
CoGetCurrentProcess(void) {
153 return (DWORD
)PROCESS_Current();
156 /******************************************************************************
157 * OleUninitialize [OLE2.3] [OLE32.131]
159 void WINAPI
OleUninitialize(void)
164 * Decrease the lock count on the OLE module.
166 OLE_moduleLockCount
--;
169 * If we hit the bottom of the lock stack, free the libraries.
171 if (OLE_moduleLockCount
==0)
174 * Actually free the libraries.
176 TRACE(ole
, "() - Freeing the last reference count\n");
181 OLEDD_UnInitialize();
185 * Then, uninitialize the COM libraries.
190 /***********************************************************************
191 * OleFlushClipboard [OLE2.76]
193 HRESULT WINAPI
OleFlushClipboard16(void)
198 /***********************************************************************
199 * OleSetClipboard [OLE32.127]
201 HRESULT WINAPI
OleSetClipboard(LPVOID pDataObj
)
203 FIXME(ole
,"(%p), stub!\n", pDataObj
);
207 /******************************************************************************
208 * CoRegisterMessageFilter32 [OLE32.38]
210 HRESULT WINAPI
CoRegisterMessageFilter(
211 LPMESSAGEFILTER lpMessageFilter
, /* Pointer to interface */
212 LPMESSAGEFILTER
*lplpMessageFilter
/* Indirect pointer to prior instance if non-NULL */
215 if (lplpMessageFilter
) {
216 *lplpMessageFilter
= NULL
;
221 /******************************************************************************
222 * OleInitializeWOW [OLE32.109]
224 HRESULT WINAPI
OleInitializeWOW(DWORD x
) {
225 FIXME(ole
,"(0x%08lx),stub!\n",x
);
229 /***********************************************************************
230 * RegisterDragDrop16 (OLE2.35)
232 HRESULT WINAPI
RegisterDragDrop16(
234 LPDROPTARGET pDropTarget
236 FIXME(ole
,"(0x%04x,%p),stub!\n",hwnd
,pDropTarget
);
240 /***********************************************************************
241 * RegisterDragDrop32 (OLE32.139)
243 HRESULT WINAPI
RegisterDragDrop(
245 LPDROPTARGET pDropTarget
)
247 DropTargetNode
* dropTargetInfo
;
249 TRACE(ole
,"(0x%x,%p)\n", hwnd
, pDropTarget
);
252 * First, check if the window is already registered.
254 dropTargetInfo
= OLEDD_FindDropTarget(hwnd
);
256 if (dropTargetInfo
!=NULL
)
257 return DRAGDROP_E_ALREADYREGISTERED
;
260 * If it's not there, we can add it. We first create a node for it.
262 dropTargetInfo
= HeapAlloc(GetProcessHeap(), 0, sizeof(DropTargetNode
));
264 if (dropTargetInfo
==NULL
)
265 return E_OUTOFMEMORY
;
267 dropTargetInfo
->hwndTarget
= hwnd
;
268 dropTargetInfo
->prevDropTarget
= NULL
;
269 dropTargetInfo
->nextDropTarget
= NULL
;
272 * Don't forget that this is an interface pointer, need to nail it down since
273 * we keep a copy of it.
275 dropTargetInfo
->dropTarget
= pDropTarget
;
276 IDropTarget_AddRef(dropTargetInfo
->dropTarget
);
278 OLEDD_InsertDropTarget(dropTargetInfo
);
283 /***********************************************************************
284 * RevokeDragDrop16 (OLE2.36)
286 HRESULT WINAPI
RevokeDragDrop16(
289 FIXME(ole
,"(0x%04x),stub!\n",hwnd
);
293 /***********************************************************************
294 * RevokeDragDrop32 (OLE32.141)
296 HRESULT WINAPI
RevokeDragDrop(
299 DropTargetNode
* dropTargetInfo
;
301 TRACE(ole
,"(0x%x)\n", hwnd
);
304 * First, check if the window is already registered.
306 dropTargetInfo
= OLEDD_ExtractDropTarget(hwnd
);
309 * If it ain't in there, it's an error.
311 if (dropTargetInfo
==NULL
)
312 return DRAGDROP_E_NOTREGISTERED
;
315 * If it's in there, clean-up it's used memory and
318 IDropTarget_Release(dropTargetInfo
->dropTarget
);
319 HeapFree(GetProcessHeap(), 0, dropTargetInfo
);
324 /***********************************************************************
325 * OleRegGetUserType (OLE32.122)
327 HRESULT WINAPI
OleRegGetUserType(
330 LPOLESTR
* pszUserType
)
332 FIXME(ole
,",stub!\n");
336 /***********************************************************************
337 * DoDragDrop32 [OLE32.65]
339 HRESULT WINAPI
DoDragDrop (
340 IDataObject
*pDataObject
, /* ptr to the data obj */
341 IDropSource
* pDropSource
, /* ptr to the source obj */
342 DWORD dwOKEffect
, /* effects allowed by the source */
343 DWORD
*pdwEffect
) /* ptr to effects of the source */
345 TrackerWindowInfo trackerInfo
;
346 HWND hwndTrackWindow
;
349 TRACE(ole
,"(DataObject %p, DropSource %p)\n", pDataObject
, pDropSource
);
352 * Setup the drag n drop tracking window.
354 trackerInfo
.dataObject
= pDataObject
;
355 trackerInfo
.dropSource
= pDropSource
;
356 trackerInfo
.dwOKEffect
= dwOKEffect
;
357 trackerInfo
.pdwEffect
= pdwEffect
;
358 trackerInfo
.trackingDone
= FALSE
;
359 trackerInfo
.escPressed
= FALSE
;
360 trackerInfo
.curDragTargetHWND
= 0;
361 trackerInfo
.curDragTarget
= 0;
363 hwndTrackWindow
= CreateWindowA(OLEDD_DRAGTRACKERCLASS
,
366 CW_USEDEFAULT
, CW_USEDEFAULT
,
367 CW_USEDEFAULT
, CW_USEDEFAULT
,
371 (LPVOID
)&trackerInfo
);
373 if (hwndTrackWindow
!=0)
376 * Capture the mouse input
378 SetCapture(hwndTrackWindow
);
381 * Pump messages. All mouse input should go the the capture window.
383 while (!trackerInfo
.trackingDone
&& GetMessageA(&msg
, 0, 0, 0) )
385 if ( (msg
.message
>= WM_KEYFIRST
) &&
386 (msg
.message
<= WM_KEYFIRST
) )
389 * When keyboard messages are sent to windows on this thread, we
390 * want to ignore notify the drop source that the state changed.
391 * in the case of the Escape key, we also notify the drop source
392 * we give it a special meaning.
394 if ( (msg
.message
==WM_KEYDOWN
) &&
395 (msg
.wParam
==VK_ESCAPE
) )
397 trackerInfo
.escPressed
= TRUE
;
401 * Notify the drop source.
403 OLEDD_TrackStateChange(&trackerInfo
,
405 OLEDD_GetButtonState());
410 * Dispatch the messages only when it's not a keyboard message.
412 DispatchMessageA(&msg
);
417 * Destroy the temporary window.
419 DestroyWindow(hwndTrackWindow
);
421 return trackerInfo
.returnValue
;
427 /***********************************************************************
428 * OleQueryLinkFromData32 [OLE32.118]
430 HRESULT WINAPI
OleQueryLinkFromData32(
431 IDataObject
* pSrcDataObject
)
433 FIXME(ole
,"(%p),stub!\n", pSrcDataObject
);
437 /***********************************************************************
438 * OleRegGetMiscStatus32 [OLE32.121]
440 HRESULT WINAPI
OleRegGetMiscStatus32(
445 FIXME(ole
,"(),stub!\n");
446 return REGDB_E_CLASSNOTREG
;
449 /***********************************************************************
450 * OleGetClipboard32 [OLE32.105]
452 HRESULT WINAPI
OleGetClipboard32(
453 IDataObject
** ppDataObj
)
455 FIXME(ole
,"(%p),stub!\n", ppDataObj
);
463 /***********************************************************************
464 * OleCreateMenuDescriptor [OLE32.97]
466 HOLEMENU WINAPI
OleCreateMenuDescriptor(
468 LPOLEMENUGROUPWIDTHS lpMenuWidths
)
470 FIXME(ole
,"(%x,%p),stub!\n", hmenuCombined
, lpMenuWidths
);
475 /***********************************************************************
476 * OleDestroyMenuDescriptor [OLE32.99]
478 HRESULT WINAPI
OleDestroyMenuDescriptor(
479 HOLEMENU hmenuDescriptor
)
481 FIXME(ole
,"(%x),stub!\n", (unsigned int)hmenuDescriptor
);
485 /***********************************************************************
486 * OleSetMenuDescriptor [OLE32.129]
488 HRESULT WINAPI
OleSetMenuDescriptor(
489 HOLEMENU hmenuDescriptor
,
491 HWND hwndActiveObject
,
492 LPOLEINPLACEFRAME lpFrame
,
493 LPOLEINPLACEACTIVEOBJECT lpActiveObject
)
495 FIXME(ole
,"(%x, %x, %x, %p, %p),stub!\n",
496 (unsigned int)hmenuDescriptor
,
505 /***********************************************************************
506 * ReleaseStgMedium [OLE32.140]
508 void WINAPI
ReleaseStgMedium(
511 switch (pmedium
->tymed
)
515 if ( (pmedium
->pUnkForRelease
==0) &&
516 (pmedium
->u
.hGlobal
!=0) )
517 GlobalFree(pmedium
->u
.hGlobal
);
519 pmedium
->u
.hGlobal
= 0;
524 if (pmedium
->u
.lpszFileName
!=0)
526 if (pmedium
->pUnkForRelease
==0)
528 DeleteFileW(pmedium
->u
.lpszFileName
);
531 CoTaskMemFree(pmedium
->u
.lpszFileName
);
534 pmedium
->u
.lpszFileName
= 0;
539 if (pmedium
->u
.pstm
!=0)
541 IStream_Release(pmedium
->u
.pstm
);
549 if (pmedium
->u
.pstg
!=0)
551 IStorage_Release(pmedium
->u
.pstg
);
559 if ( (pmedium
->pUnkForRelease
==0) &&
560 (pmedium
->u
.hGlobal
!=0) )
561 DeleteObject(pmedium
->u
.hGlobal
);
563 pmedium
->u
.hGlobal
= 0;
568 if ( (pmedium
->pUnkForRelease
==0) &&
569 (pmedium
->u
.hMetaFilePict
!=0) )
571 DeleteMetaFile(pmedium
->u
.hMetaFilePict
);
572 GlobalFree(pmedium
->u
.hMetaFilePict
);
575 pmedium
->u
.hMetaFilePict
= 0;
580 if ( (pmedium
->pUnkForRelease
==0) &&
581 (pmedium
->u
.hEnhMetaFile
!=0) )
583 DeleteEnhMetaFile(pmedium
->u
.hEnhMetaFile
);
586 pmedium
->u
.hEnhMetaFile
= 0;
595 * After cleaning up, the unknown is released
597 if (pmedium
->pUnkForRelease
!=0)
599 IUnknown_Release(pmedium
->pUnkForRelease
);
600 pmedium
->pUnkForRelease
= 0;
607 * Initializes the OLE drag and drop data structures.
609 static void OLEDD_Initialize()
613 ZeroMemory (&wndClass
, sizeof(WNDCLASSA
));
614 wndClass
.style
= CS_GLOBALCLASS
;
615 wndClass
.lpfnWndProc
= (WNDPROC
)OLEDD_DragTrackerWindowProc
;
616 wndClass
.cbClsExtra
= 0;
617 wndClass
.cbWndExtra
= sizeof(TrackerWindowInfo
*);
618 wndClass
.hCursor
= 0;
619 wndClass
.hbrBackground
= 0;
620 wndClass
.lpszClassName
= OLEDD_DRAGTRACKERCLASS
;
622 RegisterClassA (&wndClass
);
626 * OLEDD_UnInitialize()
628 * Releases the OLE drag and drop data structures.
630 static void OLEDD_UnInitialize()
633 * Simply empty the list.
635 while (targetListHead
!=NULL
)
637 RevokeDragDrop(targetListHead
->hwndTarget
);
642 * OLEDD_InsertDropTarget()
644 * Insert the target node in the tree.
646 static void OLEDD_InsertDropTarget(DropTargetNode
* nodeToAdd
)
648 DropTargetNode
* curNode
;
649 DropTargetNode
** parentNodeLink
;
652 * Iterate the tree to find the insertion point.
654 curNode
= targetListHead
;
655 parentNodeLink
= &targetListHead
;
657 while (curNode
!=NULL
)
659 if (nodeToAdd
->hwndTarget
<curNode
->hwndTarget
)
662 * If the node we want to add has a smaller HWND, go left
664 parentNodeLink
= &curNode
->prevDropTarget
;
665 curNode
= curNode
->prevDropTarget
;
667 else if (nodeToAdd
->hwndTarget
>curNode
->hwndTarget
)
670 * If the node we want to add has a larger HWND, go right
672 parentNodeLink
= &curNode
->nextDropTarget
;
673 curNode
= curNode
->nextDropTarget
;
678 * The item was found in the list. It shouldn't have been there
686 * If we get here, we have found a spot for our item. The parentNodeLink
687 * pointer points to the pointer that we have to modify.
688 * The curNode should be NULL. We just have to establish the link and Voila!
690 assert(curNode
==NULL
);
691 assert(parentNodeLink
!=NULL
);
692 assert(*parentNodeLink
==NULL
);
694 *parentNodeLink
=nodeToAdd
;
698 * OLEDD_ExtractDropTarget()
700 * Removes the target node from the tree.
702 static DropTargetNode
* OLEDD_ExtractDropTarget(HWND hwndOfTarget
)
704 DropTargetNode
* curNode
;
705 DropTargetNode
** parentNodeLink
;
708 * Iterate the tree to find the insertion point.
710 curNode
= targetListHead
;
711 parentNodeLink
= &targetListHead
;
713 while (curNode
!=NULL
)
715 if (hwndOfTarget
<curNode
->hwndTarget
)
718 * If the node we want to add has a smaller HWND, go left
720 parentNodeLink
= &curNode
->prevDropTarget
;
721 curNode
= curNode
->prevDropTarget
;
723 else if (hwndOfTarget
>curNode
->hwndTarget
)
726 * If the node we want to add has a larger HWND, go right
728 parentNodeLink
= &curNode
->nextDropTarget
;
729 curNode
= curNode
->nextDropTarget
;
734 * The item was found in the list. Detach it from it's parent and
735 * re-insert it's kids in the tree.
737 assert(parentNodeLink
!=NULL
);
738 assert(*parentNodeLink
==curNode
);
741 * We arbitrately re-attach the left sub-tree to the parent.
743 *parentNodeLink
= curNode
->prevDropTarget
;
746 * And we re-insert the right subtree
748 if (curNode
->nextDropTarget
!=NULL
)
750 OLEDD_InsertDropTarget(curNode
->nextDropTarget
);
754 * The node we found is still a valid node once we complete
755 * the unlinking of the kids.
757 curNode
->nextDropTarget
=NULL
;
758 curNode
->prevDropTarget
=NULL
;
765 * If we get here, the node is not in the tree
771 * OLEDD_FindDropTarget()
773 * Finds information about the drop target.
775 static DropTargetNode
* OLEDD_FindDropTarget(HWND hwndOfTarget
)
777 DropTargetNode
* curNode
;
780 * Iterate the tree to find the HWND value.
782 curNode
= targetListHead
;
784 while (curNode
!=NULL
)
786 if (hwndOfTarget
<curNode
->hwndTarget
)
789 * If the node we want to add has a smaller HWND, go left
791 curNode
= curNode
->prevDropTarget
;
793 else if (hwndOfTarget
>curNode
->hwndTarget
)
796 * If the node we want to add has a larger HWND, go right
798 curNode
= curNode
->nextDropTarget
;
803 * The item was found in the list.
810 * If we get here, the item is not in the list
816 * OLEDD_DragTrackerWindowProc()
818 * This method is the WindowProcedure of the drag n drop tracking
819 * window. During a drag n Drop operation, an invisible window is created
820 * to receive the user input and act upon it. This procedure is in charge
823 static LRESULT WINAPI
OLEDD_DragTrackerWindowProc(
833 LPCREATESTRUCTA createStruct
= (LPCREATESTRUCTA
)lParam
;
835 SetWindowLongA(hwnd
, 0, (LONG
)createStruct
->lpCreateParams
);
842 TrackerWindowInfo
* trackerInfo
= (TrackerWindowInfo
*)GetWindowLongA(hwnd
, 0);
846 * Get the current mouse position in screen coordinates.
848 mousePos
.x
= LOWORD(lParam
);
849 mousePos
.y
= HIWORD(lParam
);
850 ClientToScreen(hwnd
, &mousePos
);
853 * Track the movement of the mouse.
855 OLEDD_TrackMouseMove(trackerInfo
, mousePos
, wParam
);
866 TrackerWindowInfo
* trackerInfo
= (TrackerWindowInfo
*)GetWindowLongA(hwnd
, 0);
870 * Get the current mouse position in screen coordinates.
872 mousePos
.x
= LOWORD(lParam
);
873 mousePos
.y
= HIWORD(lParam
);
874 ClientToScreen(hwnd
, &mousePos
);
877 * Notify everyone that the button state changed
878 * TODO: Check if the "escape" key was pressed.
880 OLEDD_TrackStateChange(trackerInfo
, mousePos
, wParam
);
887 * This is a window proc after all. Let's call the default.
889 return DefWindowProcA (hwnd
, uMsg
, wParam
, lParam
);
893 * OLEDD_TrackMouseMove()
895 * This method is invoked while a drag and drop operation is in effect.
896 * it will generate the appropriate callbacks in the drop source
897 * and drop target. It will also provide the expected feedback to
901 * trackerInfo - Pointer to the structure identifying the
902 * drag & drop operation that is currently
904 * mousePos - Current position of the mouse in screen
906 * keyState - Contains the state of the shift keys and the
907 * mouse buttons (MK_LBUTTON and the like)
909 static void OLEDD_TrackMouseMove(
910 TrackerWindowInfo
* trackerInfo
,
914 HWND hwndNewTarget
= 0;
918 * Get the handle of the window under the mouse
920 hwndNewTarget
= WindowFromPoint(mousePos
);
923 * If we are hovering over the same target as before, send the
924 * DragOver notification
926 if ( (trackerInfo
->curDragTarget
!= 0) &&
927 (trackerInfo
->curDragTargetHWND
==hwndNewTarget
) )
929 POINTL mousePosParam
;
932 * The documentation tells me that the coordinate should be in the target
933 * window's coordinate space. However, the tests I made tell me the
934 * coordinates should be in screen coordinates.
936 mousePosParam
.x
= mousePos
.x
;
937 mousePosParam
.y
= mousePos
.y
;
939 IDropTarget_DragOver(trackerInfo
->curDragTarget
,
942 trackerInfo
->pdwEffect
);
946 DropTargetNode
* newDropTargetNode
= 0;
949 * If we changed window, we have to notify our old target and check for
952 if (trackerInfo
->curDragTarget
!=0)
954 IDropTarget_DragLeave(trackerInfo
->curDragTarget
);
958 * Make sure we're hovering over a window.
960 if (hwndNewTarget
!=0)
963 * Find-out if there is a drag target under the mouse
965 newDropTargetNode
= OLEDD_FindDropTarget(hwndNewTarget
);
967 trackerInfo
->curDragTargetHWND
= hwndNewTarget
;
968 trackerInfo
->curDragTarget
= newDropTargetNode
? newDropTargetNode
->dropTarget
: 0;
971 * If there is, notify it that we just dragged-in
973 if (trackerInfo
->curDragTarget
!=0)
975 POINTL mousePosParam
;
978 * The documentation tells me that the coordinate should be in the target
979 * window's coordinate space. However, the tests I made tell me the
980 * coordinates should be in screen coordinates.
982 mousePosParam
.x
= mousePos
.x
;
983 mousePosParam
.y
= mousePos
.y
;
985 IDropTarget_DragEnter(trackerInfo
->curDragTarget
,
986 trackerInfo
->dataObject
,
989 trackerInfo
->pdwEffect
);
995 * The mouse is not over a window so we don't track anything.
997 trackerInfo
->curDragTargetHWND
= 0;
998 trackerInfo
->curDragTarget
= 0;
1003 * Now that we have done that, we have to tell the source to give
1004 * us feedback on the work being done by the target. If we don't
1005 * have a target, simulate no effect.
1007 if (trackerInfo
->curDragTarget
==0)
1009 *trackerInfo
->pdwEffect
= DROPEFFECT_NONE
;
1012 hr
= IDropSource_GiveFeedback(trackerInfo
->dropSource
,
1013 *trackerInfo
->pdwEffect
);
1016 * When we ask for feedback from the drop source, sometimes it will
1017 * do all the necessary work and sometimes it will not handle it
1018 * when that's the case, we must display the standard drag and drop
1021 if (hr
==DRAGDROP_S_USEDEFAULTCURSORS
)
1023 if ( (*trackerInfo
->pdwEffect
& DROPEFFECT_MOVE
) ||
1024 (*trackerInfo
->pdwEffect
& DROPEFFECT_COPY
) ||
1025 (*trackerInfo
->pdwEffect
& DROPEFFECT_LINK
) )
1027 SetCursor(LoadCursorA(0, IDC_SIZEALLA
));
1031 SetCursor(LoadCursorA(0, IDC_NOA
));
1037 * OLEDD_TrackStateChange()
1039 * This method is invoked while a drag and drop operation is in effect.
1040 * It is used to notify the drop target/drop source callbacks when
1041 * the state of the keyboard or mouse button change.
1044 * trackerInfo - Pointer to the structure identifying the
1045 * drag & drop operation that is currently
1047 * mousePos - Current position of the mouse in screen
1049 * keyState - Contains the state of the shift keys and the
1050 * mouse buttons (MK_LBUTTON and the like)
1052 static void OLEDD_TrackStateChange(
1053 TrackerWindowInfo
* trackerInfo
,
1058 * Ask the drop source what to do with the operation.
1060 trackerInfo
->returnValue
= IDropSource_QueryContinueDrag(
1061 trackerInfo
->dropSource
,
1062 trackerInfo
->escPressed
,
1066 * All the return valued will stop the operation except the S_OK
1069 if (trackerInfo
->returnValue
!=S_OK
)
1072 * Make sure the message loop in DoDragDrop stops
1074 trackerInfo
->trackingDone
= TRUE
;
1077 * Release the mouse in case the drop target decides to show a popup
1078 * or a menu or something.
1083 * If we end-up over a target, drop the object in the target or
1084 * inform the target that the operation was cancelled.
1086 if (trackerInfo
->curDragTarget
!=0)
1088 switch (trackerInfo
->returnValue
)
1091 * If the source wants us to complete the operation, we tell
1092 * the drop target that we just dropped the object in it.
1094 case DRAGDROP_S_DROP
:
1096 POINTL mousePosParam
;
1099 * The documentation tells me that the coordinate should be
1100 * in the target window's coordinate space. However, the tests
1101 * I made tell me the coordinates should be in screen coordinates.
1103 mousePosParam
.x
= mousePos
.x
;
1104 mousePosParam
.y
= mousePos
.y
;
1106 IDropTarget_Drop(trackerInfo
->curDragTarget
,
1107 trackerInfo
->dataObject
,
1110 trackerInfo
->pdwEffect
);
1114 * If the source told us that we should cancel, fool the drop
1115 * target by telling it that the mouse left it's window.
1117 case DRAGDROP_S_CANCEL
:
1118 IDropTarget_DragLeave(trackerInfo
->curDragTarget
);
1126 * OLEDD_GetButtonState()
1128 * This method will use the current state of the keyboard to build
1129 * a button state mask equivalent to the one passed in the
1130 * WM_MOUSEMOVE wParam.
1132 static DWORD
OLEDD_GetButtonState()
1134 BYTE keyboardState
[256];
1137 GetKeyboardState(keyboardState
);
1139 if ( (keyboardState
[VK_SHIFT
] & 0x80) !=0)
1140 keyMask
|= MK_SHIFT
;
1142 if ( (keyboardState
[VK_CONTROL
] & 0x80) !=0)
1143 keyMask
|= MK_CONTROL
;
1145 if ( (keyboardState
[VK_LBUTTON
] & 0x80) !=0)
1146 keyMask
|= MK_LBUTTON
;
1148 if ( (keyboardState
[VK_RBUTTON
] & 0x80) !=0)
1149 keyMask
|= MK_RBUTTON
;
1151 if ( (keyboardState
[VK_MBUTTON
] & 0x80) !=0)
1152 keyMask
|= MK_MBUTTON
;