2 * IEnumFORMATETC, IDataObject
4 * selecting and droping objects within the shell and/or common dialogs
6 * Copyright 1998 <juergen.schmied@metronet.de>
13 #include "shell32_main.h"
16 DEFAULT_DEBUG_CHANNEL(shell
)
19 UINT cfFileGroupDesc
=0;
20 UINT cfFileContents
=0;
22 /***********************************************************************
23 * IEnumFORMATETC implementation
28 ICOM_VTABLE(IEnumFORMATETC
)* lpvtbl
;
30 /* IEnumFORMATETC fields */
36 static HRESULT WINAPI
IEnumFORMATETC_fnQueryInterface(LPENUMFORMATETC iface
, REFIID riid
, LPVOID
* ppvObj
);
37 static ULONG WINAPI
IEnumFORMATETC_fnAddRef(LPENUMFORMATETC iface
);
38 static ULONG WINAPI
IEnumFORMATETC_fnRelease(LPENUMFORMATETC iface
);
39 static HRESULT WINAPI
IEnumFORMATETC_fnNext(LPENUMFORMATETC iface
, ULONG celt
, FORMATETC
* rgelt
, ULONG
* pceltFethed
);
40 static HRESULT WINAPI
IEnumFORMATETC_fnSkip(LPENUMFORMATETC iface
, ULONG celt
);
41 static HRESULT WINAPI
IEnumFORMATETC_fnReset(LPENUMFORMATETC iface
);
42 static HRESULT WINAPI
IEnumFORMATETC_fnClone(LPENUMFORMATETC iface
, LPENUMFORMATETC
* ppenum
);
44 static struct ICOM_VTABLE(IEnumFORMATETC
) efvt
=
46 IEnumFORMATETC_fnQueryInterface
,
47 IEnumFORMATETC_fnAddRef
,
48 IEnumFORMATETC_fnRelease
,
49 IEnumFORMATETC_fnNext
,
50 IEnumFORMATETC_fnSkip
,
51 IEnumFORMATETC_fnReset
,
52 IEnumFORMATETC_fnClone
55 LPENUMFORMATETC
IEnumFORMATETC_Constructor(UINT cfmt
, const FORMATETC afmt
[])
57 IEnumFORMATETCImpl
* ef
;
58 DWORD size
=cfmt
* sizeof(FORMATETC
);
60 ef
=(IEnumFORMATETCImpl
*)HeapAlloc(GetProcessHeap(),0,sizeof(IEnumFORMATETCImpl
));
66 ef
->pFmt
= SHAlloc (size
);
69 { memcpy(ef
->pFmt
, afmt
, size
);
72 TRACE(shell
,"(%p)->()\n",ef
);
74 return (LPENUMFORMATETC
)ef
;
76 static HRESULT WINAPI
IEnumFORMATETC_fnQueryInterface(LPENUMFORMATETC iface
, REFIID riid
, LPVOID
* ppvObj
)
78 ICOM_THIS(IEnumFORMATETCImpl
,iface
);
80 WINE_StringFromCLSID((LPCLSID
)riid
,xriid
);
81 TRACE(shell
,"(%p)->(\n\tIID:\t%s,%p)\n",This
,xriid
,ppvObj
);
85 if(IsEqualIID(riid
, &IID_IUnknown
))
88 else if(IsEqualIID(riid
, &IID_IEnumFORMATETC
))
89 { *ppvObj
= (IDataObject
*)This
;
93 { IEnumFORMATETC_AddRef((IEnumFORMATETC
*)*ppvObj
);
94 TRACE(shell
,"-- Interface: (%p)->(%p)\n",ppvObj
,*ppvObj
);
97 TRACE(shell
,"-- Interface: E_NOINTERFACE\n");
101 static ULONG WINAPI
IEnumFORMATETC_fnAddRef(LPENUMFORMATETC iface
)
103 ICOM_THIS(IEnumFORMATETCImpl
,iface
);
104 TRACE(shell
,"(%p)->(count=%lu)\n",This
, This
->ref
);
106 return ++(This
->ref
);
108 static ULONG WINAPI
IEnumFORMATETC_fnRelease(LPENUMFORMATETC iface
)
110 ICOM_THIS(IEnumFORMATETCImpl
,iface
);
111 TRACE(shell
,"(%p)->()\n",This
);
116 { TRACE(shell
," destroying IEnumFORMATETC(%p)\n",This
);
118 { SHFree (This
->pFmt
);
120 HeapFree(GetProcessHeap(),0,This
);
125 static HRESULT WINAPI
IEnumFORMATETC_fnNext(LPENUMFORMATETC iface
, ULONG celt
, FORMATETC
*rgelt
, ULONG
*pceltFethed
)
127 ICOM_THIS(IEnumFORMATETCImpl
,iface
);
129 HRESULT hres
= S_FALSE
;
131 TRACE (shell
, "(%p)->()\n", This
);
133 if (This
->posFmt
< This
->countFmt
)
134 { cfetch
= This
->countFmt
- This
->posFmt
;
139 memcpy(rgelt
, &This
->pFmt
[This
->posFmt
], cfetch
* sizeof(FORMATETC
));
140 This
->posFmt
+= cfetch
;
147 { *pceltFethed
= cfetch
;
152 static HRESULT WINAPI
IEnumFORMATETC_fnSkip(LPENUMFORMATETC iface
, ULONG celt
)
154 ICOM_THIS(IEnumFORMATETCImpl
,iface
);
155 FIXME (shell
, "(%p)->(num=%lu)\n", This
, celt
);
157 This
->posFmt
+= celt
;
158 if (This
->posFmt
> This
->countFmt
)
159 { This
->posFmt
= This
->countFmt
;
164 static HRESULT WINAPI
IEnumFORMATETC_fnReset(LPENUMFORMATETC iface
)
166 ICOM_THIS(IEnumFORMATETCImpl
,iface
);
167 FIXME (shell
, "(%p)->()\n", This
);
172 static HRESULT WINAPI
IEnumFORMATETC_fnClone(LPENUMFORMATETC iface
, LPENUMFORMATETC
* ppenum
)
174 ICOM_THIS(IEnumFORMATETCImpl
,iface
);
175 FIXME (shell
, "(%p)->(ppenum=%p)\n", This
, ppenum
);
179 /***********************************************************************
180 * IDataObject implementation
185 /* IUnknown fields */
186 ICOM_VTABLE(IDataObject
)* lpvtbl
;
188 /* IDataObject fields */
190 LPIDLLIST lpill
; /* the data of the dataobject */
194 static HRESULT WINAPI
IDataObject_fnQueryInterface(LPDATAOBJECT iface
, REFIID riid
, LPVOID
* ppvObj
);
195 static ULONG WINAPI
IDataObject_fnAddRef(LPDATAOBJECT iface
);
196 static ULONG WINAPI
IDataObject_fnRelease(LPDATAOBJECT iface
);
197 static HRESULT WINAPI
IDataObject_fnGetData(LPDATAOBJECT iface
, LPFORMATETC pformatetcIn
, STGMEDIUM
* pmedium
);
198 static HRESULT WINAPI
IDataObject_fnGetDataHere(LPDATAOBJECT iface
, LPFORMATETC pformatetc
, STGMEDIUM
* pmedium
);
199 static HRESULT WINAPI
IDataObject_fnQueryGetData(LPDATAOBJECT iface
, LPFORMATETC pformatetc
);
200 static HRESULT WINAPI
IDataObject_fnGetCanonicalFormatEtc(LPDATAOBJECT iface
, LPFORMATETC pformatectIn
, LPFORMATETC pformatetcOut
);
201 static HRESULT WINAPI
IDataObject_fnSetData(LPDATAOBJECT iface
, LPFORMATETC pformatetc
, STGMEDIUM
* pmedium
, BOOL fRelease
);
202 static HRESULT WINAPI
IDataObject_fnEnumFormatEtc(LPDATAOBJECT iface
, DWORD dwDirection
, IEnumFORMATETC
** ppenumFormatEtc
);
203 static HRESULT WINAPI
IDataObject_fnDAdvise(LPDATAOBJECT iface
, FORMATETC
* pformatetc
, DWORD advf
, IAdviseSink
* pAdvSink
, DWORD
* pdwConnection
);
204 static HRESULT WINAPI
IDataObject_fnDUnadvise(LPDATAOBJECT iface
, DWORD dwConnection
);
205 static HRESULT WINAPI
IDataObject_fnEnumDAdvise(LPDATAOBJECT iface
, IEnumSTATDATA
**ppenumAdvise
);
207 static struct ICOM_VTABLE(IDataObject
) dtovt
=
209 IDataObject_fnQueryInterface
,
210 IDataObject_fnAddRef
,
211 IDataObject_fnRelease
,
212 IDataObject_fnGetData
,
213 IDataObject_fnGetDataHere
,
214 IDataObject_fnQueryGetData
,
215 IDataObject_fnGetCanonicalFormatEtc
,
216 IDataObject_fnSetData
,
217 IDataObject_fnEnumFormatEtc
,
218 IDataObject_fnDAdvise
,
219 IDataObject_fnDUnadvise
,
220 IDataObject_fnEnumDAdvise
223 /**************************************************************************
224 * IDataObject_Constructor
226 LPDATAOBJECT
IDataObject_Constructor(HWND hwndOwner
, LPSHELLFOLDER psf
, LPITEMIDLIST
* apidl
, UINT cidl
)
228 IDataObjectImpl
* dto
;
229 if (!(dto
= (IDataObjectImpl
*)HeapAlloc(GetProcessHeap(),0,sizeof(IDataObjectImpl
))))
235 dto
->pidl
=ILClone(((IGenericSFImpl
*)psf
)->pMyPidl
); /* FIXME:add a reference and don't copy*/
237 /* fill the ItemID List List */
238 dto
->lpill
= IDLList_Constructor (8);
242 dto
->lpill
->lpvtbl
->fnAddItems(dto
->lpill
, apidl
, cidl
);
244 TRACE(shell
,"(%p)->(sf=%p apidl=%p cidl=%u)\n",dto
, psf
, apidl
, cidl
);
246 return (LPDATAOBJECT
)dto
;
248 /***************************************************************************
249 * IDataObject_QueryInterface
251 static HRESULT WINAPI
IDataObject_fnQueryInterface(LPDATAOBJECT iface
, REFIID riid
, LPVOID
* ppvObj
)
253 ICOM_THIS(IDataObjectImpl
,iface
);
255 WINE_StringFromCLSID((LPCLSID
)riid
,xriid
);
256 TRACE(shell
,"(%p)->(\n\tIID:\t%s,%p)\n",This
,xriid
,ppvObj
);
260 if(IsEqualIID(riid
, &IID_IUnknown
)) /*IUnknown*/
263 else if(IsEqualIID(riid
, &IID_IDataObject
)) /*IDataObject*/
264 { *ppvObj
= (IDataObject
*)This
;
268 { IDataObject_AddRef((IDataObject
*)*ppvObj
);
269 TRACE(shell
,"-- Interface: (%p)->(%p)\n",ppvObj
,*ppvObj
);
272 TRACE(shell
,"-- Interface: E_NOINTERFACE\n");
273 return E_NOINTERFACE
;
275 /**************************************************************************
278 static ULONG WINAPI
IDataObject_fnAddRef(LPDATAOBJECT iface
)
280 ICOM_THIS(IDataObjectImpl
,iface
);
282 TRACE(shell
,"(%p)->(count=%lu)\n",This
, This
->ref
);
285 return ++(This
->ref
);
287 /**************************************************************************
288 * IDataObject_Release
290 static ULONG WINAPI
IDataObject_fnRelease(LPDATAOBJECT iface
)
292 ICOM_THIS(IDataObjectImpl
,iface
);
293 TRACE(shell
,"(%p)->()\n",This
);
298 { TRACE(shell
," destroying IDataObject(%p)\n",This
);
299 IDLList_Destructor(This
->lpill
);
300 HeapFree(GetProcessHeap(),0,This
);
305 /**************************************************************************
306 * DATAOBJECT_InitShellIDList (internal)
309 * get or register the "Shell IDList Array" clipformat
311 static BOOL
DATAOBJECT_InitShellIDList(void)
316 cfShellIDList
= RegisterClipboardFormatA(CFSTR_SHELLIDLIST
);
317 return(cfShellIDList
!= 0);
320 /**************************************************************************
321 * DATAOBJECT_InitFileGroupDesc (internal)
324 * get or register the "FileGroupDescriptor" clipformat
326 /* FIXME: DATAOBJECT_InitFileGroupDesc is not used (19981226)
327 static BOOL32 DATAOBJECT_InitFileGroupDesc(void)
328 { if (cfFileGroupDesc)
332 cfFileGroupDesc = RegisterClipboardFormatA(CFSTR_FILEDESCRIPTORA);
333 return(cfFileGroupDesc != 0);
336 /**************************************************************************
337 * DATAOBJECT_InitFileContents (internal)
340 * get or register the "FileContents" clipformat
342 /* FIXME: DATAOBJECT_InitFileContents is not used (19981226)
343 static BOOL32 DATAOBJECT_InitFileContents(void)
344 { if (cfFileContents)
348 cfFileContents = RegisterClipboardFormatA(CFSTR_FILECONTENTS);
349 return(cfFileContents != 0);
353 /**************************************************************************
354 * interface implementation
356 static HRESULT WINAPI
IDataObject_fnGetData(LPDATAOBJECT iface
, LPFORMATETC pformatetcIn
, STGMEDIUM
*pmedium
)
358 ICOM_THIS(IDataObjectImpl
,iface
);
361 DWORD size
, size1
, size2
;
366 GetClipboardFormatNameA (pformatetcIn
->cfFormat
, temp
, 256);
367 WARN (shell
, "(%p)->(%p %p format=%s)semi-stub\n", This
, pformatetcIn
, pmedium
, temp
);
369 if (!DATAOBJECT_InitShellIDList()) /* is the clipformat registred? */
370 { return(E_UNEXPECTED
);
373 if (pformatetcIn
->cfFormat
== cfShellIDList
)
374 { if (pformatetcIn
->ptd
==NULL
375 && (pformatetcIn
->dwAspect
& DVASPECT_CONTENT
)
376 && pformatetcIn
->lindex
==-1
377 && (pformatetcIn
->tymed
&TYMED_HGLOBAL
))
378 { cItems
= This
->lpill
->lpvtbl
->fnGetCount(This
->lpill
);
380 { return(E_UNEXPECTED
);
382 pidl
= This
->lpill
->lpvtbl
->fnGetElement(This
->lpill
, 0);
387 /*hack consider only the first item*/
389 size
= sizeof(CIDA
) + sizeof (UINT
)*(cItems
-1);
390 size1
= ILGetSize (This
->pidl
);
391 size2
= ILGetSize (pidl
);
392 hmem
= GlobalAlloc(GMEM_FIXED
, size
+size1
+size2
);
393 pcida
= GlobalLock (hmem
);
395 { return(E_OUTOFMEMORY
);
399 pcida
->aoffset
[0] = size
;
400 pcida
->aoffset
[1] = size
+size1
;
402 TRACE(shell
,"-- %lu %lu %lu\n",size
, size1
, size2
);
403 TRACE(shell
,"-- %p %p\n",This
->pidl
, pidl
);
404 TRACE(shell
,"-- %p %p %p\n",pcida
, (LPBYTE
)pcida
+size
,(LPBYTE
)pcida
+size
+size1
);
406 memcpy ((LPBYTE
)pcida
+size
, This
->pidl
, size1
);
407 memcpy ((LPBYTE
)pcida
+size
+size1
, pidl
, size2
);
408 TRACE(shell
,"-- after copy\n");
412 pmedium
->tymed
= TYMED_HGLOBAL
;
413 pmedium
->u
.hGlobal
= (HGLOBAL
)pcida
;
414 pmedium
->pUnkForRelease
= NULL
;
415 TRACE(shell
,"-- ready\n");
419 FIXME (shell
, "-- clipformat not implemented\n");
420 return (E_INVALIDARG
);
422 static HRESULT WINAPI
IDataObject_fnGetDataHere(LPDATAOBJECT iface
, LPFORMATETC pformatetc
, STGMEDIUM
*pmedium
)
424 ICOM_THIS(IDataObjectImpl
,iface
);
425 FIXME (shell
, "(%p)->()\n", This
);
428 static HRESULT WINAPI
IDataObject_fnQueryGetData(LPDATAOBJECT iface
, LPFORMATETC pformatetc
)
430 ICOM_THIS(IDataObjectImpl
,iface
);
431 FIXME (shell
, "(%p)->()\n", This
);
434 static HRESULT WINAPI
IDataObject_fnGetCanonicalFormatEtc(LPDATAOBJECT iface
, LPFORMATETC pformatectIn
, LPFORMATETC pformatetcOut
)
436 ICOM_THIS(IDataObjectImpl
,iface
);
437 FIXME (shell
, "(%p)->()\n", This
);
440 static HRESULT WINAPI
IDataObject_fnSetData(LPDATAOBJECT iface
, LPFORMATETC pformatetc
, STGMEDIUM
*pmedium
, BOOL fRelease
)
442 ICOM_THIS(IDataObjectImpl
,iface
);
443 FIXME (shell
, "(%p)->()\n", This
);
446 static HRESULT WINAPI
IDataObject_fnEnumFormatEtc(LPDATAOBJECT iface
, DWORD dwDirection
, IEnumFORMATETC
**ppenumFormatEtc
)
448 ICOM_THIS(IDataObjectImpl
,iface
);
449 FIXME (shell
, "(%p)->()\n", This
);
452 static HRESULT WINAPI
IDataObject_fnDAdvise(LPDATAOBJECT iface
, FORMATETC
*pformatetc
, DWORD advf
, IAdviseSink
*pAdvSink
, DWORD
*pdwConnection
)
454 ICOM_THIS(IDataObjectImpl
,iface
);
455 FIXME (shell
, "(%p)->()\n", This
);
458 static HRESULT WINAPI
IDataObject_fnDUnadvise(LPDATAOBJECT iface
, DWORD dwConnection
)
460 ICOM_THIS(IDataObjectImpl
,iface
);
461 FIXME (shell
, "(%p)->()\n", This
);
464 static HRESULT WINAPI
IDataObject_fnEnumDAdvise(LPDATAOBJECT iface
, IEnumSTATDATA
**ppenumAdvise
)
466 ICOM_THIS(IDataObjectImpl
,iface
);
467 FIXME (shell
, "(%p)->()\n", This
);