2 * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
11 #define WIN32_LEAN_AND_MEAN
13 #undef WIN32_LEAN_AND_MEAN
16 #include "Ecore_Win32.h"
17 #include "ecore_win32_private.h"
19 #include "ecore_win32_dnd_enumformatetc.h"
20 #include "ecore_win32_dnd_data_object.h"
23 static HGLOBAL DupGlobalMem(HGLOBAL hMem)
25 DWORD len = (DWORD)GlobalSize(hMem);
26 PVOID source = GlobalLock(hMem);
27 PVOID dest = GlobalAlloc(GMEM_FIXED, len);
28 memcpy(dest, source, len);
35 DataObject::DataObject(FORMATETC *fmtetc, STGMEDIUM *stgmed, int count)
37 assert(fmtetc != NULL);
38 assert(stgmed != NULL);
41 // reference count must ALWAYS start at 1
45 format_etc_ = new FORMATETC[count];
46 stg_medium_ = new STGMEDIUM[count];
48 for(int i = 0; i < count; i++)
50 format_etc_[i] = fmtetc[i];
51 stg_medium_[i] = stgmed[i];
55 DataObject::~DataObject()
64 HRESULT DataObject::QueryInterface(REFIID iid, void **ppvObject)
66 // check to see what interface has been requested
67 if ((iid == IID_IDataObject) || (iid == IID_IUnknown))
77 ULONG DataObject::AddRef()
79 return InterlockedIncrement(&ref_count_);
82 ULONG DataObject::Release()
84 LONG count = InterlockedDecrement(&ref_count_);
95 HRESULT DataObject::GetData(FORMATETC *pFormatEtc, STGMEDIUM *pMedium)
97 assert(pMedium != NULL);
100 // try to match the specified FORMATETC with one of our supported formats
101 if((idx = lookup_format_etc(pFormatEtc)) == -1)
102 return DV_E_FORMATETC;
104 // found a match - transfer data into supplied storage medium
105 pMedium->tymed = format_etc_[idx].tymed;
106 pMedium->pUnkForRelease = 0;
108 // copy the data into the caller's storage medium
109 switch(format_etc_[idx].tymed)
112 pMedium->hGlobal = DupGlobalMem(stg_medium_[idx].hGlobal);
116 return DV_E_FORMATETC;
122 HRESULT DataObject::GetDataHere(FORMATETC *pFormatEtc, STGMEDIUM *pmedium)
124 return DATA_E_FORMATETC;
127 HRESULT DataObject::QueryGetData(FORMATETC *pFormatEtc)
129 return (lookup_format_etc(pFormatEtc) == -1) ? DV_E_FORMATETC : S_OK;
132 HRESULT DataObject::GetCanonicalFormatEtc(FORMATETC *pFormatEct, FORMATETC *pFormatEtcOut)
134 // Apparently we have to set this field to NULL even though we don't do anything else
135 pFormatEtcOut->ptd = NULL;
139 HRESULT DataObject::SetData(FORMATETC *pFormatEtc, STGMEDIUM *pMedium, BOOL fRelease)
144 HRESULT DataObject::EnumFormatEtc(DWORD dwDirection, IEnumFORMATETC **ppEnumFormatEtc)
146 // only the get direction is supported for OLE
147 if(dwDirection == DATADIR_GET)
149 // for Win2k+ you can use the SHCreateStdEnumFmtEtc API call, however
150 // to support all Windows platforms we need to implement IEnumFormatEtc ourselves.
151 return CreateEnumFormatEtc(formats_num_, format_etc_, ppEnumFormatEtc);
155 // the direction specified is not supported for drag+drop
160 HRESULT DataObject::DAdvise(FORMATETC *pFormatEtc, DWORD advf, IAdviseSink *, DWORD *)
162 return OLE_E_ADVISENOTSUPPORTED;
165 HRESULT DataObject::DUnadvise(DWORD dwConnection)
167 return OLE_E_ADVISENOTSUPPORTED;
170 HRESULT DataObject::EnumDAdvise(IEnumSTATDATA **ppEnumAdvise)
172 return OLE_E_ADVISENOTSUPPORTED;
175 // internal helper function
177 int DataObject::lookup_format_etc(FORMATETC *pFormatEtc)
179 // check each of our formats in turn to see if one matches
180 for(int i = 0; i < formats_num_; i++)
182 if((format_etc_[i].tymed & pFormatEtc->tymed) &&
183 (format_etc_[i].cfFormat == pFormatEtc->cfFormat) &&
184 (format_etc_[i].dwAspect == pFormatEtc->dwAspect))
186 // return index of stored format
191 // error, format not found
195 void *_ecore_win32_dnd_data_object_new(void *fmtetc, void *stgmeds, int count)
197 IDataObject *object = new DataObject((FORMATETC *)fmtetc, (STGMEDIUM *)stgmeds, (UINT)count);
198 assert(object != NULL);
202 void _ecore_win32_dnd_data_object_free(void *data_object)
207 IDataObject *object = (IDataObject *)data_object;