123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577 |
- #include "StdAfx.h"
- /**************************************************************************
- THIS CODE AND INFORMATION IS PROVIDED 'AS IS' WITHOUT WARRANTY OF
- ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
- PARTICULAR PURPOSE.
- Author: Leon Finker 1/2001
- **************************************************************************/
- // IDataObjectImpl.cpp: implementation of the CIDataObjectImpl class.
- //////////////////////////////////////////////////////////////////////
- #include <atlbase.h>
- #include "DragDropImpl.h"
- namespace DuiLib {
- //////////////////////////////////////////////////////////////////////
- // CIDataObject Class
- //////////////////////////////////////////////////////////////////////
- CIDataObject::CIDataObject(CIDropSource* pDropSource)
- :m_cRefCount(0)
- ,m_pDropSource(pDropSource)
- {
- }
- CIDataObject::~CIDataObject()
- {
- for(int i = 0; i < m_StgMedium.size(); ++i)
- {
- ReleaseStgMedium(m_StgMedium[i]);
- delete m_StgMedium[i];
- }
- for(int j = 0; j < m_ArrFormatEtc.size(); ++j)
- delete m_ArrFormatEtc[j];
- }
- STDMETHODIMP CIDataObject::QueryInterface(/* [in] */ REFIID riid,
- /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject)
- {
- *ppvObject = NULL;
- if (IID_IUnknown==riid || IID_IDataObject==riid)
- *ppvObject=this;
- /*if(riid == IID_IAsyncOperation)
- *ppvObject=(IAsyncOperation*)this;*/
- if (NULL!=*ppvObject)
- {
- ((LPUNKNOWN)*ppvObject)->AddRef();
- return S_OK;
- }
- return E_NOINTERFACE;
- }
- STDMETHODIMP_(ULONG) CIDataObject::AddRef( void)
- {
- ATLTRACE("CIDataObject::AddRef\n");
- return ++m_cRefCount;
- }
- STDMETHODIMP_(ULONG) CIDataObject::Release( void)
- {
- ATLTRACE("CIDataObject::Release\n");
- long nTemp;
- nTemp = --m_cRefCount;
- if(nTemp==0)
- delete this;
- return nTemp;
- }
- STDMETHODIMP CIDataObject::GetData(
- /* [unique][in] */ FORMATETC __RPC_FAR *pformatetcIn,
- /* [out] */ STGMEDIUM __RPC_FAR *pmedium)
- {
- ATLTRACE("CIDataObject::GetData\n");
- if(pformatetcIn == NULL || pmedium == NULL)
- return E_INVALIDARG;
- pmedium->hGlobal = NULL;
- ATLASSERT(m_StgMedium.size() == m_ArrFormatEtc.size());
- for(int i=0; i < m_ArrFormatEtc.size(); ++i)
- {
- if(pformatetcIn->tymed & m_ArrFormatEtc[i]->tymed &&
- pformatetcIn->dwAspect == m_ArrFormatEtc[i]->dwAspect &&
- pformatetcIn->cfFormat == m_ArrFormatEtc[i]->cfFormat)
- {
- CopyMedium(pmedium, m_StgMedium[i], m_ArrFormatEtc[i]);
- return S_OK;
- }
- }
- return DV_E_FORMATETC;
- }
- STDMETHODIMP CIDataObject::GetDataHere(
- /* [unique][in] */ FORMATETC __RPC_FAR *pformatetc,
- /* [out][in] */ STGMEDIUM __RPC_FAR *pmedium)
- {
- ATLTRACE("CIDataObject::GetDataHere\n");
- return E_NOTIMPL;
- }
- STDMETHODIMP CIDataObject::QueryGetData(
- /* [unique][in] */ FORMATETC __RPC_FAR *pformatetc)
- {
- ATLTRACE("CIDataObject::QueryGetData\n");
- if(pformatetc == NULL)
- return E_INVALIDARG;
- //support others if needed DVASPECT_THUMBNAIL //DVASPECT_ICON //DVASPECT_DOCPRINT
- if (!(DVASPECT_CONTENT & pformatetc->dwAspect))
- return (DV_E_DVASPECT);
- HRESULT hr = DV_E_TYMED;
- for(int i = 0; i < m_ArrFormatEtc.size(); ++i)
- {
- if(pformatetc->tymed & m_ArrFormatEtc[i]->tymed)
- {
- if(pformatetc->cfFormat == m_ArrFormatEtc[i]->cfFormat)
- return S_OK;
- else
- hr = DV_E_CLIPFORMAT;
- }
- else
- hr = DV_E_TYMED;
- }
- return hr;
- }
- STDMETHODIMP CIDataObject::GetCanonicalFormatEtc(
- /* [unique][in] */ FORMATETC __RPC_FAR *pformatectIn,
- /* [out] */ FORMATETC __RPC_FAR *pformatetcOut)
- {
- ATLTRACE("CIDataObject::GetCanonicalFormatEtc\n");
- if (pformatetcOut == NULL)
- return E_INVALIDARG;
- return DATA_S_SAMEFORMATETC;
- }
- STDMETHODIMP CIDataObject::SetData(
- /* [unique][in] */ FORMATETC __RPC_FAR *pformatetc,
- /* [unique][in] */ STGMEDIUM __RPC_FAR *pmedium,
- /* [in] */ BOOL fRelease)
- {
- ATLTRACE("CIDataObject::SetData\n");
- if(pformatetc == NULL || pmedium == NULL)
- return E_INVALIDARG;
- ATLASSERT(pformatetc->tymed == pmedium->tymed);
- FORMATETC* fetc=new FORMATETC;
- STGMEDIUM* pStgMed = new STGMEDIUM;
- if(fetc == NULL || pStgMed == NULL)
- return E_OUTOFMEMORY;
- ZeroMemory(fetc,sizeof(FORMATETC));
- ZeroMemory(pStgMed,sizeof(STGMEDIUM));
- *fetc = *pformatetc;
- m_ArrFormatEtc.push_back(fetc);
- if(fRelease)
- *pStgMed = *pmedium;
- else
- {
- CopyMedium(pStgMed, pmedium, pformatetc);
- }
- m_StgMedium.push_back(pStgMed);
- return S_OK;
- }
- void CIDataObject::CopyMedium(STGMEDIUM* pMedDest, STGMEDIUM* pMedSrc, FORMATETC* pFmtSrc)
- {
- switch(pMedSrc->tymed)
- {
- case TYMED_HGLOBAL:
- pMedDest->hGlobal = (HGLOBAL)OleDuplicateData(pMedSrc->hGlobal,pFmtSrc->cfFormat, NULL);
- break;
- case TYMED_GDI:
- pMedDest->hBitmap = (HBITMAP)OleDuplicateData(pMedSrc->hBitmap,pFmtSrc->cfFormat, NULL);
- break;
- case TYMED_MFPICT:
- pMedDest->hMetaFilePict = (HMETAFILEPICT)OleDuplicateData(pMedSrc->hMetaFilePict,pFmtSrc->cfFormat, NULL);
- break;
- case TYMED_ENHMF:
- pMedDest->hEnhMetaFile = (HENHMETAFILE)OleDuplicateData(pMedSrc->hEnhMetaFile,pFmtSrc->cfFormat, NULL);
- break;
- case TYMED_FILE:
- pMedSrc->lpszFileName = (LPOLESTR)OleDuplicateData(pMedSrc->lpszFileName,pFmtSrc->cfFormat, NULL);
- break;
- case TYMED_ISTREAM:
- pMedDest->pstm = pMedSrc->pstm;
- pMedSrc->pstm->AddRef();
- break;
- case TYMED_ISTORAGE:
- pMedDest->pstg = pMedSrc->pstg;
- pMedSrc->pstg->AddRef();
- break;
- case TYMED_NULL:
- default:
- break;
- }
- pMedDest->tymed = pMedSrc->tymed;
- pMedDest->pUnkForRelease = NULL;
- if(pMedSrc->pUnkForRelease != NULL)
- {
- pMedDest->pUnkForRelease = pMedSrc->pUnkForRelease;
- pMedSrc->pUnkForRelease->AddRef();
- }
- }
- STDMETHODIMP CIDataObject::EnumFormatEtc(
- /* [in] */ DWORD dwDirection,
- /* [out] */ IEnumFORMATETC __RPC_FAR *__RPC_FAR *ppenumFormatEtc)
- {
- ATLTRACE("CIDataObject::EnumFormatEtc\n");
- if(ppenumFormatEtc == NULL)
- return E_POINTER;
- *ppenumFormatEtc=NULL;
- switch (dwDirection)
- {
- case DATADIR_GET:
- *ppenumFormatEtc= new CEnumFormatEtc(m_ArrFormatEtc);
- if(*ppenumFormatEtc == NULL)
- return E_OUTOFMEMORY;
- (*ppenumFormatEtc)->AddRef();
- break;
- case DATADIR_SET:
- default:
- return E_NOTIMPL;
- break;
- }
- return S_OK;
- }
- STDMETHODIMP CIDataObject::DAdvise(
- /* [in] */ FORMATETC __RPC_FAR *pformatetc,
- /* [in] */ DWORD advf,
- /* [unique][in] */ IAdviseSink __RPC_FAR *pAdvSink,
- /* [out] */ DWORD __RPC_FAR *pdwConnection)
- {
- ATLTRACE("CIDataObject::DAdvise\n");
- return OLE_E_ADVISENOTSUPPORTED;
- }
- STDMETHODIMP CIDataObject::DUnadvise(
- /* [in] */ DWORD dwConnection)
- {
- ATLTRACE("CIDataObject::DUnadvise\n");
- return E_NOTIMPL;
- }
- HRESULT STDMETHODCALLTYPE CIDataObject::EnumDAdvise(
- /* [out] */ IEnumSTATDATA __RPC_FAR *__RPC_FAR *ppenumAdvise)
- {
- ATLTRACE("CIDataObject::EnumDAdvise\n");
- return OLE_E_ADVISENOTSUPPORTED;
- }
- //////////////////////////////////////////////////////////////////////
- // CIDropSource Class
- //////////////////////////////////////////////////////////////////////
- STDMETHODIMP CIDropSource::QueryInterface(/* [in] */ REFIID riid,
- /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject)
- {
- *ppvObject = NULL;
- if (IID_IUnknown==riid || IID_IDropSource==riid)
- *ppvObject=this;
- if (*ppvObject != NULL)
- {
- ((LPUNKNOWN)*ppvObject)->AddRef();
- return S_OK;
- }
- return E_NOINTERFACE;
- }
- STDMETHODIMP_(ULONG) CIDropSource::AddRef( void)
- {
- ATLTRACE("CIDropSource::AddRef\n");
- return ++m_cRefCount;
- }
- STDMETHODIMP_(ULONG) CIDropSource::Release( void)
- {
- ATLTRACE("CIDropSource::Release\n");
- long nTemp;
- nTemp = --m_cRefCount;
- ATLASSERT(nTemp >= 0);
- if(nTemp==0)
- delete this;
- return nTemp;
- }
- STDMETHODIMP CIDropSource::QueryContinueDrag(
- /* [in] */ BOOL fEscapePressed,
- /* [in] */ DWORD grfKeyState)
- {
- //ATLTRACE("CIDropSource::QueryContinueDrag\n");
- if(fEscapePressed)
- return DRAGDROP_S_CANCEL;
- if(!(grfKeyState & (MK_LBUTTON|MK_RBUTTON)))
- {
- m_bDropped = true;
- return DRAGDROP_S_DROP;
- }
- return S_OK;
- }
- STDMETHODIMP CIDropSource::GiveFeedback(
- /* [in] */ DWORD dwEffect)
- {
- //ATLTRACE("CIDropSource::GiveFeedback\n");
- return DRAGDROP_S_USEDEFAULTCURSORS;
- }
- //////////////////////////////////////////////////////////////////////
- // CEnumFormatEtc Class
- //////////////////////////////////////////////////////////////////////
- CEnumFormatEtc::CEnumFormatEtc(const FormatEtcArray& ArrFE):
- m_cRefCount(0),m_iCur(0)
- {
- ATLTRACE("CEnumFormatEtc::CEnumFormatEtc()\n");
- for(int i = 0; i < ArrFE.size(); ++i)
- m_pFmtEtc.push_back(ArrFE[i]);
- }
- CEnumFormatEtc::CEnumFormatEtc(const PFormatEtcArray& ArrFE):
- m_cRefCount(0),m_iCur(0)
- {
- for(int i = 0; i < ArrFE.size(); ++i)
- m_pFmtEtc.push_back(*ArrFE[i]);
- }
- STDMETHODIMP CEnumFormatEtc::QueryInterface(REFIID refiid, void FAR* FAR* ppv)
- {
- ATLTRACE("CEnumFormatEtc::QueryInterface()\n");
- *ppv = NULL;
- if (IID_IUnknown==refiid || IID_IEnumFORMATETC==refiid)
- *ppv=this;
- if (*ppv != NULL)
- {
- ((LPUNKNOWN)*ppv)->AddRef();
- return S_OK;
- }
- return E_NOINTERFACE;
- }
- STDMETHODIMP_(ULONG) CEnumFormatEtc::AddRef(void)
- {
- ATLTRACE("CEnumFormatEtc::AddRef()\n");
- return ++m_cRefCount;
- }
- STDMETHODIMP_(ULONG) CEnumFormatEtc::Release(void)
- {
- ATLTRACE("CEnumFormatEtc::Release()\n");
- long nTemp = --m_cRefCount;
- ATLASSERT(nTemp >= 0);
- if(nTemp == 0)
- delete this;
- return nTemp;
- }
- STDMETHODIMP CEnumFormatEtc::Next( ULONG celt,LPFORMATETC lpFormatEtc, ULONG FAR *pceltFetched)
- {
- ATLTRACE("CEnumFormatEtc::Next()\n");
- if(pceltFetched != NULL)
- *pceltFetched=0;
- ULONG cReturn = celt;
- if(celt <= 0 || lpFormatEtc == NULL || m_iCur >= m_pFmtEtc.size())
- return S_FALSE;
- if(pceltFetched == NULL && celt != 1) // pceltFetched can be NULL only for 1 item request
- return S_FALSE;
- while (m_iCur < m_pFmtEtc.size() && cReturn > 0)
- {
- *lpFormatEtc++ = m_pFmtEtc[m_iCur++];
- --cReturn;
- }
- if (pceltFetched != NULL)
- *pceltFetched = celt - cReturn;
- return (cReturn == 0) ? S_OK : S_FALSE;
- }
- STDMETHODIMP CEnumFormatEtc::Skip(ULONG celt)
- {
- ATLTRACE("CEnumFormatEtc::Skip()\n");
- if((m_iCur + int(celt)) >= m_pFmtEtc.size())
- return S_FALSE;
- m_iCur += celt;
- return S_OK;
- }
- STDMETHODIMP CEnumFormatEtc::Reset(void)
- {
- ATLTRACE("CEnumFormatEtc::Reset()\n");
- m_iCur = 0;
- return S_OK;
- }
- STDMETHODIMP CEnumFormatEtc::Clone(IEnumFORMATETC FAR * FAR*ppCloneEnumFormatEtc)
- {
- ATLTRACE("CEnumFormatEtc::Clone()\n");
- if(ppCloneEnumFormatEtc == NULL)
- return E_POINTER;
- CEnumFormatEtc *newEnum = new CEnumFormatEtc(m_pFmtEtc);
- if(newEnum ==NULL)
- return E_OUTOFMEMORY;
- newEnum->AddRef();
- newEnum->m_iCur = m_iCur;
- *ppCloneEnumFormatEtc = newEnum;
- return S_OK;
- }
- //////////////////////////////////////////////////////////////////////
- // CIDropTarget Class
- //////////////////////////////////////////////////////////////////////
- CIDropTarget::CIDropTarget() : m_hTargetWnd(NULL), m_cRefCount(0), m_bAllowDrop(false), m_pDropTargetHelper(NULL), m_pSupportedFrmt(NULL)
- {
- if(FAILED(CoCreateInstance(CLSID_DragDropHelper,NULL,CLSCTX_INPROC_SERVER, IID_IDropTargetHelper,(LPVOID*)&m_pDropTargetHelper))) {
- m_pDropTargetHelper = NULL;
- }
- }
- CIDropTarget::~CIDropTarget()
- {
- if(m_pDropTargetHelper != NULL) {
- m_pDropTargetHelper->Release();
- m_pDropTargetHelper = NULL;
- }
- }
- HRESULT STDMETHODCALLTYPE CIDropTarget::QueryInterface( /* [in] */ REFIID riid, /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject)
- {
- *ppvObject = NULL;
- if (IID_IUnknown==riid || IID_IDropTarget==riid)
- *ppvObject=this;
- if (*ppvObject != NULL)
- {
- ((LPUNKNOWN)*ppvObject)->AddRef();
- return S_OK;
- }
- return E_NOINTERFACE;
- }
- ULONG STDMETHODCALLTYPE CIDropTarget::Release( void)
- {
- ATLTRACE("CIDropTarget::Release\n");
- return --m_cRefCount;
- }
- bool CIDropTarget::QueryDrop(DWORD grfKeyState, LPDWORD pdwEffect)
- {
- ATLTRACE("CIDropTarget::QueryDrop\n");
- DWORD dwOKEffects = *pdwEffect;
- if(!m_bAllowDrop)
- {
- *pdwEffect = DROPEFFECT_NONE;
- return false;
- }
- //CTRL+SHIFT -- DROPEFFECT_LINK
- //CTRL -- DROPEFFECT_COPY
- //SHIFT -- DROPEFFECT_MOVE
- //no modifier -- DROPEFFECT_MOVE or whatever is allowed by src
- *pdwEffect = (grfKeyState & MK_CONTROL) ? ((grfKeyState & MK_SHIFT) ? DROPEFFECT_LINK : DROPEFFECT_COPY): ((grfKeyState & MK_SHIFT) ? DROPEFFECT_MOVE : 0);
- if(*pdwEffect == 0)
- {
- // No modifier keys used by user while dragging.
- if (DROPEFFECT_COPY & dwOKEffects)
- *pdwEffect = DROPEFFECT_COPY;
- else if (DROPEFFECT_MOVE & dwOKEffects)
- *pdwEffect = DROPEFFECT_MOVE;
- else if (DROPEFFECT_LINK & dwOKEffects)
- *pdwEffect = DROPEFFECT_LINK;
- else
- {
- *pdwEffect = DROPEFFECT_NONE;
- }
- }
- else
- {
- // Check if the drag source application allows the drop effect desired by user.
- // The drag source specifies this in DoDragDrop
- if(!(*pdwEffect & dwOKEffects))
- *pdwEffect = DROPEFFECT_NONE;
- }
- return (DROPEFFECT_NONE == *pdwEffect)?false:true;
- }
- HRESULT STDMETHODCALLTYPE CIDropTarget::DragEnter(
- /* [unique][in] */ IDataObject __RPC_FAR *pDataObj,
- /* [in] */ DWORD grfKeyState,
- /* [in] */ POINTL pt,
- /* [out][in] */ DWORD __RPC_FAR *pdwEffect)
- {
- ATLTRACE("CIDropTarget::DragEnter\n");
- if(pDataObj == NULL) return E_INVALIDARG;
- if(m_pDropTargetHelper) {
- m_pDropTargetHelper->DragEnter(m_hTargetWnd, pDataObj, (LPPOINT)&pt, *pdwEffect);
- }
- m_pSupportedFrmt = NULL;
- for(int i =0; i<m_formatetc.size(); ++i) {
- m_bAllowDrop = pDataObj->QueryGetData(&m_formatetc[i]) == S_OK;
- if(m_bAllowDrop) {
- m_pSupportedFrmt = &m_formatetc[i];
- break;
- }
- }
- QueryDrop(grfKeyState, pdwEffect);
- return S_OK;
- }
- HRESULT STDMETHODCALLTYPE CIDropTarget::DragOver(
- /* [in] */ DWORD grfKeyState,
- /* [in] */ POINTL pt,
- /* [out][in] */ DWORD __RPC_FAR *pdwEffect)
- {
- ATLTRACE("CIDropTarget::DragOver\n");
- if(m_pDropTargetHelper)
- m_pDropTargetHelper->DragOver((LPPOINT)&pt, *pdwEffect);
- QueryDrop(grfKeyState, pdwEffect);
- return S_OK;
- }
- HRESULT STDMETHODCALLTYPE CIDropTarget::DragLeave( void)
- {
- ATLTRACE("CIDropTarget::DragLeave\n");
- if(m_pDropTargetHelper)
- m_pDropTargetHelper->DragLeave();
- m_bAllowDrop = false;
- m_pSupportedFrmt = NULL;
- return S_OK;
- }
- HRESULT STDMETHODCALLTYPE CIDropTarget::Drop(
- /* [unique][in] */ IDataObject __RPC_FAR *pDataObj,
- /* [in] */ DWORD grfKeyState, /* [in] */ POINTL pt,
- /* [out][in] */ DWORD __RPC_FAR *pdwEffect)
- {
- ATLTRACE("CIDropTarget::Drop\n");
- if (pDataObj == NULL) return E_INVALIDARG;
- if(m_pDropTargetHelper) m_pDropTargetHelper->Drop(pDataObj, (LPPOINT)&pt, *pdwEffect);
- if(QueryDrop(grfKeyState, pdwEffect)) {
- if(m_bAllowDrop && m_pSupportedFrmt != NULL) {
- STGMEDIUM medium;
- if(pDataObj->GetData(m_pSupportedFrmt, &medium) == S_OK) {
- if(OnDrop(m_pSupportedFrmt, medium, pdwEffect)) //does derive class wants us to free medium?
- ReleaseStgMedium(&medium);
- }
- }
- }
- m_bAllowDrop=false;
- *pdwEffect = DROPEFFECT_NONE;
- m_pSupportedFrmt = NULL;
- return S_OK;
- }
- }
|