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"
15 UINT32 cfShellIDList
=0;
16 UINT32 cfFileGroupDesc
=0;
17 UINT32 cfFileContents
=0;
19 /***********************************************************************
20 * IEnumFORMATETC implementation
22 static HRESULT WINAPI
IEnumFORMATETC_QueryInterface (LPENUMFORMATETC
this, REFIID riid
, LPVOID
* ppvObj
);
23 static ULONG WINAPI
IEnumFORMATETC_AddRef (LPENUMFORMATETC
this);
24 static ULONG WINAPI
IEnumFORMATETC_Release (LPENUMFORMATETC
this);
25 static HRESULT WINAPI
IEnumFORMATETC_Next(LPENUMFORMATETC
this, ULONG celt
, FORMATETC32
*rgelt
, ULONG
*pceltFethed
);
26 static HRESULT WINAPI
IEnumFORMATETC_Skip(LPENUMFORMATETC
this, ULONG celt
);
27 static HRESULT WINAPI
IEnumFORMATETC_Reset(LPENUMFORMATETC
this);
28 static HRESULT WINAPI
IEnumFORMATETC_Clone(LPENUMFORMATETC
this, LPENUMFORMATETC
* ppenum
);
30 static struct IEnumFORMATETC_VTable efvt
=
31 { IEnumFORMATETC_QueryInterface
,
32 IEnumFORMATETC_AddRef
,
33 IEnumFORMATETC_Release
,
40 extern LPENUMFORMATETC
IEnumFORMATETC_Constructor(UINT32 cfmt
, const FORMATETC32 afmt
[])
42 DWORD size
=cfmt
* sizeof(FORMATETC32
);
44 ef
=(LPENUMFORMATETC
)HeapAlloc(GetProcessHeap(),0,sizeof(IEnumFORMATETC
));
50 ef
->pFmt
= SHAlloc (size
);
53 { memcpy(ef
->pFmt
, afmt
, size
);
56 TRACE(shell
,"(%p)->()\n",ef
);
59 static HRESULT WINAPI
IEnumFORMATETC_QueryInterface (LPENUMFORMATETC
this, REFIID riid
, LPVOID
* ppvObj
)
61 WINE_StringFromCLSID((LPCLSID
)riid
,xriid
);
62 TRACE(shell
,"(%p)->(\n\tIID:\t%s,%p)\n",this,xriid
,ppvObj
);
66 if(IsEqualIID(riid
, &IID_IUnknown
))
69 else if(IsEqualIID(riid
, &IID_IEnumFORMATETC
))
70 { *ppvObj
= (IDataObject
*)this;
74 { (*(LPENUMFORMATETC
*)ppvObj
)->lpvtbl
->fnAddRef(this);
75 TRACE(shell
,"-- Interface: (%p)->(%p)\n",ppvObj
,*ppvObj
);
78 TRACE(shell
,"-- Interface: E_NOINTERFACE\n");
82 static ULONG WINAPI
IEnumFORMATETC_AddRef (LPENUMFORMATETC
this)
83 { TRACE(shell
,"(%p)->(count=%lu)\n",this,(this->ref
)+1);
86 static ULONG WINAPI
IEnumFORMATETC_Release (LPENUMFORMATETC
this)
87 { TRACE(shell
,"(%p)->()\n",this);
89 { TRACE(shell
," destroying IEnumFORMATETC(%p)\n",this);
91 { SHFree (this->pFmt
);
93 HeapFree(GetProcessHeap(),0,this);
98 static HRESULT WINAPI
IEnumFORMATETC_Next(LPENUMFORMATETC
this, ULONG celt
, FORMATETC32
*rgelt
, ULONG
*pceltFethed
)
100 HRESULT hres
= S_FALSE
;
102 TRACE (shell
, "(%p)->()\n", this);
104 if (this->posFmt
< this->countFmt
)
105 { cfetch
= this->countFmt
- this->posFmt
;
110 memcpy(rgelt
, &this->pFmt
[this->posFmt
], cfetch
* sizeof(FORMATETC32
));
111 this->posFmt
+= cfetch
;
118 { *pceltFethed
= cfetch
;
123 static HRESULT WINAPI
IEnumFORMATETC_Skip(LPENUMFORMATETC
this, ULONG celt
)
124 { FIXME (shell
, "(%p)->(num=%lu)\n", this, celt
);
126 this->posFmt
+= celt
;
127 if (this->posFmt
> this->countFmt
)
128 { this->posFmt
= this->countFmt
;
133 static HRESULT WINAPI
IEnumFORMATETC_Reset(LPENUMFORMATETC
this)
134 { FIXME (shell
, "(%p)->()\n", this);
139 static HRESULT WINAPI
IEnumFORMATETC_Clone(LPENUMFORMATETC
this, LPENUMFORMATETC
* ppenum
)
140 { FIXME (shell
, "(%p)->(ppenum=%p)\n", this, ppenum
);
144 /***********************************************************************
145 * IDataObject implementation
148 static HRESULT WINAPI
IDataObject_QueryInterface (LPDATAOBJECT
, REFIID riid
, LPVOID
* ppvObj
);
149 static ULONG WINAPI
IDataObject_AddRef (LPDATAOBJECT
);
150 static ULONG WINAPI
IDataObject_Release (LPDATAOBJECT
);
151 static HRESULT WINAPI
IDataObject_GetData (LPDATAOBJECT
, LPFORMATETC32 pformatetcIn
, STGMEDIUM32
*pmedium
);
152 static HRESULT WINAPI
IDataObject_GetDataHere(LPDATAOBJECT
, LPFORMATETC32 pformatetc
, STGMEDIUM32
*pmedium
);
153 static HRESULT WINAPI
IDataObject_QueryGetData(LPDATAOBJECT
, LPFORMATETC32 pformatetc
);
154 static HRESULT WINAPI
IDataObject_GetCanonicalFormatEtc(LPDATAOBJECT
, LPFORMATETC32 pformatectIn
, LPFORMATETC32 pformatetcOut
);
155 static HRESULT WINAPI
IDataObject_SetData(LPDATAOBJECT
, LPFORMATETC32 pformatetc
, STGMEDIUM32
*pmedium
, BOOL32 fRelease
);
156 static HRESULT WINAPI
IDataObject_EnumFormatEtc(LPDATAOBJECT
, DWORD dwDirection
, IEnumFORMATETC
**ppenumFormatEtc
);
157 static HRESULT WINAPI
IDataObject_DAdvise (LPDATAOBJECT
, LPFORMATETC32
*pformatetc
, DWORD advf
, IAdviseSink
*pAdvSink
, DWORD
*pdwConnection
);
158 static HRESULT WINAPI
IDataObject_DUnadvise(LPDATAOBJECT
, DWORD dwConnection
);
159 static HRESULT WINAPI
IDataObject_EnumDAdvise(LPDATAOBJECT
, IEnumSTATDATA
**ppenumAdvise
);
161 static struct IDataObject_VTable dtovt
=
162 { IDataObject_QueryInterface
,
166 IDataObject_GetDataHere
,
167 IDataObject_QueryGetData
,
168 IDataObject_GetCanonicalFormatEtc
,
170 IDataObject_EnumFormatEtc
,
172 IDataObject_DUnadvise
,
173 IDataObject_EnumDAdvise
176 /**************************************************************************
177 * IDataObject_Constructor
179 LPDATAOBJECT
IDataObject_Constructor(HWND32 hwndOwner
, LPSHELLFOLDER psf
, LPITEMIDLIST
* apidl
, UINT32 cidl
)
181 if (!(dto
= (LPDATAOBJECT
)HeapAlloc(GetProcessHeap(),0,sizeof(IDataObject
))))
187 dto
->pidl
=ILClone(psf
->mpidl
); /* FIXME:add a reference and don't copy*/
189 /* fill the ItemID List List */
190 dto
->lpill
= IDLList_Constructor (8);
194 dto
->lpill
->lpvtbl
->fnAddItems(dto
->lpill
, apidl
, cidl
);
196 TRACE(shell
,"(%p)->(sf=%p apidl=%p cidl=%u)\n",dto
, psf
, apidl
, cidl
);
199 /***************************************************************************
200 * IDataObject_QueryInterface
202 static HRESULT WINAPI
IDataObject_QueryInterface (LPDATAOBJECT
this, REFIID riid
, LPVOID
* ppvObj
)
204 WINE_StringFromCLSID((LPCLSID
)riid
,xriid
);
205 TRACE(shell
,"(%p)->(\n\tIID:\t%s,%p)\n",this,xriid
,ppvObj
);
209 if(IsEqualIID(riid
, &IID_IUnknown
)) /*IUnknown*/
212 else if(IsEqualIID(riid
, &IID_IDataObject
)) /*IDataObject*/
213 { *ppvObj
= (IDataObject
*)this;
217 { (*(LPDATAOBJECT
*)ppvObj
)->lpvtbl
->fnAddRef(this);
218 TRACE(shell
,"-- Interface: (%p)->(%p)\n",ppvObj
,*ppvObj
);
221 TRACE(shell
,"-- Interface: E_NOINTERFACE\n");
222 return E_NOINTERFACE
;
224 /**************************************************************************
227 static ULONG WINAPI
IDataObject_AddRef(LPDATAOBJECT
this)
228 { TRACE(shell
,"(%p)->(count=%lu)\n",this,(this->ref
)+1);
229 return ++(this->ref
);
231 /**************************************************************************
232 * IDataObject_Release
234 static ULONG WINAPI
IDataObject_Release(LPDATAOBJECT
this)
235 { TRACE(shell
,"(%p)->()\n",this);
237 { TRACE(shell
," destroying IDataObject(%p)\n",this);
238 IDLList_Destructor(this->lpill
);
239 HeapFree(GetProcessHeap(),0,this);
244 /**************************************************************************
245 * DATAOBJECT_InitShellIDList (internal)
248 * get or register the "Shell IDList Array" clipformat
250 static BOOL32
DATAOBJECT_InitShellIDList(void)
255 cfShellIDList
= RegisterClipboardFormat32A(CFSTR_SHELLIDLIST
);
256 return(cfShellIDList
!= 0);
259 /**************************************************************************
260 * DATAOBJECT_InitFileGroupDesc (internal)
263 * get or register the "FileGroupDescriptor" clipformat
265 static BOOL32
DATAOBJECT_InitFileGroupDesc(void)
266 { if (cfFileGroupDesc
)
270 cfFileGroupDesc
= RegisterClipboardFormat32A(CFSTR_FILEDESCRIPTORA
);
271 return(cfFileGroupDesc
!= 0);
273 /**************************************************************************
274 * DATAOBJECT_InitFileContents (internal)
277 * get or register the "FileContents" clipformat
279 static BOOL32
DATAOBJECT_InitFileContents(void)
280 { if (cfFileContents
)
284 cfFileContents
= RegisterClipboardFormat32A(CFSTR_FILECONTENTS
);
285 return(cfFileContents
!= 0);
289 /**************************************************************************
290 * interface implementation
292 static HRESULT WINAPI
IDataObject_GetData (LPDATAOBJECT
this, LPFORMATETC32 pformatetcIn
, STGMEDIUM32
*pmedium
)
295 DWORD size
, size1
, size2
;
300 GetClipboardFormatName32A (pformatetcIn
->cfFormat
, temp
, 256);
301 WARN (shell
, "(%p)->(%p %p format=%s)semi-stub\n", this, pformatetcIn
, pmedium
, temp
);
303 if (!DATAOBJECT_InitShellIDList()) /* is the clipformat registred? */
304 { return(E_UNEXPECTED
);
307 if (pformatetcIn
->cfFormat
== cfShellIDList
)
308 { if (pformatetcIn
->ptd
==NULL
309 && (pformatetcIn
->dwAspect
& DVASPECT_CONTENT
)
310 && pformatetcIn
->lindex
==-1
311 && (pformatetcIn
->tymed
&TYMED_HGLOBAL
))
312 { cItems
= this->lpill
->lpvtbl
->fnGetCount(this->lpill
);
314 { return(E_UNEXPECTED
);
316 pidl
= this->lpill
->lpvtbl
->fnGetElement(this->lpill
, 0);
321 /*hack consider only the first item*/
323 size
= sizeof(CIDA
) + sizeof (UINT32
)*(cItems
-1);
324 size1
= ILGetSize (this->pidl
);
325 size2
= ILGetSize (pidl
);
326 hmem
= GlobalAlloc32(GMEM_FIXED
, size
+size1
+size2
);
327 pcida
= GlobalLock32 (hmem
);
329 { return(E_OUTOFMEMORY
);
333 pcida
->aoffset
[0] = size
;
334 pcida
->aoffset
[1] = size
+size1
;
336 TRACE(shell
,"-- %lu %lu %lu\n",size
, size1
, size2
);
337 TRACE(shell
,"-- %p %p\n",this->pidl
, pidl
);
338 TRACE(shell
,"-- %p %p %p\n",pcida
, (LPBYTE
)pcida
+size
,(LPBYTE
)pcida
+size
+size1
);
340 memcpy ((LPBYTE
)pcida
+size
, this->pidl
, size1
);
341 memcpy ((LPBYTE
)pcida
+size
+size1
, pidl
, size2
);
342 TRACE(shell
,"-- after copy\n");
344 GlobalUnlock32(hmem
);
346 pmedium
->tymed
= TYMED_HGLOBAL
;
347 pmedium
->u
.hGlobal
= (HGLOBAL32
)pcida
;
348 pmedium
->pUnkForRelease
= NULL
;
349 TRACE(shell
,"-- ready\n");
353 FIXME (shell
, "-- clipformat not implemented\n");
354 return (E_INVALIDARG
);
356 static HRESULT WINAPI
IDataObject_GetDataHere(LPDATAOBJECT
this, LPFORMATETC32 pformatetc
, STGMEDIUM32
*pmedium
)
357 { FIXME (shell
, "(%p)->()\n", this);
360 static HRESULT WINAPI
IDataObject_QueryGetData(LPDATAOBJECT
this, LPFORMATETC32 pformatetc
)
361 { FIXME (shell
, "(%p)->()\n", this);
364 static HRESULT WINAPI
IDataObject_GetCanonicalFormatEtc(LPDATAOBJECT
this, LPFORMATETC32 pformatectIn
, LPFORMATETC32 pformatetcOut
)
365 { FIXME (shell
, "(%p)->()\n", this);
368 static HRESULT WINAPI
IDataObject_SetData(LPDATAOBJECT
this, LPFORMATETC32 pformatetc
, STGMEDIUM32
*pmedium
, BOOL32 fRelease
)
369 { FIXME (shell
, "(%p)->()\n", this);
372 static HRESULT WINAPI
IDataObject_EnumFormatEtc(LPDATAOBJECT
this, DWORD dwDirection
, IEnumFORMATETC
**ppenumFormatEtc
)
373 { FIXME (shell
, "(%p)->()\n", this);
376 static HRESULT WINAPI
IDataObject_DAdvise (LPDATAOBJECT
this, LPFORMATETC32
*pformatetc
, DWORD advf
, IAdviseSink
*pAdvSink
, DWORD
*pdwConnection
)
377 { FIXME (shell
, "(%p)->()\n", this);
380 static HRESULT WINAPI
IDataObject_DUnadvise(LPDATAOBJECT
this, DWORD dwConnection
)
381 { FIXME (shell
, "(%p)->()\n", this);
384 static HRESULT WINAPI
IDataObject_EnumDAdvise(LPDATAOBJECT
this, IEnumSTATDATA
**ppenumAdvise
)
385 { FIXME (shell
, "(%p)->()\n", this);