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	11/2000
8    Modifications: replaced ATL by STL, Martin Fuchs 7/2003
9 **************************************************************************/
10 
11 #include <vector>
12 using std::vector;
13 
14 
15 typedef vector<FORMATETC> FormatArray;
16 
17  /// structure containing information for one format of EnumFormatEtcImpl
18 struct DataStorage {
19 	FORMATETC*	_format;
20 	STGMEDIUM*	_medium;
21 };
22 
23 typedef vector<DataStorage> StorageArray;
24 
25 
26  /// implementation of IEnumFORMATETC interface
27 class EnumFormatEtcImpl
28  :	public IComSrvBase<IEnumFORMATETC, EnumFormatEtcImpl>, public SimpleComObject
29 {
30 	typedef IComSrvBase<IEnumFORMATETC, EnumFormatEtcImpl> super;
31 
32 private:
33 	 ULONG			m_cRefCount;
34 	 FormatArray	m_pFmtEtc;
35 	 size_t 		m_iCur;
36 
37 public:
38 	 EnumFormatEtcImpl(const FormatArray& ArrFE);
39 	 EnumFormatEtcImpl(const StorageArray& ArrFE);
40 	 virtual ~EnumFormatEtcImpl() {}
41 
42 	 //IEnumFORMATETC members
43 	 virtual HRESULT STDMETHODCALLTYPE Next(ULONG, LPFORMATETC, ULONG*);
44 	 virtual HRESULT STDMETHODCALLTYPE Skip(ULONG);
45 	 virtual HRESULT STDMETHODCALLTYPE Reset(void);
46 	 virtual HRESULT STDMETHODCALLTYPE Clone(IEnumFORMATETC**);
47 };
48 
49  /// implementation of IDropSource interface
50 class IDropSourceImpl
51  :	public IComSrvBase<IDropSource, IDropSourceImpl>, public SimpleComObject
52 {
53 	typedef IComSrvBase<IDropSource, IDropSourceImpl> super;
54 
55 	long m_cRefCount;
56 
57 public:
58 	bool m_bDropped;
59 
60 	IDropSourceImpl()
61 	 :	super(IID_IDropSource),
62 		m_cRefCount(0),
63 		m_bDropped(false)
64 	{
65 	}
66 
67 	virtual ~IDropSourceImpl() {}
68 
69 	//IDropSource
70 	virtual HRESULT STDMETHODCALLTYPE QueryContinueDrag(
71 		/* [in] */ BOOL fEscapePressed,
72 		/* [in] */ DWORD grfKeyState);
73 
74 	virtual HRESULT STDMETHODCALLTYPE GiveFeedback(
75 		/* [in] */ DWORD dwEffect);
76 };
77 
78  /// implementation of IDataObject interface
79 class IDataObjectImpl
80  :	public IComSrvBase<IDataObject, IDataObjectImpl>, public SimpleComObject
81 	//public IAsyncOperation
82 {
83 	typedef IComSrvBase<IDataObject, IDataObjectImpl> super;
84 
85 	IDropSourceImpl* m_pDropSource;
86 	long m_cRefCount;
87 
88 	StorageArray	_storage;
89 
90 public:
91 	IDataObjectImpl(IDropSourceImpl* pDropSource);
92 	virtual ~IDataObjectImpl();
93 
94 	void CopyMedium(STGMEDIUM* pMedDest, STGMEDIUM* pMedSrc, FORMATETC* pFmtSrc);
95 
96 	//IDataObject
97 	virtual /* [local] */ HRESULT STDMETHODCALLTYPE GetData(
98 		/* [unique][in] */ FORMATETC __RPC_FAR *pformatetcIn,
99 		/* [out] */ STGMEDIUM __RPC_FAR *pmedium);
100 
101 	virtual /* [local] */ HRESULT STDMETHODCALLTYPE GetDataHere(
102 		/* [unique][in] */ FORMATETC __RPC_FAR *pformatetc,
103 		/* [out][in] */ STGMEDIUM __RPC_FAR *pmedium);
104 
105 	virtual HRESULT STDMETHODCALLTYPE QueryGetData(
106 		/* [unique][in] */ FORMATETC __RPC_FAR *pformatetc);
107 
108 	virtual HRESULT STDMETHODCALLTYPE GetCanonicalFormatEtc(
109 		/* [unique][in] */ FORMATETC __RPC_FAR *pformatectIn,
110 		/* [out] */ FORMATETC __RPC_FAR *pformatetcOut);
111 
112 	virtual /* [local] */ HRESULT STDMETHODCALLTYPE SetData(
113 		/* [unique][in] */ FORMATETC __RPC_FAR *pformatetc,
114 		/* [unique][in] */ STGMEDIUM __RPC_FAR *pmedium,
115 		/* [in] */ BOOL fRelease);
116 
117 	virtual HRESULT STDMETHODCALLTYPE EnumFormatEtc(
118 		/* [in] */ DWORD dwDirection,
119 		/* [out] */ IEnumFORMATETC __RPC_FAR *__RPC_FAR *ppenumFormatEtc);
120 
121 	virtual HRESULT STDMETHODCALLTYPE DAdvise(
122 		/* [in] */ FORMATETC __RPC_FAR *pformatetc,
123 		/* [in] */ DWORD advf,
124 		/* [unique][in] */ IAdviseSink __RPC_FAR *pAdvSink,
125 		/* [out] */ DWORD __RPC_FAR *pdwConnection);
126 
127 	virtual HRESULT STDMETHODCALLTYPE DUnadvise(
128 		/* [in] */ DWORD dwConnection);
129 
130 	virtual HRESULT STDMETHODCALLTYPE EnumDAdvise(
131 		/* [out] */ IEnumSTATDATA __RPC_FAR *__RPC_FAR *ppenumAdvise);
132 
133 	//IAsyncOperation
134 	//virtual HRESULT STDMETHODCALLTYPE SetAsyncMode(
135 	//	  /* [in] */ BOOL fDoOpAsync)
136 	//{
137 	//	return E_NOTIMPL;
138 	//}
139 	//
140 	//virtual HRESULT STDMETHODCALLTYPE GetAsyncMode(
141 	//	  /* [out] */ BOOL __RPC_FAR *pfIsOpAsync)
142 	//{
143 	//	return E_NOTIMPL;
144 	//}
145 	//
146 	//virtual HRESULT STDMETHODCALLTYPE StartOperation(
147 	//	  /* [optional][unique][in] */ IBindCtx __RPC_FAR *pbcReserved)
148 	//{
149 	//	return E_NOTIMPL;
150 	//}
151 	//
152 	//virtual HRESULT STDMETHODCALLTYPE InOperation(
153 	//	  /* [out] */ BOOL __RPC_FAR *pfInAsyncOp)
154 	//{
155 	//	return E_NOTIMPL;
156 	//}
157 	//
158 	//virtual HRESULT STDMETHODCALLTYPE EndOperation(
159 	//	  /* [in] */ HRESULT hResult,
160 	//	  /* [unique][in] */ IBindCtx __RPC_FAR *pbcReserved,
161 	//	  /* [in] */ DWORD dwEffects)
162 	//{
163 	//	return E_NOTIMPL;
164 	//}*/
165 };
166 
167  /// implementation of IDropTarget interface
168 class IDropTargetImpl : public IDropTarget
169 {
170 	DWORD m_cRefCount;
171 	bool m_bAllowDrop;
172 	IDropTargetHelper* m_pDropTargetHelper;
173 
174 	FormatArray m_formatetc;
175 	FORMATETC* m_pSupportedFrmt;
176 
177 protected:
178 	HWND m_hTargetWnd;
179 
180 public:
181 	IDropTargetImpl(HWND m_hTargetWnd);
182 	virtual ~IDropTargetImpl();
183 
184 	void AddSuportedFormat(FORMATETC& ftetc) {m_formatetc.push_back(ftetc);}
185 
186 	//return values: true - release the medium. false - don't release the medium
187 	virtual bool OnDrop(FORMATETC* pFmtEtc, STGMEDIUM& medium, DWORD *pdwEffect) = 0;
188 
189 	virtual HRESULT STDMETHODCALLTYPE QueryInterface(
190 		/* [in] */ REFIID riid,
191 		/* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject);
192 	virtual ULONG STDMETHODCALLTYPE AddRef() {return ++m_cRefCount;}
193 	virtual ULONG STDMETHODCALLTYPE Release();
194 
195 	bool QueryDrop(DWORD grfKeyState, LPDWORD pdwEffect);
196 	virtual HRESULT STDMETHODCALLTYPE DragEnter(
197 		/* [unique][in] */ IDataObject __RPC_FAR *pDataObj,
198 		/* [in] */ DWORD grfKeyState,
199 		/* [in] */ POINTL pt,
200 		/* [out][in] */ DWORD __RPC_FAR *pdwEffect);
201 	virtual HRESULT STDMETHODCALLTYPE DragOver(
202 		/* [in] */ DWORD grfKeyState,
203 		/* [in] */ POINTL pt,
204 		/* [out][in] */ DWORD __RPC_FAR *pdwEffect);
205 	virtual HRESULT STDMETHODCALLTYPE DragLeave();
206 	virtual HRESULT STDMETHODCALLTYPE Drop(
207 		/* [unique][in] */ IDataObject __RPC_FAR *pDataObj,
208 		/* [in] */ DWORD grfKeyState,
209 		/* [in] */ POINTL pt,
210 		/* [out][in] */ DWORD __RPC_FAR *pdwEffect);
211 };
212 
213  /// implementation of IDragSourceHelper interface
214 class DragSourceHelper
215 {
216 	IDragSourceHelper* pDragSourceHelper;
217 
218 public:
219 	DragSourceHelper()
220 	{
221 		if (FAILED(CoCreateInstance(CLSID_DragDropHelper,
222 						NULL,
223 						CLSCTX_INPROC_SERVER,
224 						IID_IDragSourceHelper,
225 						(void**)&pDragSourceHelper)))
226 			pDragSourceHelper = NULL;
227 	}
228 
229 	virtual ~DragSourceHelper()
230 	{
231 		if (pDragSourceHelper != NULL)
232 		{
233 			pDragSourceHelper->Release();
234 			pDragSourceHelper=NULL;
235 		}
236 	}
237 
238 	// IDragSourceHelper
239 	HRESULT InitializeFromBitmap(HBITMAP hBitmap,
240 		POINT& pt,	// cursor position in client coords of the window
241 		RECT& rc,	// selected item's bounding rect
242 		IDataObject* pDataObject,
243 		COLORREF crColorKey=GetSysColor(COLOR_WINDOW)// color of the window used for transparent effect.
244 		)
245 	{
246 		if (pDragSourceHelper == NULL)
247 			return E_FAIL;
248 
249 		SHDRAGIMAGE	di;
250 		BITMAP		bm;
251 		GetObject(hBitmap, sizeof(bm), &bm);
252 		di.sizeDragImage.cx = bm.bmWidth;
253 		di.sizeDragImage.cy = bm.bmHeight;
254 		di.hbmpDragImage = hBitmap;
255 		di.crColorKey = crColorKey;
256 		di.ptOffset.x = pt.x - rc.left;
257 		di.ptOffset.y = pt.y - rc.top;
258 		return pDragSourceHelper->InitializeFromBitmap(&di, pDataObject);
259 	}
260 
261 	HRESULT InitializeFromWindow(HWND hwnd, POINT& pt,IDataObject* pDataObject)
262 	{
263 		if (pDragSourceHelper == NULL)
264 			return E_FAIL;
265 		return pDragSourceHelper->InitializeFromWindow(hwnd, &pt, pDataObject);
266 	}
267 };
268