2 * IEnumFORMATETC, IDataObject
4 * selecting and droping objects within the shell and/or common dialogs
6 * Copyright 1998 <juergen.schmied@metronet.de>
10 #include "wine/obj_base.h"
11 #include "wine/obj_storage.h"
12 #include "wine/obj_moniker.h"
13 #include "wine/obj_dataobject.h"
17 #include "shell32_main.h"
19 UINT32 cfShellIDList=0;
20 UINT32 cfFileGroupDesc=0;
21 UINT32 cfFileContents=0;
23 /***********************************************************************
24 * IEnumFORMATETC implementation
26 typedef struct _IEnumFORMATETC
29 ICOM_VTABLE(IEnumFORMATETC)* lpvtbl;
31 /* IEnumFORMATETC fields */
37 static HRESULT WINAPI IEnumFORMATETC_fnQueryInterface(LPUNKNOWN iface, REFIID riid, LPVOID* ppvObj);
38 static ULONG WINAPI IEnumFORMATETC_fnAddRef(LPUNKNOWN iface);
39 static ULONG WINAPI IEnumFORMATETC_fnRelease(LPUNKNOWN iface);
40 static HRESULT WINAPI IEnumFORMATETC_fnNext(LPENUMFORMATETC iface, ULONG celt, FORMATETC32* rgelt, ULONG* pceltFethed);
41 static HRESULT WINAPI IEnumFORMATETC_fnSkip(LPENUMFORMATETC iface, ULONG celt);
42 static HRESULT WINAPI IEnumFORMATETC_fnReset(LPENUMFORMATETC iface);
43 static HRESULT WINAPI IEnumFORMATETC_fnClone(LPENUMFORMATETC iface, LPENUMFORMATETC* ppenum);
45 static struct ICOM_VTABLE(IEnumFORMATETC) efvt =
48 IEnumFORMATETC_fnQueryInterface,
49 IEnumFORMATETC_fnAddRef,
50 IEnumFORMATETC_fnRelease
52 IEnumFORMATETC_fnNext,
53 IEnumFORMATETC_fnSkip,
54 IEnumFORMATETC_fnReset,
55 IEnumFORMATETC_fnClone
58 LPENUMFORMATETC IEnumFORMATETC_Constructor(UINT32 cfmt, const FORMATETC32 afmt[])
61 DWORD size=cfmt * sizeof(FORMATETC32);
63 ef=(_IEnumFORMATETC*)HeapAlloc(GetProcessHeap(),0,sizeof(_IEnumFORMATETC));
69 ef->pFmt = SHAlloc (size);
72 { memcpy(ef->pFmt, afmt, size);
75 TRACE(shell,"(%p)->()\n",ef);
77 return (LPENUMFORMATETC)ef;
79 static HRESULT WINAPI IEnumFORMATETC_fnQueryInterface(LPUNKNOWN iface, REFIID riid, LPVOID* ppvObj)
81 ICOM_THIS(IEnumFORMATETC,iface);
83 WINE_StringFromCLSID((LPCLSID)riid,xriid);
84 TRACE(shell,"(%p)->(\n\tIID:\t%s,%p)\n",this,xriid,ppvObj);
88 if(IsEqualIID(riid, &IID_IUnknown))
91 else if(IsEqualIID(riid, &IID_IEnumFORMATETC))
92 { *ppvObj = (IDataObject*)this;
96 { IEnumFORMATETC_AddRef((IEnumFORMATETC*)*ppvObj);
97 TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
100 TRACE(shell,"-- Interface: E_NOINTERFACE\n");
101 return E_NOINTERFACE;
104 static ULONG WINAPI IEnumFORMATETC_fnAddRef(LPUNKNOWN iface)
106 ICOM_THIS(IEnumFORMATETC,iface);
107 TRACE(shell,"(%p)->(count=%lu)\n",this,(this->ref)+1);
109 return ++(this->ref);
111 static ULONG WINAPI IEnumFORMATETC_fnRelease(LPUNKNOWN iface)
113 ICOM_THIS(IEnumFORMATETC,iface);
114 TRACE(shell,"(%p)->()\n",this);
119 { TRACE(shell," destroying IEnumFORMATETC(%p)\n",this);
121 { SHFree (this->pFmt);
123 HeapFree(GetProcessHeap(),0,this);
128 static HRESULT WINAPI IEnumFORMATETC_fnNext(LPENUMFORMATETC iface, ULONG celt, FORMATETC32 *rgelt, ULONG *pceltFethed)
130 ICOM_THIS(IEnumFORMATETC,iface);
132 HRESULT hres = S_FALSE;
134 TRACE (shell, "(%p)->()\n", this);
136 if (this->posFmt < this->countFmt)
137 { cfetch = this->countFmt - this->posFmt;
142 memcpy(rgelt, &this->pFmt[this->posFmt], cfetch * sizeof(FORMATETC32));
143 this->posFmt += cfetch;
150 { *pceltFethed = cfetch;
155 static HRESULT WINAPI IEnumFORMATETC_fnSkip(LPENUMFORMATETC iface, ULONG celt)
157 ICOM_THIS(IEnumFORMATETC,iface);
158 FIXME (shell, "(%p)->(num=%lu)\n", this, celt);
160 this->posFmt += celt;
161 if (this->posFmt > this->countFmt)
162 { this->posFmt = this->countFmt;
167 static HRESULT WINAPI IEnumFORMATETC_fnReset(LPENUMFORMATETC iface)
169 ICOM_THIS(IEnumFORMATETC,iface);
170 FIXME (shell, "(%p)->()\n", this);
175 static HRESULT WINAPI IEnumFORMATETC_fnClone(LPENUMFORMATETC iface, LPENUMFORMATETC* ppenum)
177 ICOM_THIS(IEnumFORMATETC,iface);
178 FIXME (shell, "(%p)->(ppenum=%p)\n", this, ppenum);
182 /***********************************************************************
183 * IDataObject implementation
185 typedef struct _IDataObject
187 /* IUnknown fields */
188 ICOM_VTABLE(IDataObject)* lpvtbl;
190 /* IDataObject fields */
192 LPIDLLIST lpill; /* the data of the dataobject */
196 static HRESULT WINAPI IDataObject_fnQueryInterface(LPUNKNOWN iface, REFIID riid, LPVOID* ppvObj);
197 static ULONG WINAPI IDataObject_fnAddRef(LPUNKNOWN iface);
198 static ULONG WINAPI IDataObject_fnRelease(LPUNKNOWN iface);
199 static HRESULT WINAPI IDataObject_fnGetData(LPDATAOBJECT iface, LPFORMATETC32 pformatetcIn, STGMEDIUM32* pmedium);
200 static HRESULT WINAPI IDataObject_fnGetDataHere(LPDATAOBJECT iface, LPFORMATETC32 pformatetc, STGMEDIUM32* pmedium);
201 static HRESULT WINAPI IDataObject_fnQueryGetData(LPDATAOBJECT iface, LPFORMATETC32 pformatetc);
202 static HRESULT WINAPI IDataObject_fnGetCanonicalFormatEtc(LPDATAOBJECT iface, LPFORMATETC32 pformatectIn, LPFORMATETC32 pformatetcOut);
203 static HRESULT WINAPI IDataObject_fnSetData(LPDATAOBJECT iface, LPFORMATETC32 pformatetc, STGMEDIUM32* pmedium, BOOL32 fRelease);
204 static HRESULT WINAPI IDataObject_fnEnumFormatEtc(LPDATAOBJECT iface, DWORD dwDirection, IEnumFORMATETC** ppenumFormatEtc);
205 static HRESULT WINAPI IDataObject_fnDAdvise(LPDATAOBJECT iface, LPFORMATETC32* pformatetc, DWORD advf, IAdviseSink* pAdvSink, DWORD* pdwConnection);
206 static HRESULT WINAPI IDataObject_fnDUnadvise(LPDATAOBJECT iface, DWORD dwConnection);
207 static HRESULT WINAPI IDataObject_fnEnumDAdvise(LPDATAOBJECT iface, IEnumSTATDATA **ppenumAdvise);
209 static struct ICOM_VTABLE(IDataObject) dtovt =
212 IDataObject_fnQueryInterface,
213 IDataObject_fnAddRef,
214 IDataObject_fnRelease
216 IDataObject_fnGetData,
217 IDataObject_fnGetDataHere,
218 IDataObject_fnQueryGetData,
219 IDataObject_fnGetCanonicalFormatEtc,
220 IDataObject_fnSetData,
221 IDataObject_fnEnumFormatEtc,
222 IDataObject_fnDAdvise,
223 IDataObject_fnDUnadvise,
224 IDataObject_fnEnumDAdvise
227 /**************************************************************************
228 * IDataObject_Constructor
230 LPDATAOBJECT IDataObject_Constructor(HWND32 hwndOwner, LPSHELLFOLDER psf, LPITEMIDLIST * apidl, UINT32 cidl)
233 if (!(dto = (_IDataObject*)HeapAlloc(GetProcessHeap(),0,sizeof(_IDataObject))))
239 dto->pidl=ILClone(psf->mpidl); /* FIXME:add a reference and don't copy*/
241 /* fill the ItemID List List */
242 dto->lpill = IDLList_Constructor (8);
246 dto->lpill->lpvtbl->fnAddItems(dto->lpill, apidl, cidl);
248 TRACE(shell,"(%p)->(sf=%p apidl=%p cidl=%u)\n",dto, psf, apidl, cidl);
250 return (LPDATAOBJECT)dto;
252 /***************************************************************************
253 * IDataObject_QueryInterface
255 static HRESULT WINAPI IDataObject_fnQueryInterface (LPUNKNOWN iface, REFIID riid, LPVOID * ppvObj)
257 ICOM_THIS(IDataObject,iface);
259 WINE_StringFromCLSID((LPCLSID)riid,xriid);
260 TRACE(shell,"(%p)->(\n\tIID:\t%s,%p)\n",this,xriid,ppvObj);
264 if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/
267 else if(IsEqualIID(riid, &IID_IDataObject)) /*IDataObject*/
268 { *ppvObj = (IDataObject*)this;
272 { IDataObject_AddRef((IDataObject*)*ppvObj);
273 TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
276 TRACE(shell,"-- Interface: E_NOINTERFACE\n");
277 return E_NOINTERFACE;
279 /**************************************************************************
282 static ULONG WINAPI IDataObject_fnAddRef(LPUNKNOWN iface)
284 ICOM_THIS(IDataObject,iface);
286 TRACE(shell,"(%p)->(count=%lu)\n",this,(this->ref)+1);
289 return ++(this->ref);
291 /**************************************************************************
292 * IDataObject_Release
294 static ULONG WINAPI IDataObject_fnRelease(LPUNKNOWN iface)
296 ICOM_THIS(IDataObject,iface);
297 TRACE(shell,"(%p)->()\n",this);
302 { TRACE(shell," destroying IDataObject(%p)\n",this);
303 IDLList_Destructor(this->lpill);
304 HeapFree(GetProcessHeap(),0,this);
309 /**************************************************************************
310 * DATAOBJECT_InitShellIDList (internal)
313 * get or register the "Shell IDList Array" clipformat
315 static BOOL32 DATAOBJECT_InitShellIDList(void)
320 cfShellIDList = RegisterClipboardFormat32A(CFSTR_SHELLIDLIST);
321 return(cfShellIDList != 0);
324 /**************************************************************************
325 * DATAOBJECT_InitFileGroupDesc (internal)
328 * get or register the "FileGroupDescriptor" clipformat
330 /* FIXME: DATAOBJECT_InitFileGroupDesc is not used (19981226)
331 static BOOL32 DATAOBJECT_InitFileGroupDesc(void)
332 { if (cfFileGroupDesc)
336 cfFileGroupDesc = RegisterClipboardFormat32A(CFSTR_FILEDESCRIPTORA);
337 return(cfFileGroupDesc != 0);
340 /**************************************************************************
341 * DATAOBJECT_InitFileContents (internal)
344 * get or register the "FileContents" clipformat
346 /* FIXME: DATAOBJECT_InitFileContents is not used (19981226)
347 static BOOL32 DATAOBJECT_InitFileContents(void)
348 { if (cfFileContents)
352 cfFileContents = RegisterClipboardFormat32A(CFSTR_FILECONTENTS);
353 return(cfFileContents != 0);
357 /**************************************************************************
358 * interface implementation
360 static HRESULT WINAPI IDataObject_fnGetData(LPDATAOBJECT iface, LPFORMATETC32 pformatetcIn, STGMEDIUM32 *pmedium)
362 ICOM_THIS(IDataObject,iface);
365 DWORD size, size1, size2;
370 GetClipboardFormatName32A (pformatetcIn->cfFormat, temp, 256);
371 WARN (shell, "(%p)->(%p %p format=%s)semi-stub\n", this, pformatetcIn, pmedium, temp);
373 if (!DATAOBJECT_InitShellIDList()) /* is the clipformat registred? */
374 { return(E_UNEXPECTED);
377 if (pformatetcIn->cfFormat == cfShellIDList)
378 { if (pformatetcIn->ptd==NULL
379 && (pformatetcIn->dwAspect & DVASPECT_CONTENT)
380 && pformatetcIn->lindex==-1
381 && (pformatetcIn->tymed&TYMED_HGLOBAL))
382 { cItems = this->lpill->lpvtbl->fnGetCount(this->lpill);
384 { return(E_UNEXPECTED);
386 pidl = this->lpill->lpvtbl->fnGetElement(this->lpill, 0);
391 /*hack consider only the first item*/
393 size = sizeof(CIDA) + sizeof (UINT32)*(cItems-1);
394 size1 = ILGetSize (this->pidl);
395 size2 = ILGetSize (pidl);
396 hmem = GlobalAlloc32(GMEM_FIXED, size+size1+size2);
397 pcida = GlobalLock32 (hmem);
399 { return(E_OUTOFMEMORY);
403 pcida->aoffset[0] = size;
404 pcida->aoffset[1] = size+size1;
406 TRACE(shell,"-- %lu %lu %lu\n",size, size1, size2 );
407 TRACE(shell,"-- %p %p\n",this->pidl, pidl);
408 TRACE(shell,"-- %p %p %p\n",pcida, (LPBYTE)pcida+size,(LPBYTE)pcida+size+size1);
410 memcpy ((LPBYTE)pcida+size, this->pidl, size1);
411 memcpy ((LPBYTE)pcida+size+size1, pidl, size2);
412 TRACE(shell,"-- after copy\n");
414 GlobalUnlock32(hmem);
416 pmedium->tymed = TYMED_HGLOBAL;
417 pmedium->u.hGlobal = (HGLOBAL32)pcida;
418 pmedium->pUnkForRelease = NULL;
419 TRACE(shell,"-- ready\n");
423 FIXME (shell, "-- clipformat not implemented\n");
424 return (E_INVALIDARG);
426 static HRESULT WINAPI IDataObject_fnGetDataHere(LPDATAOBJECT iface, LPFORMATETC32 pformatetc, STGMEDIUM32 *pmedium)
428 ICOM_THIS(IDataObject,iface);
429 FIXME (shell, "(%p)->()\n", this);
432 static HRESULT WINAPI IDataObject_fnQueryGetData(LPDATAOBJECT iface, LPFORMATETC32 pformatetc)
434 ICOM_THIS(IDataObject,iface);
435 FIXME (shell, "(%p)->()\n", this);
438 static HRESULT WINAPI IDataObject_fnGetCanonicalFormatEtc(LPDATAOBJECT iface, LPFORMATETC32 pformatectIn, LPFORMATETC32 pformatetcOut)
440 ICOM_THIS(IDataObject,iface);
441 FIXME (shell, "(%p)->()\n", this);
444 static HRESULT WINAPI IDataObject_fnSetData(LPDATAOBJECT iface, LPFORMATETC32 pformatetc, STGMEDIUM32 *pmedium, BOOL32 fRelease)
446 ICOM_THIS(IDataObject,iface);
447 FIXME (shell, "(%p)->()\n", this);
450 static HRESULT WINAPI IDataObject_fnEnumFormatEtc(LPDATAOBJECT iface, DWORD dwDirection, IEnumFORMATETC **ppenumFormatEtc)
452 ICOM_THIS(IDataObject,iface);
453 FIXME (shell, "(%p)->()\n", this);
456 static HRESULT WINAPI IDataObject_fnDAdvise(LPDATAOBJECT iface, LPFORMATETC32 *pformatetc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection)
458 ICOM_THIS(IDataObject,iface);
459 FIXME (shell, "(%p)->()\n", this);
462 static HRESULT WINAPI IDataObject_fnDUnadvise(LPDATAOBJECT iface, DWORD dwConnection)
464 ICOM_THIS(IDataObject,iface);
465 FIXME (shell, "(%p)->()\n", this);
468 static HRESULT WINAPI IDataObject_fnEnumDAdvise(LPDATAOBJECT iface, IEnumSTATDATA **ppenumAdvise)
470 ICOM_THIS(IDataObject,iface);
471 FIXME (shell, "(%p)->()\n", this);