DragDropImpl.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577
  1. #include "StdAfx.h"
  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. // IDataObjectImpl.cpp: implementation of the CIDataObjectImpl class.
  10. //////////////////////////////////////////////////////////////////////
  11. #include <atlbase.h>
  12. #include "DragDropImpl.h"
  13. namespace DuiLib {
  14. //////////////////////////////////////////////////////////////////////
  15. // CIDataObject Class
  16. //////////////////////////////////////////////////////////////////////
  17. CIDataObject::CIDataObject(CIDropSource* pDropSource)
  18. :m_cRefCount(0)
  19. ,m_pDropSource(pDropSource)
  20. {
  21. }
  22. CIDataObject::~CIDataObject()
  23. {
  24. for(int i = 0; i < m_StgMedium.size(); ++i)
  25. {
  26. ReleaseStgMedium(m_StgMedium[i]);
  27. delete m_StgMedium[i];
  28. }
  29. for(int j = 0; j < m_ArrFormatEtc.size(); ++j)
  30. delete m_ArrFormatEtc[j];
  31. }
  32. STDMETHODIMP CIDataObject::QueryInterface(/* [in] */ REFIID riid,
  33. /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject)
  34. {
  35. *ppvObject = NULL;
  36. if (IID_IUnknown==riid || IID_IDataObject==riid)
  37. *ppvObject=this;
  38. /*if(riid == IID_IAsyncOperation)
  39. *ppvObject=(IAsyncOperation*)this;*/
  40. if (NULL!=*ppvObject)
  41. {
  42. ((LPUNKNOWN)*ppvObject)->AddRef();
  43. return S_OK;
  44. }
  45. return E_NOINTERFACE;
  46. }
  47. STDMETHODIMP_(ULONG) CIDataObject::AddRef( void)
  48. {
  49. ATLTRACE("CIDataObject::AddRef\n");
  50. return ++m_cRefCount;
  51. }
  52. STDMETHODIMP_(ULONG) CIDataObject::Release( void)
  53. {
  54. ATLTRACE("CIDataObject::Release\n");
  55. long nTemp;
  56. nTemp = --m_cRefCount;
  57. if(nTemp==0)
  58. delete this;
  59. return nTemp;
  60. }
  61. STDMETHODIMP CIDataObject::GetData(
  62. /* [unique][in] */ FORMATETC __RPC_FAR *pformatetcIn,
  63. /* [out] */ STGMEDIUM __RPC_FAR *pmedium)
  64. {
  65. ATLTRACE("CIDataObject::GetData\n");
  66. if(pformatetcIn == NULL || pmedium == NULL)
  67. return E_INVALIDARG;
  68. pmedium->hGlobal = NULL;
  69. ATLASSERT(m_StgMedium.size() == m_ArrFormatEtc.size());
  70. for(int i=0; i < m_ArrFormatEtc.size(); ++i)
  71. {
  72. if(pformatetcIn->tymed & m_ArrFormatEtc[i]->tymed &&
  73. pformatetcIn->dwAspect == m_ArrFormatEtc[i]->dwAspect &&
  74. pformatetcIn->cfFormat == m_ArrFormatEtc[i]->cfFormat)
  75. {
  76. CopyMedium(pmedium, m_StgMedium[i], m_ArrFormatEtc[i]);
  77. return S_OK;
  78. }
  79. }
  80. return DV_E_FORMATETC;
  81. }
  82. STDMETHODIMP CIDataObject::GetDataHere(
  83. /* [unique][in] */ FORMATETC __RPC_FAR *pformatetc,
  84. /* [out][in] */ STGMEDIUM __RPC_FAR *pmedium)
  85. {
  86. ATLTRACE("CIDataObject::GetDataHere\n");
  87. return E_NOTIMPL;
  88. }
  89. STDMETHODIMP CIDataObject::QueryGetData(
  90. /* [unique][in] */ FORMATETC __RPC_FAR *pformatetc)
  91. {
  92. ATLTRACE("CIDataObject::QueryGetData\n");
  93. if(pformatetc == NULL)
  94. return E_INVALIDARG;
  95. //support others if needed DVASPECT_THUMBNAIL //DVASPECT_ICON //DVASPECT_DOCPRINT
  96. if (!(DVASPECT_CONTENT & pformatetc->dwAspect))
  97. return (DV_E_DVASPECT);
  98. HRESULT hr = DV_E_TYMED;
  99. for(int i = 0; i < m_ArrFormatEtc.size(); ++i)
  100. {
  101. if(pformatetc->tymed & m_ArrFormatEtc[i]->tymed)
  102. {
  103. if(pformatetc->cfFormat == m_ArrFormatEtc[i]->cfFormat)
  104. return S_OK;
  105. else
  106. hr = DV_E_CLIPFORMAT;
  107. }
  108. else
  109. hr = DV_E_TYMED;
  110. }
  111. return hr;
  112. }
  113. STDMETHODIMP CIDataObject::GetCanonicalFormatEtc(
  114. /* [unique][in] */ FORMATETC __RPC_FAR *pformatectIn,
  115. /* [out] */ FORMATETC __RPC_FAR *pformatetcOut)
  116. {
  117. ATLTRACE("CIDataObject::GetCanonicalFormatEtc\n");
  118. if (pformatetcOut == NULL)
  119. return E_INVALIDARG;
  120. return DATA_S_SAMEFORMATETC;
  121. }
  122. STDMETHODIMP CIDataObject::SetData(
  123. /* [unique][in] */ FORMATETC __RPC_FAR *pformatetc,
  124. /* [unique][in] */ STGMEDIUM __RPC_FAR *pmedium,
  125. /* [in] */ BOOL fRelease)
  126. {
  127. ATLTRACE("CIDataObject::SetData\n");
  128. if(pformatetc == NULL || pmedium == NULL)
  129. return E_INVALIDARG;
  130. ATLASSERT(pformatetc->tymed == pmedium->tymed);
  131. FORMATETC* fetc=new FORMATETC;
  132. STGMEDIUM* pStgMed = new STGMEDIUM;
  133. if(fetc == NULL || pStgMed == NULL)
  134. return E_OUTOFMEMORY;
  135. ZeroMemory(fetc,sizeof(FORMATETC));
  136. ZeroMemory(pStgMed,sizeof(STGMEDIUM));
  137. *fetc = *pformatetc;
  138. m_ArrFormatEtc.push_back(fetc);
  139. if(fRelease)
  140. *pStgMed = *pmedium;
  141. else
  142. {
  143. CopyMedium(pStgMed, pmedium, pformatetc);
  144. }
  145. m_StgMedium.push_back(pStgMed);
  146. return S_OK;
  147. }
  148. void CIDataObject::CopyMedium(STGMEDIUM* pMedDest, STGMEDIUM* pMedSrc, FORMATETC* pFmtSrc)
  149. {
  150. switch(pMedSrc->tymed)
  151. {
  152. case TYMED_HGLOBAL:
  153. pMedDest->hGlobal = (HGLOBAL)OleDuplicateData(pMedSrc->hGlobal,pFmtSrc->cfFormat, NULL);
  154. break;
  155. case TYMED_GDI:
  156. pMedDest->hBitmap = (HBITMAP)OleDuplicateData(pMedSrc->hBitmap,pFmtSrc->cfFormat, NULL);
  157. break;
  158. case TYMED_MFPICT:
  159. pMedDest->hMetaFilePict = (HMETAFILEPICT)OleDuplicateData(pMedSrc->hMetaFilePict,pFmtSrc->cfFormat, NULL);
  160. break;
  161. case TYMED_ENHMF:
  162. pMedDest->hEnhMetaFile = (HENHMETAFILE)OleDuplicateData(pMedSrc->hEnhMetaFile,pFmtSrc->cfFormat, NULL);
  163. break;
  164. case TYMED_FILE:
  165. pMedSrc->lpszFileName = (LPOLESTR)OleDuplicateData(pMedSrc->lpszFileName,pFmtSrc->cfFormat, NULL);
  166. break;
  167. case TYMED_ISTREAM:
  168. pMedDest->pstm = pMedSrc->pstm;
  169. pMedSrc->pstm->AddRef();
  170. break;
  171. case TYMED_ISTORAGE:
  172. pMedDest->pstg = pMedSrc->pstg;
  173. pMedSrc->pstg->AddRef();
  174. break;
  175. case TYMED_NULL:
  176. default:
  177. break;
  178. }
  179. pMedDest->tymed = pMedSrc->tymed;
  180. pMedDest->pUnkForRelease = NULL;
  181. if(pMedSrc->pUnkForRelease != NULL)
  182. {
  183. pMedDest->pUnkForRelease = pMedSrc->pUnkForRelease;
  184. pMedSrc->pUnkForRelease->AddRef();
  185. }
  186. }
  187. STDMETHODIMP CIDataObject::EnumFormatEtc(
  188. /* [in] */ DWORD dwDirection,
  189. /* [out] */ IEnumFORMATETC __RPC_FAR *__RPC_FAR *ppenumFormatEtc)
  190. {
  191. ATLTRACE("CIDataObject::EnumFormatEtc\n");
  192. if(ppenumFormatEtc == NULL)
  193. return E_POINTER;
  194. *ppenumFormatEtc=NULL;
  195. switch (dwDirection)
  196. {
  197. case DATADIR_GET:
  198. *ppenumFormatEtc= new CEnumFormatEtc(m_ArrFormatEtc);
  199. if(*ppenumFormatEtc == NULL)
  200. return E_OUTOFMEMORY;
  201. (*ppenumFormatEtc)->AddRef();
  202. break;
  203. case DATADIR_SET:
  204. default:
  205. return E_NOTIMPL;
  206. break;
  207. }
  208. return S_OK;
  209. }
  210. STDMETHODIMP CIDataObject::DAdvise(
  211. /* [in] */ FORMATETC __RPC_FAR *pformatetc,
  212. /* [in] */ DWORD advf,
  213. /* [unique][in] */ IAdviseSink __RPC_FAR *pAdvSink,
  214. /* [out] */ DWORD __RPC_FAR *pdwConnection)
  215. {
  216. ATLTRACE("CIDataObject::DAdvise\n");
  217. return OLE_E_ADVISENOTSUPPORTED;
  218. }
  219. STDMETHODIMP CIDataObject::DUnadvise(
  220. /* [in] */ DWORD dwConnection)
  221. {
  222. ATLTRACE("CIDataObject::DUnadvise\n");
  223. return E_NOTIMPL;
  224. }
  225. HRESULT STDMETHODCALLTYPE CIDataObject::EnumDAdvise(
  226. /* [out] */ IEnumSTATDATA __RPC_FAR *__RPC_FAR *ppenumAdvise)
  227. {
  228. ATLTRACE("CIDataObject::EnumDAdvise\n");
  229. return OLE_E_ADVISENOTSUPPORTED;
  230. }
  231. //////////////////////////////////////////////////////////////////////
  232. // CIDropSource Class
  233. //////////////////////////////////////////////////////////////////////
  234. STDMETHODIMP CIDropSource::QueryInterface(/* [in] */ REFIID riid,
  235. /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject)
  236. {
  237. *ppvObject = NULL;
  238. if (IID_IUnknown==riid || IID_IDropSource==riid)
  239. *ppvObject=this;
  240. if (*ppvObject != NULL)
  241. {
  242. ((LPUNKNOWN)*ppvObject)->AddRef();
  243. return S_OK;
  244. }
  245. return E_NOINTERFACE;
  246. }
  247. STDMETHODIMP_(ULONG) CIDropSource::AddRef( void)
  248. {
  249. ATLTRACE("CIDropSource::AddRef\n");
  250. return ++m_cRefCount;
  251. }
  252. STDMETHODIMP_(ULONG) CIDropSource::Release( void)
  253. {
  254. ATLTRACE("CIDropSource::Release\n");
  255. long nTemp;
  256. nTemp = --m_cRefCount;
  257. ATLASSERT(nTemp >= 0);
  258. if(nTemp==0)
  259. delete this;
  260. return nTemp;
  261. }
  262. STDMETHODIMP CIDropSource::QueryContinueDrag(
  263. /* [in] */ BOOL fEscapePressed,
  264. /* [in] */ DWORD grfKeyState)
  265. {
  266. //ATLTRACE("CIDropSource::QueryContinueDrag\n");
  267. if(fEscapePressed)
  268. return DRAGDROP_S_CANCEL;
  269. if(!(grfKeyState & (MK_LBUTTON|MK_RBUTTON)))
  270. {
  271. m_bDropped = true;
  272. return DRAGDROP_S_DROP;
  273. }
  274. return S_OK;
  275. }
  276. STDMETHODIMP CIDropSource::GiveFeedback(
  277. /* [in] */ DWORD dwEffect)
  278. {
  279. //ATLTRACE("CIDropSource::GiveFeedback\n");
  280. return DRAGDROP_S_USEDEFAULTCURSORS;
  281. }
  282. //////////////////////////////////////////////////////////////////////
  283. // CEnumFormatEtc Class
  284. //////////////////////////////////////////////////////////////////////
  285. CEnumFormatEtc::CEnumFormatEtc(const FormatEtcArray& ArrFE):
  286. m_cRefCount(0),m_iCur(0)
  287. {
  288. ATLTRACE("CEnumFormatEtc::CEnumFormatEtc()\n");
  289. for(int i = 0; i < ArrFE.size(); ++i)
  290. m_pFmtEtc.push_back(ArrFE[i]);
  291. }
  292. CEnumFormatEtc::CEnumFormatEtc(const PFormatEtcArray& ArrFE):
  293. m_cRefCount(0),m_iCur(0)
  294. {
  295. for(int i = 0; i < ArrFE.size(); ++i)
  296. m_pFmtEtc.push_back(*ArrFE[i]);
  297. }
  298. STDMETHODIMP CEnumFormatEtc::QueryInterface(REFIID refiid, void FAR* FAR* ppv)
  299. {
  300. ATLTRACE("CEnumFormatEtc::QueryInterface()\n");
  301. *ppv = NULL;
  302. if (IID_IUnknown==refiid || IID_IEnumFORMATETC==refiid)
  303. *ppv=this;
  304. if (*ppv != NULL)
  305. {
  306. ((LPUNKNOWN)*ppv)->AddRef();
  307. return S_OK;
  308. }
  309. return E_NOINTERFACE;
  310. }
  311. STDMETHODIMP_(ULONG) CEnumFormatEtc::AddRef(void)
  312. {
  313. ATLTRACE("CEnumFormatEtc::AddRef()\n");
  314. return ++m_cRefCount;
  315. }
  316. STDMETHODIMP_(ULONG) CEnumFormatEtc::Release(void)
  317. {
  318. ATLTRACE("CEnumFormatEtc::Release()\n");
  319. long nTemp = --m_cRefCount;
  320. ATLASSERT(nTemp >= 0);
  321. if(nTemp == 0)
  322. delete this;
  323. return nTemp;
  324. }
  325. STDMETHODIMP CEnumFormatEtc::Next( ULONG celt,LPFORMATETC lpFormatEtc, ULONG FAR *pceltFetched)
  326. {
  327. ATLTRACE("CEnumFormatEtc::Next()\n");
  328. if(pceltFetched != NULL)
  329. *pceltFetched=0;
  330. ULONG cReturn = celt;
  331. if(celt <= 0 || lpFormatEtc == NULL || m_iCur >= m_pFmtEtc.size())
  332. return S_FALSE;
  333. if(pceltFetched == NULL && celt != 1) // pceltFetched can be NULL only for 1 item request
  334. return S_FALSE;
  335. while (m_iCur < m_pFmtEtc.size() && cReturn > 0)
  336. {
  337. *lpFormatEtc++ = m_pFmtEtc[m_iCur++];
  338. --cReturn;
  339. }
  340. if (pceltFetched != NULL)
  341. *pceltFetched = celt - cReturn;
  342. return (cReturn == 0) ? S_OK : S_FALSE;
  343. }
  344. STDMETHODIMP CEnumFormatEtc::Skip(ULONG celt)
  345. {
  346. ATLTRACE("CEnumFormatEtc::Skip()\n");
  347. if((m_iCur + int(celt)) >= m_pFmtEtc.size())
  348. return S_FALSE;
  349. m_iCur += celt;
  350. return S_OK;
  351. }
  352. STDMETHODIMP CEnumFormatEtc::Reset(void)
  353. {
  354. ATLTRACE("CEnumFormatEtc::Reset()\n");
  355. m_iCur = 0;
  356. return S_OK;
  357. }
  358. STDMETHODIMP CEnumFormatEtc::Clone(IEnumFORMATETC FAR * FAR*ppCloneEnumFormatEtc)
  359. {
  360. ATLTRACE("CEnumFormatEtc::Clone()\n");
  361. if(ppCloneEnumFormatEtc == NULL)
  362. return E_POINTER;
  363. CEnumFormatEtc *newEnum = new CEnumFormatEtc(m_pFmtEtc);
  364. if(newEnum ==NULL)
  365. return E_OUTOFMEMORY;
  366. newEnum->AddRef();
  367. newEnum->m_iCur = m_iCur;
  368. *ppCloneEnumFormatEtc = newEnum;
  369. return S_OK;
  370. }
  371. //////////////////////////////////////////////////////////////////////
  372. // CIDropTarget Class
  373. //////////////////////////////////////////////////////////////////////
  374. CIDropTarget::CIDropTarget() : m_hTargetWnd(NULL), m_cRefCount(0), m_bAllowDrop(false), m_pDropTargetHelper(NULL), m_pSupportedFrmt(NULL)
  375. {
  376. if(FAILED(CoCreateInstance(CLSID_DragDropHelper,NULL,CLSCTX_INPROC_SERVER, IID_IDropTargetHelper,(LPVOID*)&m_pDropTargetHelper))) {
  377. m_pDropTargetHelper = NULL;
  378. }
  379. }
  380. CIDropTarget::~CIDropTarget()
  381. {
  382. if(m_pDropTargetHelper != NULL) {
  383. m_pDropTargetHelper->Release();
  384. m_pDropTargetHelper = NULL;
  385. }
  386. }
  387. HRESULT STDMETHODCALLTYPE CIDropTarget::QueryInterface( /* [in] */ REFIID riid, /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject)
  388. {
  389. *ppvObject = NULL;
  390. if (IID_IUnknown==riid || IID_IDropTarget==riid)
  391. *ppvObject=this;
  392. if (*ppvObject != NULL)
  393. {
  394. ((LPUNKNOWN)*ppvObject)->AddRef();
  395. return S_OK;
  396. }
  397. return E_NOINTERFACE;
  398. }
  399. ULONG STDMETHODCALLTYPE CIDropTarget::Release( void)
  400. {
  401. ATLTRACE("CIDropTarget::Release\n");
  402. return --m_cRefCount;
  403. }
  404. bool CIDropTarget::QueryDrop(DWORD grfKeyState, LPDWORD pdwEffect)
  405. {
  406. ATLTRACE("CIDropTarget::QueryDrop\n");
  407. DWORD dwOKEffects = *pdwEffect;
  408. if(!m_bAllowDrop)
  409. {
  410. *pdwEffect = DROPEFFECT_NONE;
  411. return false;
  412. }
  413. //CTRL+SHIFT -- DROPEFFECT_LINK
  414. //CTRL -- DROPEFFECT_COPY
  415. //SHIFT -- DROPEFFECT_MOVE
  416. //no modifier -- DROPEFFECT_MOVE or whatever is allowed by src
  417. *pdwEffect = (grfKeyState & MK_CONTROL) ? ((grfKeyState & MK_SHIFT) ? DROPEFFECT_LINK : DROPEFFECT_COPY): ((grfKeyState & MK_SHIFT) ? DROPEFFECT_MOVE : 0);
  418. if(*pdwEffect == 0)
  419. {
  420. // No modifier keys used by user while dragging.
  421. if (DROPEFFECT_COPY & dwOKEffects)
  422. *pdwEffect = DROPEFFECT_COPY;
  423. else if (DROPEFFECT_MOVE & dwOKEffects)
  424. *pdwEffect = DROPEFFECT_MOVE;
  425. else if (DROPEFFECT_LINK & dwOKEffects)
  426. *pdwEffect = DROPEFFECT_LINK;
  427. else
  428. {
  429. *pdwEffect = DROPEFFECT_NONE;
  430. }
  431. }
  432. else
  433. {
  434. // Check if the drag source application allows the drop effect desired by user.
  435. // The drag source specifies this in DoDragDrop
  436. if(!(*pdwEffect & dwOKEffects))
  437. *pdwEffect = DROPEFFECT_NONE;
  438. }
  439. return (DROPEFFECT_NONE == *pdwEffect)?false:true;
  440. }
  441. HRESULT STDMETHODCALLTYPE CIDropTarget::DragEnter(
  442. /* [unique][in] */ IDataObject __RPC_FAR *pDataObj,
  443. /* [in] */ DWORD grfKeyState,
  444. /* [in] */ POINTL pt,
  445. /* [out][in] */ DWORD __RPC_FAR *pdwEffect)
  446. {
  447. ATLTRACE("CIDropTarget::DragEnter\n");
  448. if(pDataObj == NULL) return E_INVALIDARG;
  449. if(m_pDropTargetHelper) {
  450. m_pDropTargetHelper->DragEnter(m_hTargetWnd, pDataObj, (LPPOINT)&pt, *pdwEffect);
  451. }
  452. m_pSupportedFrmt = NULL;
  453. for(int i =0; i<m_formatetc.size(); ++i) {
  454. m_bAllowDrop = pDataObj->QueryGetData(&m_formatetc[i]) == S_OK;
  455. if(m_bAllowDrop) {
  456. m_pSupportedFrmt = &m_formatetc[i];
  457. break;
  458. }
  459. }
  460. QueryDrop(grfKeyState, pdwEffect);
  461. return S_OK;
  462. }
  463. HRESULT STDMETHODCALLTYPE CIDropTarget::DragOver(
  464. /* [in] */ DWORD grfKeyState,
  465. /* [in] */ POINTL pt,
  466. /* [out][in] */ DWORD __RPC_FAR *pdwEffect)
  467. {
  468. ATLTRACE("CIDropTarget::DragOver\n");
  469. if(m_pDropTargetHelper)
  470. m_pDropTargetHelper->DragOver((LPPOINT)&pt, *pdwEffect);
  471. QueryDrop(grfKeyState, pdwEffect);
  472. return S_OK;
  473. }
  474. HRESULT STDMETHODCALLTYPE CIDropTarget::DragLeave( void)
  475. {
  476. ATLTRACE("CIDropTarget::DragLeave\n");
  477. if(m_pDropTargetHelper)
  478. m_pDropTargetHelper->DragLeave();
  479. m_bAllowDrop = false;
  480. m_pSupportedFrmt = NULL;
  481. return S_OK;
  482. }
  483. HRESULT STDMETHODCALLTYPE CIDropTarget::Drop(
  484. /* [unique][in] */ IDataObject __RPC_FAR *pDataObj,
  485. /* [in] */ DWORD grfKeyState, /* [in] */ POINTL pt,
  486. /* [out][in] */ DWORD __RPC_FAR *pdwEffect)
  487. {
  488. ATLTRACE("CIDropTarget::Drop\n");
  489. if (pDataObj == NULL) return E_INVALIDARG;
  490. if(m_pDropTargetHelper) m_pDropTargetHelper->Drop(pDataObj, (LPPOINT)&pt, *pdwEffect);
  491. if(QueryDrop(grfKeyState, pdwEffect)) {
  492. if(m_bAllowDrop && m_pSupportedFrmt != NULL) {
  493. STGMEDIUM medium;
  494. if(pDataObj->GetData(m_pSupportedFrmt, &medium) == S_OK) {
  495. if(OnDrop(m_pSupportedFrmt, medium, pdwEffect)) //does derive class wants us to free medium?
  496. ReleaseStgMedium(&medium);
  497. }
  498. }
  499. }
  500. m_bAllowDrop=false;
  501. *pdwEffect = DROPEFFECT_NONE;
  502. m_pSupportedFrmt = NULL;
  503. return S_OK;
  504. }
  505. }