CPatch: New memory management
[TortoiseGit.git] / src / Utils / DragDropImpl.h
blob97d6768b564f1c62a9b8fdf113d11ef67b59f3f7
1 // IDataObjectImpl.h: interface for the CIDataObjectImpl class.
2 /**************************************************************************
3 THIS CODE AND INFORMATION IS PROVIDED 'AS IS' WITHOUT WARRANTY OF
4 ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
5 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
6 PARTICULAR PURPOSE.
7 Author: Leon Finker 1/2001
8 **************************************************************************/
9 #ifndef __DRAGDROPIMPL_H__
10 #define __DRAGDROPIMPL_H__
11 //#include <ShlDisp.h>
12 #include <shobjidl.h>
13 #include <shlobj.h>
15 ///////////////////////////////////////////////////////////////////////////////////////////////
16 class CDragSourceNotify : IDropSourceNotify
18 private:
19 LONG refCount;
21 public:
23 CDragSourceNotify(void)
25 refCount = 0;
28 ~CDragSourceNotify(void)
32 HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject) override
34 if(!ppvObject)
35 return E_POINTER;
37 if (IsEqualIID(riid, IID_IUnknown))
38 *ppvObject = static_cast<IUnknown*>(this);
39 else if (IsEqualIID(riid, IID_IDropSourceNotify))
40 *ppvObject = static_cast<IDropSourceNotify*>(this);
41 else
43 *ppvObject = nullptr;
44 return E_NOINTERFACE;
47 AddRef();
48 return S_OK;
51 ULONG STDMETHODCALLTYPE AddRef(void) override
53 return InterlockedIncrement(&refCount);
56 ULONG STDMETHODCALLTYPE Release(void) override
58 ULONG ret = InterlockedDecrement(&refCount);
59 if(!ret) {
60 delete this;
62 return ret;
65 HRESULT STDMETHODCALLTYPE DragEnterTarget(HWND /*hWndTarget*/) override
67 return S_OK;
70 HRESULT STDMETHODCALLTYPE DragLeaveTarget(void) override
72 return S_OK;
77 ///////////////////////////////////////////////////////////////////////////////////////////////
78 class CEnumFormatEtc : public IEnumFORMATETC
80 private:
81 ULONG m_cRefCount;
82 CSimpleArray<FORMATETC> m_pFmtEtc;
83 int m_iCur;
85 public:
86 CEnumFormatEtc(const CSimpleArray<FORMATETC>& ArrFE);
87 CEnumFormatEtc(const CSimpleArray<FORMATETC*>& ArrFE);
88 //IUnknown members
89 STDMETHOD(QueryInterface)(REFIID, void FAR* FAR*) override;
90 STDMETHOD_(ULONG, AddRef)(void) override;
91 STDMETHOD_(ULONG, Release)(void) override;
93 //IEnumFORMATETC members
94 STDMETHOD(Next)(ULONG, LPFORMATETC, ULONG FAR *) override;
95 STDMETHOD(Skip)(ULONG) override;
96 STDMETHOD(Reset)(void) override;
97 STDMETHOD(Clone)(IEnumFORMATETC FAR* FAR*) override;
100 ///////////////////////////////////////////////////////////////////////////////////////////////
101 class CIDropSource : public IDropSource
103 long m_cRefCount;
104 public:
105 bool m_bDropped;
106 IDataObject * m_pIDataObj;
107 CDragSourceNotify* pDragSourceNotify;
110 CIDropSource()
111 : m_cRefCount(0)
112 , m_bDropped(false)
113 , m_pIDataObj(nullptr)
115 pDragSourceNotify = new CDragSourceNotify();
116 pDragSourceNotify->AddRef();
118 ~CIDropSource()
120 if (m_pIDataObj)
122 m_pIDataObj->Release();
123 m_pIDataObj = nullptr;
125 if (pDragSourceNotify)
127 pDragSourceNotify->Release();
128 pDragSourceNotify = nullptr;
131 //IUnknown
132 virtual HRESULT STDMETHODCALLTYPE QueryInterface(
133 /* [in] */ REFIID riid,
134 /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject) override;
135 virtual ULONG STDMETHODCALLTYPE AddRef( void) override;
136 virtual ULONG STDMETHODCALLTYPE Release( void) override;
137 //IDropSource
138 virtual HRESULT STDMETHODCALLTYPE QueryContinueDrag(
139 /* [in] */ BOOL fEscapePressed,
140 /* [in] */ DWORD grfKeyState) override;
142 virtual HRESULT STDMETHODCALLTYPE GiveFeedback(
143 /* [in] */ DWORD dwEffect) override;
146 ///////////////////////////////////////////////////////////////////////////////////////////////
147 class CIDataObject : public IDataObject//,public IAsyncOperation
149 CIDropSource* m_pDropSource;
150 long m_cRefCount;
151 CSimpleArray<FORMATETC*> m_ArrFormatEtc;
152 CSimpleArray<STGMEDIUM*> m_StgMedium;
153 public:
154 CIDataObject(CIDropSource* pDropSource);
155 ~CIDataObject();
156 void CopyMedium(STGMEDIUM* pMedDest, STGMEDIUM* pMedSrc, FORMATETC* pFmtSrc);
157 //IUnknown
158 virtual HRESULT STDMETHODCALLTYPE QueryInterface(
159 /* [in] */ REFIID riid,
160 /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject) override;
161 virtual ULONG STDMETHODCALLTYPE AddRef( void) override;
162 virtual ULONG STDMETHODCALLTYPE Release( void) override;
164 //IDataObject
165 virtual /* [local] */ HRESULT STDMETHODCALLTYPE GetData(
166 /* [unique][in] */ FORMATETC __RPC_FAR *pformatetcIn,
167 /* [out] */ STGMEDIUM __RPC_FAR *pmedium) override;
169 virtual /* [local] */ HRESULT STDMETHODCALLTYPE GetDataHere(
170 /* [unique][in] */ FORMATETC __RPC_FAR *pformatetc,
171 /* [out][in] */ STGMEDIUM __RPC_FAR *pmedium) override;
173 virtual HRESULT STDMETHODCALLTYPE QueryGetData(
174 /* [unique][in] */ FORMATETC __RPC_FAR *pformatetc) override;
176 virtual HRESULT STDMETHODCALLTYPE GetCanonicalFormatEtc(
177 /* [unique][in] */ FORMATETC __RPC_FAR *pformatectIn,
178 /* [out] */ FORMATETC __RPC_FAR *pformatetcOut) override;
180 virtual /* [local] */ HRESULT STDMETHODCALLTYPE SetData(
181 /* [unique][in] */ FORMATETC __RPC_FAR *pformatetc,
182 /* [unique][in] */ STGMEDIUM __RPC_FAR *pmedium,
183 /* [in] */ BOOL fRelease) override;
185 virtual HRESULT STDMETHODCALLTYPE EnumFormatEtc(
186 /* [in] */ DWORD dwDirection,
187 /* [out] */ IEnumFORMATETC __RPC_FAR *__RPC_FAR *ppenumFormatEtc) override;
189 virtual HRESULT STDMETHODCALLTYPE DAdvise(
190 /* [in] */ FORMATETC __RPC_FAR *pformatetc,
191 /* [in] */ DWORD advf,
192 /* [unique][in] */ IAdviseSink __RPC_FAR *pAdvSink,
193 /* [out] */ DWORD __RPC_FAR *pdwConnection) override;
195 virtual HRESULT STDMETHODCALLTYPE DUnadvise(
196 /* [in] */ DWORD dwConnection) override;
198 virtual HRESULT STDMETHODCALLTYPE EnumDAdvise(
199 /* [out] */ IEnumSTATDATA __RPC_FAR *__RPC_FAR *ppenumAdvise) override;
201 //IAsyncOperation
202 //virtual HRESULT STDMETHODCALLTYPE SetAsyncMode(
203 // /* [in] */ BOOL fDoOpAsync)
205 // return E_NOTIMPL;
208 //virtual HRESULT STDMETHODCALLTYPE GetAsyncMode(
209 // /* [out] */ BOOL __RPC_FAR *pfIsOpAsync)
211 // return E_NOTIMPL;
214 //virtual HRESULT STDMETHODCALLTYPE StartOperation(
215 // /* [optional][unique][in] */ IBindCtx __RPC_FAR *pbcReserved)
217 // return E_NOTIMPL;
220 //virtual HRESULT STDMETHODCALLTYPE InOperation(
221 // /* [out] */ BOOL __RPC_FAR *pfInAsyncOp)
223 // return E_NOTIMPL;
226 //virtual HRESULT STDMETHODCALLTYPE EndOperation(
227 // /* [in] */ HRESULT hResult,
228 // /* [unique][in] */ IBindCtx __RPC_FAR *pbcReserved,
229 // /* [in] */ DWORD dwEffects)
231 // return E_NOTIMPL;
235 // helper function
236 HRESULT SetDropDescription(DROPIMAGETYPE image, LPCTSTR format, LPCTSTR insert);
239 ///////////////////////////////////////////////////////////////////////////////////////////////
240 class CIDropTarget : public IDropTarget
242 DWORD m_cRefCount;
243 bool m_bAllowDrop;
244 IDropTargetHelper *m_pDropTargetHelper;
245 CSimpleArray<FORMATETC> m_formatetc;
246 FORMATETC* m_pSupportedFrmt;
247 protected:
248 HWND m_hTargetWnd;
249 IDataObject * m_pIDataObject;
250 public:
252 CIDropTarget(HWND m_hTargetWnd);
253 virtual ~CIDropTarget();
254 void AddSuportedFormat(FORMATETC& ftetc) { m_formatetc.Add(ftetc); }
256 //return values: true - release the medium. false - don't release the medium
257 virtual bool OnDrop(FORMATETC* pFmtEtc, STGMEDIUM& medium,DWORD *pdwEffect, POINTL pt) = 0;
259 virtual HRESULT STDMETHODCALLTYPE QueryInterface(
260 /* [in] */ REFIID riid,
261 /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject) override;
262 virtual ULONG STDMETHODCALLTYPE AddRef( void) override { ATLTRACE("CIDropTarget::AddRef\n"); return ++m_cRefCount; }
263 virtual ULONG STDMETHODCALLTYPE Release( void) override;
265 bool QueryDrop(DWORD grfKeyState, LPDWORD pdwEffect);
266 virtual HRESULT STDMETHODCALLTYPE DragEnter(
267 /* [unique][in] */ IDataObject __RPC_FAR *pDataObj,
268 /* [in] */ DWORD grfKeyState,
269 /* [in] */ POINTL pt,
270 /* [out][in] */ DWORD __RPC_FAR *pdwEffect) override;
271 virtual HRESULT STDMETHODCALLTYPE DragOver(
272 /* [in] */ DWORD grfKeyState,
273 /* [in] */ POINTL pt,
274 /* [out][in] */ DWORD __RPC_FAR *pdwEffect) override;
275 virtual HRESULT STDMETHODCALLTYPE DragLeave( void) override;
276 virtual HRESULT STDMETHODCALLTYPE Drop(
277 /* [unique][in] */ IDataObject __RPC_FAR *pDataObj,
278 /* [in] */ DWORD grfKeyState,
279 /* [in] */ POINTL pt,
280 /* [out][in] */ DWORD __RPC_FAR *pdwEffect) override;
282 // helper function
283 HRESULT SetDropDescription(DROPIMAGETYPE image, LPCTSTR format, LPCTSTR insert);
286 class CDragSourceHelper
288 IDragSourceHelper2* pDragSourceHelper2;
289 IDragSourceHelper* pDragSourceHelper;
291 public:
292 CDragSourceHelper()
294 pDragSourceHelper = nullptr;
295 pDragSourceHelper2 = nullptr;
296 if(FAILED(CoCreateInstance(CLSID_DragDropHelper,
297 nullptr,
298 CLSCTX_INPROC_SERVER,
299 IID_IDragSourceHelper2,
300 (void**)&pDragSourceHelper2)))
302 pDragSourceHelper2 = nullptr;
303 if(FAILED(CoCreateInstance(CLSID_DragDropHelper,
304 nullptr,
305 CLSCTX_INPROC_SERVER,
306 IID_IDragSourceHelper,
307 (void**)&pDragSourceHelper)))
308 pDragSourceHelper = nullptr;
311 virtual ~CDragSourceHelper()
313 if (pDragSourceHelper2)
315 pDragSourceHelper2->Release();
316 pDragSourceHelper2 = nullptr;
318 if (pDragSourceHelper)
320 pDragSourceHelper->Release();
321 pDragSourceHelper = nullptr;
325 // IDragSourceHelper
326 HRESULT InitializeFromBitmap(HBITMAP hBitmap,
327 POINT& pt, // cursor position in client coords of the window
328 RECT& rc, // selected item's bounding rect
329 IDataObject* pDataObject,
330 BOOL allowDropDescription=TRUE,
331 COLORREF crColorKey=GetSysColor(COLOR_WINDOW)// color of the window used for transparent effect.
334 if (!pDragSourceHelper && !pDragSourceHelper2)
335 return E_FAIL;
337 if ((allowDropDescription)&&(pDragSourceHelper2))
338 pDragSourceHelper2->SetFlags(DSH_ALLOWDROPDESCRIPTIONTEXT);
340 SHDRAGIMAGE di;
341 BITMAP bm;
342 GetObject(hBitmap, sizeof(bm), &bm);
343 di.sizeDragImage.cx = bm.bmWidth;
344 di.sizeDragImage.cy = bm.bmHeight;
345 di.hbmpDragImage = hBitmap;
346 di.crColorKey = crColorKey;
347 di.ptOffset.x = pt.x - rc.left;
348 di.ptOffset.y = pt.y - rc.top;
349 if (pDragSourceHelper2)
350 return pDragSourceHelper2->InitializeFromBitmap(&di, pDataObject);
351 if (!pDragSourceHelper)
352 return E_FAIL;
353 return pDragSourceHelper->InitializeFromBitmap(&di, pDataObject);
355 HRESULT InitializeFromWindow(HWND hwnd, POINT& pt, IDataObject* pDataObject, BOOL allowDropDescription=TRUE)
357 if (!pDragSourceHelper && !pDragSourceHelper2)
358 return E_FAIL;
359 if ((allowDropDescription)&&(pDragSourceHelper2))
360 pDragSourceHelper2->SetFlags(DSH_ALLOWDROPDESCRIPTIONTEXT);
361 if (pDragSourceHelper2)
362 return pDragSourceHelper2->InitializeFromWindow(hwnd, &pt, pDataObject);
363 if (!pDragSourceHelper)
364 return E_FAIL;
365 return pDragSourceHelper->InitializeFromWindow(hwnd, &pt, pDataObject);
368 #endif //__DRAGDROPIMPL_H__