2 * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
9 #include "ecore_win32_dnd_drop_target.h"
11 #include "ecore_win32_private.h"
16 DropTarget::DropTarget(HWND window, Ecore_Win32_Dnd_DropTarget_Callback callback, void *window_obj_ptr)
20 , drop_callback_(callback)
21 ,drop_callback_ptr_(window_obj_ptr)
27 HRESULT DropTarget::QueryInterface(REFIID iid, void **ppvObject)
29 // check to see what interface has been requested
30 if (iid == IID_IDropTarget || iid == IID_IUnknown)
41 ULONG DropTarget::AddRef()
43 return InterlockedIncrement(&ref_count_);
46 ULONG DropTarget::Release()
48 LONG count = InterlockedDecrement(&ref_count_);
61 HRESULT DropTarget::DragEnter(IDataObject *pDataObject, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
63 // does the dataobject contain data we want?
64 allow_drop_ = QueryDataObject(pDataObject) &&
65 (drop_callback_ == NULL ||
66 (drop_callback_(drop_callback_ptr_, ECORE_WIN32_DND_EVENT_DRAG_ENTER, pt.x, pt.y, NULL, 0) != 0));
70 // get the dropeffect based on keyboard state
71 *pdwEffect = DropEffect(grfKeyState, pt, *pdwEffect);
73 //PositionCursor(_hwnd, pt);
76 *pdwEffect = DROPEFFECT_NONE;
80 HRESULT DropTarget::DragOver(DWORD grfKeyState, POINTL pt, DWORD * pdwEffect)
83 (drop_callback_ == NULL) ||
84 (drop_callback_(drop_callback_ptr_, ECORE_WIN32_DND_EVENT_DRAG_OVER, pt.x, pt.y, NULL, 0) != 0);
88 *pdwEffect = DropEffect(grfKeyState, pt, *pdwEffect);
89 //PositionCursor(m_hWnd, pt);
93 *pdwEffect = DROPEFFECT_NONE;
99 HRESULT DropTarget::DragLeave()
104 if (drop_callback_ != NULL)
105 drop_callback_(drop_callback_ptr_, ECORE_WIN32_DND_EVENT_DRAG_LEAVE, pt.x, pt.y, NULL, 0);
110 HRESULT DropTarget::Drop(IDataObject *pDataObject, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
114 // construct a FORMATETC object
115 FORMATETC fmtetc = { CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
118 // See if the dataobject contains any TEXT stored as a HGLOBAL
119 if (pDataObject->QueryGetData(&fmtetc) == S_OK)
121 // Yippie! the data is there, so go get it!
122 if (pDataObject->GetData(&fmtetc, &stgmed) == S_OK)
124 // we asked for the data as a HGLOBAL, so access it appropriately
125 PVOID data = GlobalLock(stgmed.hGlobal);
126 UINT size = GlobalSize(stgmed.hGlobal);
128 if (drop_callback_ != NULL)
130 drop_callback_(drop_callback_ptr_,
131 ECORE_WIN32_DND_EVENT_DROP,
136 GlobalUnlock(stgmed.hGlobal);
138 // release the data using the COM API
139 ReleaseStgMedium(&stgmed);
142 *pdwEffect = DropEffect(grfKeyState, pt, *pdwEffect);
146 *pdwEffect = DROPEFFECT_NONE;
153 // internal helper function
155 DWORD DropTarget::DropEffect(DWORD grfKeyState, POINTL pt __UNUSED__, DWORD dwAllowed)
159 // 1. check "pt" -> do we allow a drop at the specified coordinates?
161 // 2. work out that the drop-effect should be based on grfKeyState
162 if (grfKeyState & MK_CONTROL)
164 dwEffect = dwAllowed & DROPEFFECT_COPY;
166 else if (grfKeyState & MK_SHIFT)
168 dwEffect = dwAllowed & DROPEFFECT_MOVE;
171 // 3. no key-modifiers were specified (or drop effect not allowed), so
172 // base the effect on those allowed by the dropsource
175 if (dwAllowed & DROPEFFECT_COPY) dwEffect = DROPEFFECT_COPY;
176 if (dwAllowed & DROPEFFECT_MOVE) dwEffect = DROPEFFECT_MOVE;
182 bool DropTarget::QueryDataObject(IDataObject *pDataObject)
184 FORMATETC fmtetc = { CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
186 // does the data object support CF_TEXT using a HGLOBAL?
187 return pDataObject->QueryGetData(&fmtetc) == S_OK;
191 // ecore_win32 private functions
193 void *_ecore_win32_dnd_register_drop_window(HWND hwnd, Ecore_Win32_Dnd_DropTarget_Callback callback, void *ptr)
195 DropTarget *pDropTarget = new DropTarget(hwnd, callback, ptr);
197 if (pDropTarget == NULL)
200 // acquire a strong lock
201 if (FAILED(CoLockObjectExternal(pDropTarget, TRUE, FALSE)))
207 // tell OLE that the window is a drop target
208 if (FAILED(RegisterDragDrop(hwnd, pDropTarget)))
217 void _ecore_win32_dnd_unregister_drop_window(HWND hwnd, void *drop_target)
219 IDropTarget *pDropTarget = (IDropTarget *)drop_target;
221 if (drop_target == NULL)
225 RevokeDragDrop(hwnd);
227 // remove the strong lock
228 CoLockObjectExternal(pDropTarget, FALSE, TRUE);
230 // release our own reference
231 pDropTarget->Release();