// Classic Shell (c) 2009-2017, Ivo Beltchev // Open-Shell (c) 2017-2018, The Open-Shell Team // Confidential information of Ivo Beltchev. Not for disclosure or distribution without prior written consent from the author #pragma once // CDropTargetProxy - a wrapper for another object's IDropTarget. On Windows 8.1 the interface is not properly released // when the window is destroyed during a drag operation. So the wrapper is used as a decoy to minimize the leaked resources class CDropTargetProxy: public IDropTarget { public: CDropTargetProxy( IDropTarget *pOwner ) { m_pOwner=pOwner; m_RefCount=0; } ~CDropTargetProxy( void ) = default; void Reset( void ) { m_pOwner=NULL; } // IUnknown virtual STDMETHODIMP QueryInterface( REFIID riid, void **ppvObject ) { *ppvObject=NULL; if (IID_IUnknown==riid || IID_IDropTarget==riid) { AddRef(); *ppvObject=static_cast(this); return S_OK; } return E_NOINTERFACE; } virtual ULONG STDMETHODCALLTYPE AddRef( void ) { return InterlockedIncrement(&m_RefCount); } virtual ULONG STDMETHODCALLTYPE Release( void ) { long nTemp=InterlockedDecrement(&m_RefCount); if (!nTemp) delete this; return nTemp; } // IDropTarget virtual HRESULT STDMETHODCALLTYPE DragEnter( IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect ); virtual HRESULT STDMETHODCALLTYPE DragOver( DWORD grfKeyState, POINTL pt, DWORD *pdwEffect ); virtual HRESULT STDMETHODCALLTYPE DragLeave( void ); virtual HRESULT STDMETHODCALLTYPE Drop( IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect ); private: IDropTarget *m_pOwner; LONG m_RefCount; };