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
);
76 return (LPENUMFORMATETC
)ef
;
78 static HRESULT WINAPI
IEnumFORMATETC_fnQueryInterface(LPUNKNOWN iface
, REFIID riid
, LPVOID
* ppvObj
)
80 ICOM_THIS(IEnumFORMATETC
,iface
);
82 WINE_StringFromCLSID((LPCLSID
)riid
,xriid
);
83 TRACE(shell
,"(%p)->(\n\tIID:\t%s,%p)\n",this,xriid
,ppvObj
);
87 if(IsEqualIID(riid
, &IID_IUnknown
))
90 else if(IsEqualIID(riid
, &IID_IEnumFORMATETC
))
91 { *ppvObj
= (IDataObject
*)this;
95 { IEnumFORMATETC_AddRef((IEnumFORMATETC
*)*ppvObj
);
96 TRACE(shell
,"-- Interface: (%p)->(%p)\n",ppvObj
,*ppvObj
);
99 TRACE(shell
,"-- Interface: E_NOINTERFACE\n");
100 return E_NOINTERFACE
;
103 static ULONG WINAPI
IEnumFORMATETC_fnAddRef(LPUNKNOWN iface
)
105 ICOM_THIS(IEnumFORMATETC
,iface
);
106 TRACE(shell
,"(%p)->(count=%lu)\n",this,(this->ref
)+1);
107 return ++(this->ref
);
109 static ULONG WINAPI
IEnumFORMATETC_fnRelease(LPUNKNOWN iface
)
111 ICOM_THIS(IEnumFORMATETC
,iface
);
112 TRACE(shell
,"(%p)->()\n",this);
114 { TRACE(shell
," destroying IEnumFORMATETC(%p)\n",this);
116 { SHFree (this->pFmt
);
118 HeapFree(GetProcessHeap(),0,this);
123 static HRESULT WINAPI
IEnumFORMATETC_fnNext(LPENUMFORMATETC iface
, ULONG celt
, FORMATETC32
*rgelt
, ULONG
*pceltFethed
)
125 ICOM_THIS(IEnumFORMATETC
,iface
);
127 HRESULT hres
= S_FALSE
;
129 TRACE (shell
, "(%p)->()\n", this);
131 if (this->posFmt
< this->countFmt
)
132 { cfetch
= this->countFmt
- this->posFmt
;
137 memcpy(rgelt
, &this->pFmt
[this->posFmt
], cfetch
* sizeof(FORMATETC32
));
138 this->posFmt
+= cfetch
;
145 { *pceltFethed
= cfetch
;
150 static HRESULT WINAPI
IEnumFORMATETC_fnSkip(LPENUMFORMATETC iface
, ULONG celt
)
152 ICOM_THIS(IEnumFORMATETC
,iface
);
153 FIXME (shell
, "(%p)->(num=%lu)\n", this, celt
);
155 this->posFmt
+= celt
;
156 if (this->posFmt
> this->countFmt
)
157 { this->posFmt
= this->countFmt
;
162 static HRESULT WINAPI
IEnumFORMATETC_fnReset(LPENUMFORMATETC iface
)
164 ICOM_THIS(IEnumFORMATETC
,iface
);
165 FIXME (shell
, "(%p)->()\n", this);
170 static HRESULT WINAPI
IEnumFORMATETC_fnClone(LPENUMFORMATETC iface
, LPENUMFORMATETC
* ppenum
)
172 ICOM_THIS(IEnumFORMATETC
,iface
);
173 FIXME (shell
, "(%p)->(ppenum=%p)\n", this, ppenum
);
177 /***********************************************************************
178 * IDataObject implementation
180 typedef struct _IDataObject
182 /* IUnknown fields */
183 ICOM_VTABLE(IDataObject
)* lpvtbl
;
185 /* IDataObject fields */
187 LPIDLLIST lpill
; /* the data of the dataobject */
191 static HRESULT WINAPI
IDataObject_fnQueryInterface(LPUNKNOWN iface
, REFIID riid
, LPVOID
* ppvObj
);
192 static ULONG WINAPI
IDataObject_fnAddRef(LPUNKNOWN iface
);
193 static ULONG WINAPI
IDataObject_fnRelease(LPUNKNOWN iface
);
194 static HRESULT WINAPI
IDataObject_fnGetData(LPDATAOBJECT iface
, LPFORMATETC32 pformatetcIn
, STGMEDIUM32
* pmedium
);
195 static HRESULT WINAPI
IDataObject_fnGetDataHere(LPDATAOBJECT iface
, LPFORMATETC32 pformatetc
, STGMEDIUM32
* pmedium
);
196 static HRESULT WINAPI
IDataObject_fnQueryGetData(LPDATAOBJECT iface
, LPFORMATETC32 pformatetc
);
197 static HRESULT WINAPI
IDataObject_fnGetCanonicalFormatEtc(LPDATAOBJECT iface
, LPFORMATETC32 pformatectIn
, LPFORMATETC32 pformatetcOut
);
198 static HRESULT WINAPI
IDataObject_fnSetData(LPDATAOBJECT iface
, LPFORMATETC32 pformatetc
, STGMEDIUM32
* pmedium
, BOOL32 fRelease
);
199 static HRESULT WINAPI
IDataObject_fnEnumFormatEtc(LPDATAOBJECT iface
, DWORD dwDirection
, IEnumFORMATETC
** ppenumFormatEtc
);
200 static HRESULT WINAPI
IDataObject_fnDAdvise(LPDATAOBJECT iface
, LPFORMATETC32
* pformatetc
, DWORD advf
, IAdviseSink
* pAdvSink
, DWORD
* pdwConnection
);
201 static HRESULT WINAPI
IDataObject_fnDUnadvise(LPDATAOBJECT iface
, DWORD dwConnection
);
202 static HRESULT WINAPI
IDataObject_fnEnumDAdvise(LPDATAOBJECT iface
, IEnumSTATDATA
**ppenumAdvise
);
204 static struct ICOM_VTABLE(IDataObject
) dtovt
=
207 IDataObject_fnQueryInterface
,
208 IDataObject_fnAddRef
,
209 IDataObject_fnRelease
211 IDataObject_fnGetData
,
212 IDataObject_fnGetDataHere
,
213 IDataObject_fnQueryGetData
,
214 IDataObject_fnGetCanonicalFormatEtc
,
215 IDataObject_fnSetData
,
216 IDataObject_fnEnumFormatEtc
,
217 IDataObject_fnDAdvise
,
218 IDataObject_fnDUnadvise
,
219 IDataObject_fnEnumDAdvise
222 /**************************************************************************
223 * IDataObject_Constructor
225 LPDATAOBJECT
IDataObject_Constructor(HWND32 hwndOwner
, LPSHELLFOLDER psf
, LPITEMIDLIST
* apidl
, UINT32 cidl
)
228 if (!(dto
= (_IDataObject
*)HeapAlloc(GetProcessHeap(),0,sizeof(_IDataObject
))))
234 dto
->pidl
=ILClone(psf
->mpidl
); /* FIXME:add a reference and don't copy*/
236 /* fill the ItemID List List */
237 dto
->lpill
= IDLList_Constructor (8);
241 dto
->lpill
->lpvtbl
->fnAddItems(dto
->lpill
, apidl
, cidl
);
243 TRACE(shell
,"(%p)->(sf=%p apidl=%p cidl=%u)\n",dto
, psf
, apidl
, cidl
);
244 return (LPDATAOBJECT
)dto
;
246 /***************************************************************************
247 * IDataObject_QueryInterface
249 static HRESULT WINAPI
IDataObject_fnQueryInterface (LPUNKNOWN iface
, REFIID riid
, LPVOID
* ppvObj
)
251 ICOM_THIS(IDataObject
,iface
);
253 WINE_StringFromCLSID((LPCLSID
)riid
,xriid
);
254 TRACE(shell
,"(%p)->(\n\tIID:\t%s,%p)\n",this,xriid
,ppvObj
);
258 if(IsEqualIID(riid
, &IID_IUnknown
)) /*IUnknown*/
261 else if(IsEqualIID(riid
, &IID_IDataObject
)) /*IDataObject*/
262 { *ppvObj
= (IDataObject
*)this;
266 { IDataObject_AddRef((IDataObject
*)*ppvObj
);
267 TRACE(shell
,"-- Interface: (%p)->(%p)\n",ppvObj
,*ppvObj
);
270 TRACE(shell
,"-- Interface: E_NOINTERFACE\n");
271 return E_NOINTERFACE
;
273 /**************************************************************************
276 static ULONG WINAPI
IDataObject_fnAddRef(LPUNKNOWN iface
)
278 ICOM_THIS(IDataObject
,iface
);
279 TRACE(shell
,"(%p)->(count=%lu)\n",this,(this->ref
)+1);
280 return ++(this->ref
);
282 /**************************************************************************
283 * IDataObject_Release
285 static ULONG WINAPI
IDataObject_fnRelease(LPUNKNOWN iface
)
287 ICOM_THIS(IDataObject
,iface
);
288 TRACE(shell
,"(%p)->()\n",this);
290 { TRACE(shell
," destroying IDataObject(%p)\n",this);
291 IDLList_Destructor(this->lpill
);
292 HeapFree(GetProcessHeap(),0,this);
297 /**************************************************************************
298 * DATAOBJECT_InitShellIDList (internal)
301 * get or register the "Shell IDList Array" clipformat
303 static BOOL32
DATAOBJECT_InitShellIDList(void)
308 cfShellIDList
= RegisterClipboardFormat32A(CFSTR_SHELLIDLIST
);
309 return(cfShellIDList
!= 0);
312 /**************************************************************************
313 * DATAOBJECT_InitFileGroupDesc (internal)
316 * get or register the "FileGroupDescriptor" clipformat
318 /* FIXME: DATAOBJECT_InitFileGroupDesc is not used (19981226)
319 static BOOL32 DATAOBJECT_InitFileGroupDesc(void)
320 { if (cfFileGroupDesc)
324 cfFileGroupDesc = RegisterClipboardFormat32A(CFSTR_FILEDESCRIPTORA);
325 return(cfFileGroupDesc != 0);
328 /**************************************************************************
329 * DATAOBJECT_InitFileContents (internal)
332 * get or register the "FileContents" clipformat
334 /* FIXME: DATAOBJECT_InitFileContents is not used (19981226)
335 static BOOL32 DATAOBJECT_InitFileContents(void)
336 { if (cfFileContents)
340 cfFileContents = RegisterClipboardFormat32A(CFSTR_FILECONTENTS);
341 return(cfFileContents != 0);
345 /**************************************************************************
346 * interface implementation
348 static HRESULT WINAPI
IDataObject_fnGetData(LPDATAOBJECT iface
, LPFORMATETC32 pformatetcIn
, STGMEDIUM32
*pmedium
)
350 ICOM_THIS(IDataObject
,iface
);
353 DWORD size
, size1
, size2
;
358 GetClipboardFormatName32A (pformatetcIn
->cfFormat
, temp
, 256);
359 WARN (shell
, "(%p)->(%p %p format=%s)semi-stub\n", this, pformatetcIn
, pmedium
, temp
);
361 if (!DATAOBJECT_InitShellIDList()) /* is the clipformat registred? */
362 { return(E_UNEXPECTED
);
365 if (pformatetcIn
->cfFormat
== cfShellIDList
)
366 { if (pformatetcIn
->ptd
==NULL
367 && (pformatetcIn
->dwAspect
& DVASPECT_CONTENT
)
368 && pformatetcIn
->lindex
==-1
369 && (pformatetcIn
->tymed
&TYMED_HGLOBAL
))
370 { cItems
= this->lpill
->lpvtbl
->fnGetCount(this->lpill
);
372 { return(E_UNEXPECTED
);
374 pidl
= this->lpill
->lpvtbl
->fnGetElement(this->lpill
, 0);
379 /*hack consider only the first item*/
381 size
= sizeof(CIDA
) + sizeof (UINT32
)*(cItems
-1);
382 size1
= ILGetSize (this->pidl
);
383 size2
= ILGetSize (pidl
);
384 hmem
= GlobalAlloc32(GMEM_FIXED
, size
+size1
+size2
);
385 pcida
= GlobalLock32 (hmem
);
387 { return(E_OUTOFMEMORY
);
391 pcida
->aoffset
[0] = size
;
392 pcida
->aoffset
[1] = size
+size1
;
394 TRACE(shell
,"-- %lu %lu %lu\n",size
, size1
, size2
);
395 TRACE(shell
,"-- %p %p\n",this->pidl
, pidl
);
396 TRACE(shell
,"-- %p %p %p\n",pcida
, (LPBYTE
)pcida
+size
,(LPBYTE
)pcida
+size
+size1
);
398 memcpy ((LPBYTE
)pcida
+size
, this->pidl
, size1
);
399 memcpy ((LPBYTE
)pcida
+size
+size1
, pidl
, size2
);
400 TRACE(shell
,"-- after copy\n");
402 GlobalUnlock32(hmem
);
404 pmedium
->tymed
= TYMED_HGLOBAL
;
405 pmedium
->u
.hGlobal
= (HGLOBAL32
)pcida
;
406 pmedium
->pUnkForRelease
= NULL
;
407 TRACE(shell
,"-- ready\n");
411 FIXME (shell
, "-- clipformat not implemented\n");
412 return (E_INVALIDARG
);
414 static HRESULT WINAPI
IDataObject_fnGetDataHere(LPDATAOBJECT iface
, LPFORMATETC32 pformatetc
, STGMEDIUM32
*pmedium
)
416 ICOM_THIS(IDataObject
,iface
);
417 FIXME (shell
, "(%p)->()\n", this);
420 static HRESULT WINAPI
IDataObject_fnQueryGetData(LPDATAOBJECT iface
, LPFORMATETC32 pformatetc
)
422 ICOM_THIS(IDataObject
,iface
);
423 FIXME (shell
, "(%p)->()\n", this);
426 static HRESULT WINAPI
IDataObject_fnGetCanonicalFormatEtc(LPDATAOBJECT iface
, LPFORMATETC32 pformatectIn
, LPFORMATETC32 pformatetcOut
)
428 ICOM_THIS(IDataObject
,iface
);
429 FIXME (shell
, "(%p)->()\n", this);
432 static HRESULT WINAPI
IDataObject_fnSetData(LPDATAOBJECT iface
, LPFORMATETC32 pformatetc
, STGMEDIUM32
*pmedium
, BOOL32 fRelease
)
434 ICOM_THIS(IDataObject
,iface
);
435 FIXME (shell
, "(%p)->()\n", this);
438 static HRESULT WINAPI
IDataObject_fnEnumFormatEtc(LPDATAOBJECT iface
, DWORD dwDirection
, IEnumFORMATETC
**ppenumFormatEtc
)
440 ICOM_THIS(IDataObject
,iface
);
441 FIXME (shell
, "(%p)->()\n", this);
444 static HRESULT WINAPI
IDataObject_fnDAdvise(LPDATAOBJECT iface
, LPFORMATETC32
*pformatetc
, DWORD advf
, IAdviseSink
*pAdvSink
, DWORD
*pdwConnection
)
446 ICOM_THIS(IDataObject
,iface
);
447 FIXME (shell
, "(%p)->()\n", this);
450 static HRESULT WINAPI
IDataObject_fnDUnadvise(LPDATAOBJECT iface
, DWORD dwConnection
)
452 ICOM_THIS(IDataObject
,iface
);
453 FIXME (shell
, "(%p)->()\n", this);
456 static HRESULT WINAPI
IDataObject_fnEnumDAdvise(LPDATAOBJECT iface
, IEnumSTATDATA
**ppenumAdvise
)
458 ICOM_THIS(IDataObject
,iface
);
459 FIXME (shell
, "(%p)->()\n", this);