ReactOS 0.4.15-dev-7924-g5949c20
dragdropimpl.cpp
Go to the documentation of this file.
1#include <precomp.h>
2
3/**************************************************************************
4 THIS CODE AND INFORMATION IS PROVIDED 'AS IS' WITHOUT WARRANTY OF
5 ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
6 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
7 PARTICULAR PURPOSE.
8 Author: Leon Finker 11/2000
9 Modifications: replaced ATL by STL, Martin Fuchs 7/2003
10**************************************************************************/
11
12// dragdropimp.cpp: implementation of the IDataObjectImpl class.
14
15//#include <shlobj.h>
16//#include <assert.h>
17
18//#include "dragdropimpl.h"
19
21// IDataObjectImpl Class
23
26 m_pDropSource(pDropSource),
27 m_cRefCount(0)
28{
29}
30
32{
33 for(StorageArray::iterator it=_storage.begin(); it!=_storage.end(); ++it)
34 ReleaseStgMedium(it->_medium);
35}
36
38 /* [unique][in] */ FORMATETC __RPC_FAR *pformatetcIn,
39 /* [out] */ STGMEDIUM __RPC_FAR *pmedium)
40{
41 if (pformatetcIn == NULL || pmedium == NULL)
42 return E_INVALIDARG;
43
44 pmedium->hGlobal = NULL;
45
46 for(StorageArray::iterator it=_storage.begin(); it!=_storage.end(); ++it)
47 {
48 if (pformatetcIn->tymed & it->_format->tymed &&
49 pformatetcIn->dwAspect == it->_format->dwAspect &&
50 pformatetcIn->cfFormat == it->_format->cfFormat)
51 {
52 CopyMedium(pmedium, it->_medium, it->_format);
53 return S_OK;
54 }
55 }
56
57 return DV_E_FORMATETC;
58}
59
61 /* [unique][in] */ FORMATETC __RPC_FAR *pformatetc,
62 /* [out][in] */ STGMEDIUM __RPC_FAR *pmedium)
63{
64 return E_NOTIMPL;
65}
66
68 /* [unique][in] */ FORMATETC __RPC_FAR *pformatetc)
69{
70 if (pformatetc == NULL)
71 return E_INVALIDARG;
72
73 //support others if needed DVASPECT_THUMBNAIL //DVASPECT_ICON //DVASPECT_DOCPRINT
74 if (!(DVASPECT_CONTENT & pformatetc->dwAspect))
75 return (DV_E_DVASPECT);
76
78
79 for(StorageArray::iterator it=_storage.begin(); it!=_storage.end(); ++it)
80 {
81 if (pformatetc->tymed & it->_format->tymed)
82 {
83 if (pformatetc->cfFormat == it->_format->cfFormat)
84 return S_OK;
85 else
87 }
88 else
89 hr = DV_E_TYMED;
90 }
91
92 return hr;
93}
94
96 /* [unique][in] */ FORMATETC __RPC_FAR *pformatectIn,
97 /* [out] */ FORMATETC __RPC_FAR *pformatetcOut)
98{
99 if (pformatetcOut == NULL)
100 return E_INVALIDARG;
101
103}
104
106 /* [unique][in] */ FORMATETC __RPC_FAR *pformatetc,
107 /* [unique][in] */ STGMEDIUM __RPC_FAR *pmedium,
108 /* [in] */ BOOL fRelease)
109{
110 if (pformatetc == NULL || pmedium == NULL)
111 return E_INVALIDARG;
112
113 assert(pformatetc->tymed == pmedium->tymed);
114 FORMATETC* fetc=new FORMATETC;
115 STGMEDIUM* pStgMed = new STGMEDIUM;
116
117 if (fetc == NULL || pStgMed == NULL)
118 return E_OUTOFMEMORY;
119
120 ZeroMemory(fetc, sizeof(FORMATETC));
121 ZeroMemory(pStgMed, sizeof(STGMEDIUM));
122
123 *fetc = *pformatetc;
124
125 if (fRelease)
126 *pStgMed = *pmedium;
127 else
128 CopyMedium(pStgMed, pmedium, pformatetc);
129
130 DataStorage storage;
131
132 storage._format = fetc;
133 storage._medium = pStgMed;
134
135 _storage.push_back(storage);
136
137 return S_OK;
138}
139
140void IDataObjectImpl::CopyMedium(STGMEDIUM* pMedDest, STGMEDIUM* pMedSrc, FORMATETC* pFmtSrc)
141{
142 switch(pMedSrc->tymed)
143 {
144 case TYMED_HGLOBAL:
145 pMedDest->hGlobal = (HGLOBAL)OleDuplicateData(pMedSrc->hGlobal, pFmtSrc->cfFormat, 0);
146 break;
147 case TYMED_GDI:
148 pMedDest->hBitmap = (HBITMAP)OleDuplicateData(pMedSrc->hBitmap, pFmtSrc->cfFormat, 0);
149 break;
150 case TYMED_MFPICT:
151 pMedDest->hMetaFilePict = (HMETAFILEPICT)OleDuplicateData(pMedSrc->hMetaFilePict, pFmtSrc->cfFormat, 0);
152 break;
153 case TYMED_ENHMF:
154 pMedDest->hEnhMetaFile = (HENHMETAFILE)OleDuplicateData(pMedSrc->hEnhMetaFile, pFmtSrc->cfFormat, 0);
155 break;
156 case TYMED_FILE:
157 pMedDest->lpszFileName = (LPOLESTR)OleDuplicateData(pMedSrc->lpszFileName, pFmtSrc->cfFormat, 0);
158 break;
159 case TYMED_ISTREAM:
160 pMedDest->pstm = pMedSrc->pstm;
161 pMedSrc->pstm->AddRef();
162 break;
163 case TYMED_ISTORAGE:
164 pMedDest->pstg = pMedSrc->pstg;
165 pMedSrc->pstg->AddRef();
166 break;
167 case TYMED_NULL:
168 default:
169 break;
170 }
171 pMedDest->tymed = pMedSrc->tymed;
172 pMedDest->pUnkForRelease = pMedSrc->pUnkForRelease;
173}
174
176 /* [in] */ DWORD dwDirection,
177 /* [out] */ IEnumFORMATETC __RPC_FAR *__RPC_FAR *ppenumFormatEtc)
178{
179 if (ppenumFormatEtc == NULL)
180 return E_POINTER;
181
182 *ppenumFormatEtc=NULL;
183 switch (dwDirection)
184 {
185 case DATADIR_GET:
186 *ppenumFormatEtc = new EnumFormatEtcImpl(_storage);
187
188 if (!*ppenumFormatEtc)
189 return E_OUTOFMEMORY;
190
191 (*ppenumFormatEtc)->AddRef();
192 break;
193
194 case DATADIR_SET:
195 default:
196 return E_NOTIMPL;
197 break;
198 }
199
200 return S_OK;
201}
202
204 /* [in] */ FORMATETC __RPC_FAR *pformatetc,
205 /* [in] */ DWORD advf,
206 /* [unique][in] */ IAdviseSink __RPC_FAR *pAdvSink,
207 /* [out] */ DWORD __RPC_FAR *pdwConnection)
208{
210}
211
213 /* [in] */ DWORD dwConnection)
214{
215 return E_NOTIMPL;
216}
217
219 /* [out] */ IEnumSTATDATA __RPC_FAR *__RPC_FAR *ppenumAdvise)
220{
222}
223
225// IDropSourceImpl Class
227
229 /* [in] */ BOOL fEscapePressed,
230 /* [in] */ DWORD grfKeyState)
231{
232 if (fEscapePressed)
233 return DRAGDROP_S_CANCEL;
234 if (!(grfKeyState & (MK_LBUTTON|MK_RBUTTON)))
235 {
236 m_bDropped = true;
237 return DRAGDROP_S_DROP;
238 }
239
240 return S_OK;
241
242}
243
245 /* [in] */ DWORD dwEffect)
246{
248}
249
251// EnumFormatEtcImpl Class
253
256 m_cRefCount(0),
257 m_iCur(0)
258{
259 for(FormatArray::const_iterator it=ArrFE.begin(); it!=ArrFE.end(); ++it)
260 m_pFmtEtc.push_back(*it);
261}
262
265 m_cRefCount(0),
266 m_iCur(0)
267{
268 for(StorageArray::const_iterator it=ArrFE.begin(); it!=ArrFE.end(); ++it)
269 m_pFmtEtc.push_back(*it->_format);
270}
271
272STDMETHODIMP EnumFormatEtcImpl::Next(ULONG celt,LPFORMATETC lpFormatEtc, ULONG* pceltFetched)
273{
274 if (pceltFetched != NULL)
275 *pceltFetched=0;
276
277 ULONG cReturn = celt;
278
279 if (celt <= 0 || lpFormatEtc == NULL || m_iCur >= m_pFmtEtc.size())
280 return S_FALSE;
281
282 if (pceltFetched == NULL && celt != 1) // pceltFetched can be NULL only for 1 item request
283 return S_FALSE;
284
285 while (m_iCur < m_pFmtEtc.size() && cReturn > 0)
286 {
287 *lpFormatEtc++ = m_pFmtEtc[m_iCur++];
288 --cReturn;
289 }
290 if (pceltFetched != NULL)
291 *pceltFetched = celt - cReturn;
292
293 return (cReturn == 0) ? S_OK : S_FALSE;
294}
295
297{
298 if ((m_iCur + int(celt)) >= m_pFmtEtc.size())
299 return S_FALSE;
300
301 m_iCur += celt;
302 return S_OK;
303}
304
306{
307 m_iCur = 0;
308 return S_OK;
309}
310
312{
313 if (ppCloneEnumFormatEtc == NULL)
314 return E_POINTER;
315
317
318 if (!newEnum)
319 return E_OUTOFMEMORY;
320
321 newEnum->AddRef();
322 newEnum->m_iCur = m_iCur;
323 *ppCloneEnumFormatEtc = newEnum;
324
325 return S_OK;
326}
327
329// IDropTargetImpl Class
332 : m_cRefCount(0),
333 m_bAllowDrop(false),
334 m_pDropTargetHelper(NULL),
335 m_pSupportedFrmt(NULL),
336 m_hTargetWnd(hTargetWnd)
337{
339
340 if (FAILED(CoCreateInstance(CLSID_DragDropHelper, NULL, CLSCTX_INPROC_SERVER,
341 IID_IDropTargetHelper,(LPVOID*)&m_pDropTargetHelper)))
343}
344
346{
348 {
351 }
352}
353
355 /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject)
356{
357 *ppvObject = NULL;
358 if (IID_IUnknown==riid || IID_IDropTarget==riid)
359 *ppvObject=this;
360
361 if (*ppvObject != NULL)
362 {
364 return S_OK;
365 }
366
367 return E_NOINTERFACE;
368}
369
371{
372 long nTemp = --m_cRefCount;
373
374 assert(nTemp >= 0);
375
376 if (nTemp == 0)
377 delete this;
378
379 return nTemp;
380}
381
382bool IDropTargetImpl::QueryDrop(DWORD grfKeyState, LPDWORD pdwEffect)
383{
384 DWORD dwOKEffects = *pdwEffect;
385
386 if (!m_bAllowDrop)
387 {
388 *pdwEffect = DROPEFFECT_NONE;
389 return false;
390 }
391
392 //CTRL+SHIFT -- DROPEFFECT_LINK
393 //CTRL -- DROPEFFECT_COPY
394 //SHIFT -- DROPEFFECT_MOVE
395 //no modifier -- DROPEFFECT_MOVE or whatever is allowed by src
396 *pdwEffect = (grfKeyState & MK_CONTROL) ?
397 ( (grfKeyState & MK_SHIFT) ? DROPEFFECT_LINK : DROPEFFECT_COPY ):
398 ( (grfKeyState & MK_SHIFT) ? DROPEFFECT_MOVE : DROPEFFECT_NONE );
399 if (*pdwEffect == 0)
400 {
401 // No modifier keys used by user while dragging.
402 if (DROPEFFECT_COPY & dwOKEffects)
403 *pdwEffect = DROPEFFECT_COPY;
404 else if (DROPEFFECT_MOVE & dwOKEffects)
405 *pdwEffect = DROPEFFECT_MOVE;
406 else if (DROPEFFECT_LINK & dwOKEffects)
407 *pdwEffect = DROPEFFECT_LINK;
408 else
409 {
410 *pdwEffect = DROPEFFECT_NONE;
411 }
412 }
413 else
414 {
415 // Check if the drag source application allows the drop effect desired by user.
416 // The drag source specifies this in DoDragDrop
417 if (!(*pdwEffect & dwOKEffects))
418 *pdwEffect = DROPEFFECT_NONE;
419 }
420
421 return (DROPEFFECT_NONE == *pdwEffect)?false:true;
422}
423
425 /* [unique][in] */ IDataObject __RPC_FAR *pDataObj,
426 /* [in] */ DWORD grfKeyState,
427 /* [in] */ POINTL pt,
428 /* [out][in] */ DWORD __RPC_FAR *pdwEffect)
429{
430 if (pDataObj == NULL)
431 return E_INVALIDARG;
432
434 m_pDropTargetHelper->DragEnter(m_hTargetWnd, pDataObj, (LPPOINT)&pt, *pdwEffect);
435
436 //IEnumFORMATETC* pEnum;
437 //pDataObj->EnumFormatEtc(DATADIR_GET,&pEnum);
438 //FORMATETC ftm;
439 //for()
440 //pEnum->Next(1,&ftm,0);
441 //pEnum->Release();
443
445 {
446 m_bAllowDrop = (pDataObj->QueryGetData(&*it) == S_OK)? true: false;
447
448 if (m_bAllowDrop)
449 {
450 m_pSupportedFrmt = &*it;
451 break;
452 }
453 }
454
455 QueryDrop(grfKeyState, pdwEffect);
456
457 return S_OK;
458}
459
461 /* [in] */ DWORD grfKeyState,
462 /* [in] */ POINTL pt,
463 /* [out][in] */ DWORD __RPC_FAR *pdwEffect)
464{
466 m_pDropTargetHelper->DragOver((LPPOINT)&pt, *pdwEffect);
467
468 QueryDrop(grfKeyState, pdwEffect);
469
470 return S_OK;
471}
472
474{
477
478 m_bAllowDrop = false;
480
481 return S_OK;
482}
483
485 /* [unique][in] */ IDataObject __RPC_FAR *pDataObj,
486 /* [in] */ DWORD grfKeyState, /* [in] */ POINTL pt,
487 /* [out][in] */ DWORD __RPC_FAR *pdwEffect)
488{
489 if (pDataObj == NULL)
490 return E_INVALIDARG;
491
493 m_pDropTargetHelper->Drop(pDataObj, (LPPOINT)&pt, *pdwEffect);
494
495 if (QueryDrop(grfKeyState, pdwEffect))
496 {
498 {
499 STGMEDIUM medium;
500
501 if (pDataObj->GetData(m_pSupportedFrmt, &medium) == S_OK)
502 {
503 if (OnDrop(m_pSupportedFrmt, medium, pdwEffect)) //does derive class wants us to free medium?
504 ReleaseStgMedium(&medium);
505 }
506 }
507 }
508
509 m_bAllowDrop = false;
510 *pdwEffect = DROPEFFECT_NONE;
512
513 return S_OK;
514}
#define STDMETHODIMP
Definition: basetyps.h:43
const GUID IID_IUnknown
#define STDMETHODCALLTYPE
Definition: bdasup.h:9
implementation of IEnumFORMATETC interface
Definition: dragdropimpl.h:29
FormatArray m_pFmtEtc
Definition: dragdropimpl.h:34
virtual HRESULT STDMETHODCALLTYPE Skip(ULONG)
virtual HRESULT STDMETHODCALLTYPE Clone(IEnumFORMATETC **)
EnumFormatEtcImpl(const FormatArray &ArrFE)
virtual HRESULT STDMETHODCALLTYPE Next(ULONG, LPFORMATETC, ULONG *)
virtual HRESULT STDMETHODCALLTYPE Reset(void)
virtual HRESULT STDMETHODCALLTYPE SetData(FORMATETC __RPC_FAR *pformatetc, STGMEDIUM __RPC_FAR *pmedium, BOOL fRelease)
virtual HRESULT STDMETHODCALLTYPE EnumFormatEtc(DWORD dwDirection, IEnumFORMATETC __RPC_FAR *__RPC_FAR *ppenumFormatEtc)
virtual HRESULT STDMETHODCALLTYPE QueryGetData(FORMATETC __RPC_FAR *pformatetc)
virtual HRESULT STDMETHODCALLTYPE GetDataHere(FORMATETC __RPC_FAR *pformatetc, STGMEDIUM __RPC_FAR *pmedium)
virtual HRESULT STDMETHODCALLTYPE GetCanonicalFormatEtc(FORMATETC __RPC_FAR *pformatectIn, FORMATETC __RPC_FAR *pformatetcOut)
virtual HRESULT STDMETHODCALLTYPE GetData(FORMATETC __RPC_FAR *pformatetcIn, STGMEDIUM __RPC_FAR *pmedium)
StorageArray _storage
Definition: dragdropimpl.h:88
IDataObjectImpl(IDropSourceImpl *pDropSource)
void CopyMedium(STGMEDIUM *pMedDest, STGMEDIUM *pMedSrc, FORMATETC *pFmtSrc)
virtual HRESULT STDMETHODCALLTYPE DAdvise(FORMATETC __RPC_FAR *pformatetc, DWORD advf, IAdviseSink __RPC_FAR *pAdvSink, DWORD __RPC_FAR *pdwConnection)
virtual HRESULT STDMETHODCALLTYPE EnumDAdvise(IEnumSTATDATA __RPC_FAR *__RPC_FAR *ppenumAdvise)
virtual ~IDataObjectImpl()
virtual HRESULT STDMETHODCALLTYPE DUnadvise(DWORD dwConnection)
implementation of IDropSource interface
Definition: dragdropimpl.h:52
virtual HRESULT STDMETHODCALLTYPE GiveFeedback(DWORD dwEffect)
virtual HRESULT STDMETHODCALLTYPE QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState)
virtual HRESULT STDMETHODCALLTYPE DragEnter(IDataObject __RPC_FAR *pDataObj, DWORD grfKeyState, POINTL pt, DWORD __RPC_FAR *pdwEffect)
bool QueryDrop(DWORD grfKeyState, LPDWORD pdwEffect)
virtual HRESULT STDMETHODCALLTYPE Drop(IDataObject __RPC_FAR *pDataObj, DWORD grfKeyState, POINTL pt, DWORD __RPC_FAR *pdwEffect)
IDropTargetHelper * m_pDropTargetHelper
Definition: dragdropimpl.h:172
virtual HRESULT STDMETHODCALLTYPE DragLeave()
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void __RPC_FAR *__RPC_FAR *ppvObject)
virtual bool OnDrop(FORMATETC *pFmtEtc, STGMEDIUM &medium, DWORD *pdwEffect)=0
IDropTargetImpl(HWND m_hTargetWnd)
virtual ~IDropTargetImpl()
FORMATETC * m_pSupportedFrmt
Definition: dragdropimpl.h:175
FormatArray m_formatetc
Definition: dragdropimpl.h:174
virtual ULONG STDMETHODCALLTYPE Release()
virtual HRESULT STDMETHODCALLTYPE DragOver(DWORD grfKeyState, POINTL pt, DWORD __RPC_FAR *pdwEffect)
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
#define NULL
Definition: types.h:112
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3325
void WINAPI ReleaseStgMedium(STGMEDIUM *pmedium)
Definition: ole2.c:2033
#define assert(x)
Definition: debug.h:53
#define pt(x, y)
Definition: drawing.c:79
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
REFIID riid
Definition: atlbase.h:39
HRESULT Drop([in] IDataObject *pDataObject, [in] POINT *ppt, [in] DWORD dwEffect)
HRESULT DragLeave()
HRESULT DragOver([in] POINT *ppt, [in] DWORD dwEffect)
HRESULT DragEnter([in] HWND hwndTarget, [in] IDataObject *pDataObject, [in] POINT *ppt, [in] DWORD dwEffect)
const DWORD DROPEFFECT_NONE
Definition: oleidl.idl:929
const DWORD DROPEFFECT_LINK
Definition: oleidl.idl:932
const DWORD DROPEFFECT_COPY
Definition: oleidl.idl:930
const DWORD DROPEFFECT_MOVE
Definition: oleidl.idl:931
IUnknown * LPUNKNOWN
Definition: unknwn.idl:40
ULONG Release()
nsrefcnt AddRef()
#define S_OK
Definition: intsafe.h:52
#define FAILED(hr)
Definition: intsafe.h:51
static HBITMAP
Definition: button.c:44
static LPOLESTR
Definition: stg_prop.c:27
HANDLE WINAPI OleDuplicateData(HANDLE hSrc, CLIPFORMAT cfFormat, UINT uiFlags)
Definition: ole2impl.c:425
#define HGLOBAL
Definition: ole.h:15
const GUID IID_IEnumFORMATETC
const GUID IID_IDataObject
#define REFIID
Definition: guiddef.h:118
#define __RPC_FAR
Definition: rpc.h:56
HRESULT hr
Definition: shlfolder.c:183
#define false
Definition: stdbool.h:37
structure containing information for one format of EnumFormatEtcImpl
Definition: dragdropimpl.h:18
FORMATETC * _format
Definition: dragdropimpl.h:19
STGMEDIUM * _medium
Definition: dragdropimpl.h:20
iterator end()
Definition: _vector.h:184
void push_back(const _Tp &__x=_STLP_DEFAULT_CONSTRUCTED(_Tp))
Definition: _vector.h:379
iterator begin()
Definition: _vector.h:182
const value_type * const_iterator
Definition: _vector.h:125
size_type size() const
Definition: _vector.h:192
value_type * iterator
Definition: _vector.h:124
uint32_t * LPDWORD
Definition: typedefs.h:59
uint32_t ULONG
Definition: typedefs.h:59
#define ZeroMemory
Definition: winbase.h:1712
_In_ void _In_ PCCERT_CONTEXT _In_opt_ LPFILETIME _In_ DWORD _In_ DWORD _Outptr_opt_ void ** ppvObject
Definition: wincrypt.h:6082
#define S_FALSE
Definition: winerror.h:2357
#define DRAGDROP_S_USEDEFAULTCURSORS
Definition: winerror.h:2648
#define DRAGDROP_S_DROP
Definition: winerror.h:2646
#define E_NOINTERFACE
Definition: winerror.h:2364
#define DV_E_TYMED
Definition: winerror.h:2638
#define DRAGDROP_S_CANCEL
Definition: winerror.h:2647
#define DV_E_CLIPFORMAT
Definition: winerror.h:2639
#define DV_E_FORMATETC
Definition: winerror.h:2633
#define OLE_E_ADVISENOTSUPPORTED
Definition: winerror.h:2617
#define E_POINTER
Definition: winerror.h:2365
#define DV_E_DVASPECT
Definition: winerror.h:2640
#define DATA_S_SAMEFORMATETC
Definition: winerror.h:2674
#define MK_RBUTTON
Definition: winuser.h:2368
#define MK_SHIFT
Definition: winuser.h:2369
#define MK_CONTROL
Definition: winuser.h:2370
#define MK_LBUTTON
Definition: winuser.h:2367