#ifndef _DROPTGT_H_ #define _DROPTGT_H_ // There are two drag-drop support objects: // // CDropTargetWrap - This object takes a collection of drop-target // objects and wraps them as one drop-target // handler. The first drop-target wins over the // the last one if there is a conflict in who // will take the drop. // // CDelegateDropTarget - This class implements IDropTarget given an // IDelegateDropTargetCB interface. It handles // all hit testing, caching, and scrolling for you. // Use this class by inheriting it in your derived // class; it is not intended to be instantiated alone. // // Event notifications for HitTestDDT #define HTDDT_ENTER 0 #define HTDDT_OVER 1 #define HTDDT_LEAVE 2 class CDelegateDropTarget : public IDropTarget { public: // *** IDropTarget methods *** virtual STDMETHODIMP DragEnter(IDataObject *pdtobj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect); virtual STDMETHODIMP DragOver(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect); virtual STDMETHODIMP DragLeave(void); virtual STDMETHODIMP Drop(IDataObject *pdtobj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect); // *** Other methods to be implemented by derived class *** virtual HRESULT GetWindowsDDT (HWND * phwndLock, HWND * phwndScroll) PURE; virtual HRESULT HitTestDDT (UINT nEvent, LPPOINT ppt, DWORD_PTR * pdwId, DWORD *pdwEffect) PURE; virtual HRESULT GetObjectDDT (DWORD_PTR dwId, REFIID riid, LPVOID * ppvObj) PURE; virtual HRESULT OnDropDDT (IDropTarget *pdt, IDataObject *pdtobj, DWORD * pgrfKeyState, POINTL pt, DWORD *pdwEffect) PURE; friend IDropTarget* DropTargetWrap_CreateInstance(IDropTarget* pdtPrimary, IDropTarget* pdtSecondary, HWND hwnd, IDropTarget* pdt3 = NULL); protected: CDelegateDropTarget(); virtual ~CDelegateDropTarget(); BOOL IsValid() { return (_hwndLock && _hwndScroll); } void SetCallback(IDelegateDropTargetCB* pdtcb); HRESULT Init(); // init lock + scroll windows friend IDropTarget* DelegateDropTarget_CreateInstance(IDelegateDropTargetCB* pdtcb); private: void _ReleaseCurrentDropTarget(); // the below are parameters we use to implement this IDropTarget HWND _hwndLock; HWND _hwndScroll; // the object we are dragging LPDATAOBJECT _pDataObj; // from DragEnter()/Drop() // the below indicate the current drag state BITBOOL _fPrime:1; // TRUE iff _itemOver/_grfKeyState is valid DWORD_PTR _itemOver; // item we are visually dragging over IDropTarget* _pdtCur; // drop target for _itemOver DWORD _grfKeyState; // cached key state DWORD _dwEffectOut; // last *pdwEffect out POINT _ptLast; // last dragged position // for scrolling RECT _rcLockWindow; // WindowRect of hwnd for DAD_ENTER AUTO_SCROLL_DATA _asd; // for auto scrolling } ; // dummy drop target to only call DAD_DragEnterEx() on DragEnter(); class CDropDummy : public IDropTarget { public: // *** IUnknown *** virtual STDMETHODIMP_(ULONG) AddRef(void); virtual STDMETHODIMP_(ULONG) Release(void); virtual STDMETHODIMP QueryInterface(REFIID riid, LPVOID * ppvObj); // *** IDropTarget methods *** virtual STDMETHODIMP DragEnter(IDataObject *pdtobj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect); virtual STDMETHODIMP DragOver(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect); virtual STDMETHODIMP DragLeave(void) { DAD_DragLeave(); return(S_OK); }; virtual STDMETHODIMP Drop(IDataObject *pdtobj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect) { DragLeave(); return(S_OK); }; CDropDummy(HWND hwndLock) : _hwndLock(hwndLock), _cRef(1) { return; }; protected: ~CDropDummy() { return; }; private: HWND _hwndLock; // window for dummy drop target. int _cRef; }; #endif // _DROPTGT_H_