2 * IEnumFORMATETC, IDataObject
4 * selecting and droping objects within the shell and/or common dialogs
6 * Copyright 1998 <juergen.schmied@metronet.de>
12 #include "shell32_main.h"
14 UINT32 cfShellIDList
=0;
15 UINT32 cfFileGroupDesc
=0;
16 UINT32 cfFileContents
=0;
18 /***********************************************************************
19 * IEnumFORMATETC implementation
21 static HRESULT WINAPI
IEnumFORMATETC_QueryInterface (LPENUMFORMATETC
this, REFIID riid
, LPVOID
* ppvObj
);
22 static ULONG WINAPI
IEnumFORMATETC_AddRef (LPENUMFORMATETC
this);
23 static ULONG WINAPI
IEnumFORMATETC_Release (LPENUMFORMATETC
this);
24 static HRESULT WINAPI
IEnumFORMATETC_Next(LPENUMFORMATETC
this, ULONG celt
, FORMATETC32
*rgelt
, ULONG
*pceltFethed
);
25 static HRESULT WINAPI
IEnumFORMATETC_Skip(LPENUMFORMATETC
this, ULONG celt
);
26 static HRESULT WINAPI
IEnumFORMATETC_Reset(LPENUMFORMATETC
this);
27 static HRESULT WINAPI
IEnumFORMATETC_Clone(LPENUMFORMATETC
this, LPENUMFORMATETC
* ppenum
);
29 static struct IEnumFORMATETC_VTable efvt
=
30 { IEnumFORMATETC_QueryInterface
,
31 IEnumFORMATETC_AddRef
,
32 IEnumFORMATETC_Release
,
39 extern LPENUMFORMATETC
IEnumFORMATETC_Constructor(UINT32 cfmt
, const FORMATETC32 afmt
[])
41 DWORD size
=cfmt
* sizeof(FORMATETC32
);
43 ef
=(LPENUMFORMATETC
)HeapAlloc(GetProcessHeap(),0,sizeof(IEnumFORMATETC
));
49 ef
->pFmt
= SHAlloc (size
);
52 { memcpy(ef
->pFmt
, afmt
, size
);
55 TRACE(shell
,"(%p)->()\n",ef
);
58 static HRESULT WINAPI
IEnumFORMATETC_QueryInterface (LPENUMFORMATETC
this, REFIID riid
, LPVOID
* ppvObj
)
60 WINE_StringFromCLSID((LPCLSID
)riid
,xriid
);
61 TRACE(shell
,"(%p)->(\n\tIID:\t%s,%p)\n",this,xriid
,ppvObj
);
65 if(IsEqualIID(riid
, &IID_IUnknown
))
68 else if(IsEqualIID(riid
, &IID_IEnumFORMATETC
))
69 { *ppvObj
= (IDataObject
*)this;
73 { (*(LPENUMFORMATETC
*)ppvObj
)->lpvtbl
->fnAddRef(this);
74 TRACE(shell
,"-- Interface: (%p)->(%p)\n",ppvObj
,*ppvObj
);
77 TRACE(shell
,"-- Interface: E_NOINTERFACE\n");
81 static ULONG WINAPI
IEnumFORMATETC_AddRef (LPENUMFORMATETC
this)
82 { TRACE(shell
,"(%p)->(count=%lu)\n",this,(this->ref
)+1);
85 static ULONG WINAPI
IEnumFORMATETC_Release (LPENUMFORMATETC
this)
86 { TRACE(shell
,"(%p)->()\n",this);
88 { TRACE(shell
," destroying IEnumFORMATETC(%p)\n",this);
90 { SHFree (this->pFmt
);
92 HeapFree(GetProcessHeap(),0,this);
97 static HRESULT WINAPI
IEnumFORMATETC_Next(LPENUMFORMATETC
this, ULONG celt
, FORMATETC32
*rgelt
, ULONG
*pceltFethed
)
99 HRESULT hres
= S_FALSE
;
101 TRACE (shell
, "(%p)->()\n", this);
103 if (this->posFmt
< this->countFmt
)
104 { cfetch
= this->countFmt
- this->posFmt
;
109 memcpy(rgelt
, &this->pFmt
[this->posFmt
], cfetch
* sizeof(FORMATETC32
));
110 this->posFmt
+= cfetch
;
117 { *pceltFethed
= cfetch
;
122 static HRESULT WINAPI
IEnumFORMATETC_Skip(LPENUMFORMATETC
this, ULONG celt
)
123 { FIXME (shell
, "(%p)->(num=%lu)\n", this, celt
);
125 this->posFmt
+= celt
;
126 if (this->posFmt
> this->countFmt
)
127 { this->posFmt
= this->countFmt
;
132 static HRESULT WINAPI
IEnumFORMATETC_Reset(LPENUMFORMATETC
this)
133 { FIXME (shell
, "(%p)->()\n", this);
138 static HRESULT WINAPI
IEnumFORMATETC_Clone(LPENUMFORMATETC
this, LPENUMFORMATETC
* ppenum
)
139 { FIXME (shell
, "(%p)->(ppenum=%p)\n", this, ppenum
);
143 /***********************************************************************
144 * IDataObject implementation
147 static HRESULT WINAPI
IDataObject_QueryInterface (LPDATAOBJECT
, REFIID riid
, LPVOID
* ppvObj
);
148 static ULONG WINAPI
IDataObject_AddRef (LPDATAOBJECT
);
149 static ULONG WINAPI
IDataObject_Release (LPDATAOBJECT
);
150 static HRESULT WINAPI
IDataObject_GetData (LPDATAOBJECT
, LPFORMATETC32 pformatetcIn
, STGMEDIUM32
*pmedium
);
151 static HRESULT WINAPI
IDataObject_GetDataHere(LPDATAOBJECT
, LPFORMATETC32 pformatetc
, STGMEDIUM32
*pmedium
);
152 static HRESULT WINAPI
IDataObject_QueryGetData(LPDATAOBJECT
, LPFORMATETC32 pformatetc
);
153 static HRESULT WINAPI
IDataObject_GetCanonicalFormatEtc(LPDATAOBJECT
, LPFORMATETC32 pformatectIn
, LPFORMATETC32 pformatetcOut
);
154 static HRESULT WINAPI
IDataObject_SetData(LPDATAOBJECT
, LPFORMATETC32 pformatetc
, STGMEDIUM32
*pmedium
, BOOL32 fRelease
);
155 static HRESULT WINAPI
IDataObject_EnumFormatEtc(LPDATAOBJECT
, DWORD dwDirection
, IEnumFORMATETC
**ppenumFormatEtc
);
156 static HRESULT WINAPI
IDataObject_DAdvise (LPDATAOBJECT
, LPFORMATETC32
*pformatetc
, DWORD advf
, IAdviseSink
*pAdvSink
, DWORD
*pdwConnection
);
157 static HRESULT WINAPI
IDataObject_DUnadvise(LPDATAOBJECT
, DWORD dwConnection
);
158 static HRESULT WINAPI
IDataObject_EnumDAdvise(LPDATAOBJECT
, IEnumSTATDATA
**ppenumAdvise
);
160 static struct IDataObject_VTable dtovt
=
161 { IDataObject_QueryInterface
,
165 IDataObject_GetDataHere
,
166 IDataObject_QueryGetData
,
167 IDataObject_GetCanonicalFormatEtc
,
169 IDataObject_EnumFormatEtc
,
171 IDataObject_DUnadvise
,
172 IDataObject_EnumDAdvise
175 /**************************************************************************
176 * IDataObject_Constructor
178 LPDATAOBJECT
IDataObject_Constructor(HWND32 hwndOwner
, LPSHELLFOLDER psf
, LPITEMIDLIST
* apidl
, UINT32 cidl
)
180 if (!(dto
= (LPDATAOBJECT
)HeapAlloc(GetProcessHeap(),0,sizeof(IDataObject
))))
186 dto
->pidl
=ILClone(psf
->mpidl
); /* FIXME:add a reference and don't copy*/
188 /* fill the ItemID List List */
189 dto
->lpill
= IDLList_Constructor (8);
193 dto
->lpill
->lpvtbl
->fnAddItems(dto
->lpill
, apidl
, cidl
);
195 TRACE(shell
,"(%p)->(sf=%p apidl=%p cidl=%u)\n",dto
, psf
, apidl
, cidl
);
198 /***************************************************************************
199 * IDataObject_QueryInterface
201 static HRESULT WINAPI
IDataObject_QueryInterface (LPDATAOBJECT
this, REFIID riid
, LPVOID
* ppvObj
)
203 WINE_StringFromCLSID((LPCLSID
)riid
,xriid
);
204 TRACE(shell
,"(%p)->(\n\tIID:\t%s,%p)\n",this,xriid
,ppvObj
);
208 if(IsEqualIID(riid
, &IID_IUnknown
)) /*IUnknown*/
211 else if(IsEqualIID(riid
, &IID_IDataObject
)) /*IDataObject*/
212 { *ppvObj
= (IDataObject
*)this;
216 { (*(LPDATAOBJECT
*)ppvObj
)->lpvtbl
->fnAddRef(this);
217 TRACE(shell
,"-- Interface: (%p)->(%p)\n",ppvObj
,*ppvObj
);
220 TRACE(shell
,"-- Interface: E_NOINTERFACE\n");
221 return E_NOINTERFACE
;
223 /**************************************************************************
226 static ULONG WINAPI
IDataObject_AddRef(LPDATAOBJECT
this)
227 { TRACE(shell
,"(%p)->(count=%lu)\n",this,(this->ref
)+1);
228 return ++(this->ref
);
230 /**************************************************************************
231 * IDataObject_Release
233 static ULONG WINAPI
IDataObject_Release(LPDATAOBJECT
this)
234 { TRACE(shell
,"(%p)->()\n",this);
236 { TRACE(shell
," destroying IDataObject(%p)\n",this);
237 IDLList_Destructor(this->lpill
);
238 HeapFree(GetProcessHeap(),0,this);
243 /**************************************************************************
244 * DATAOBJECT_InitShellIDList (internal)
247 * get or register the "Shell IDList Array" clipformat
249 static BOOL32
DATAOBJECT_InitShellIDList()
254 cfShellIDList
= RegisterClipboardFormat32A(CFSTR_SHELLIDLIST
);
255 return(cfShellIDList
!= 0);
258 /**************************************************************************
259 * DATAOBJECT_InitFileGroupDesc (internal)
262 * get or register the "FileGroupDescriptor" clipformat
264 static BOOL32
DATAOBJECT_InitFileGroupDesc()
265 { if (cfFileGroupDesc
)
269 cfFileGroupDesc
= RegisterClipboardFormat32A(CFSTR_FILEDESCRIPTORA
);
270 return(cfFileGroupDesc
!= 0);
272 /**************************************************************************
273 * DATAOBJECT_InitFileContents (internal)
276 * get or register the "FileContents" clipformat
278 static BOOL32
DATAOBJECT_InitFileContents()
279 { if (cfFileContents
)
283 cfFileContents
= RegisterClipboardFormat32A(CFSTR_FILECONTENTS
);
284 return(cfFileContents
!= 0);
288 /**************************************************************************
289 * interface implementation
291 static HRESULT WINAPI
IDataObject_GetData (LPDATAOBJECT
this, LPFORMATETC32 pformatetcIn
, STGMEDIUM32
*pmedium
)
294 DWORD size
, size1
, size2
;
299 GetClipboardFormatName32A (pformatetcIn
->cfFormat
, temp
, 256);
300 FIXME (shell
, "(%p)->(%p %p format=%s)\n", this, pformatetcIn
, pmedium
, temp
);
302 if (!DATAOBJECT_InitShellIDList()) /* is the clipformat registred? */
303 { return(E_UNEXPECTED
);
306 if (pformatetcIn
->cfFormat
== cfShellIDList
)
307 { if (pformatetcIn
->ptd
==NULL
308 && (pformatetcIn
->dwAspect
& DVASPECT_CONTENT
)
309 && pformatetcIn
->lindex
==-1
310 && (pformatetcIn
->tymed
&TYMED_HGLOBAL
))
311 { cItems
= this->lpill
->lpvtbl
->fnGetCount(this->lpill
);
313 { return(E_UNEXPECTED
);
315 pidl
= this->lpill
->lpvtbl
->fnGetElement(this->lpill
, 0);
320 /*hack consider only the first item*/
322 size
= sizeof(CIDA
) + sizeof (UINT32
)*(cItems
-1);
323 size1
= ILGetSize (this->pidl
);
324 size2
= ILGetSize (pidl
);
325 hmem
= GlobalAlloc32(GMEM_FIXED
, size
+size1
+size2
);
326 pcida
= GlobalLock32 (hmem
);
328 { return(E_OUTOFMEMORY
);
332 pcida
->aoffset
[0] = size
;
333 pcida
->aoffset
[1] = size
+size1
;
335 TRACE(shell
,"-- %lu %lu %lu\n",size
, size1
, size2
);
336 TRACE(shell
,"-- %p %p\n",this->pidl
, pidl
);
337 TRACE(shell
,"-- %p %p %p\n",pcida
, (void*)pcida
+size
,(void*)pcida
+size
+size1
);
339 memcpy ((void*)pcida
+size
, this->pidl
, size1
);
340 memcpy ((void*)pcida
+size
+size1
, pidl
, size2
);
341 TRACE(shell
,"-- after copy\n");
343 GlobalUnlock32(hmem
);
345 pmedium
->tymed
= TYMED_HGLOBAL
;
346 pmedium
->u
.hGlobal
= (HGLOBAL32
)pcida
;
347 pmedium
->pUnkForRelease
= NULL
;
348 TRACE(shell
,"-- ready\n");
352 FIXME (shell
, "-- clipformat not implemented\n");
353 return (E_INVALIDARG
);
355 static HRESULT WINAPI
IDataObject_GetDataHere(LPDATAOBJECT
this, LPFORMATETC32 pformatetc
, STGMEDIUM32
*pmedium
)
356 { FIXME (shell
, "(%p)->()\n", this);
359 static HRESULT WINAPI
IDataObject_QueryGetData(LPDATAOBJECT
this, LPFORMATETC32 pformatetc
)
360 { FIXME (shell
, "(%p)->()\n", this);
363 static HRESULT WINAPI
IDataObject_GetCanonicalFormatEtc(LPDATAOBJECT
this, LPFORMATETC32 pformatectIn
, LPFORMATETC32 pformatetcOut
)
364 { FIXME (shell
, "(%p)->()\n", this);
367 static HRESULT WINAPI
IDataObject_SetData(LPDATAOBJECT
this, LPFORMATETC32 pformatetc
, STGMEDIUM32
*pmedium
, BOOL32 fRelease
)
368 { FIXME (shell
, "(%p)->()\n", this);
371 static HRESULT WINAPI
IDataObject_EnumFormatEtc(LPDATAOBJECT
this, DWORD dwDirection
, IEnumFORMATETC
**ppenumFormatEtc
)
372 { FIXME (shell
, "(%p)->()\n", this);
375 static HRESULT WINAPI
IDataObject_DAdvise (LPDATAOBJECT
this, LPFORMATETC32
*pformatetc
, DWORD advf
, IAdviseSink
*pAdvSink
, DWORD
*pdwConnection
)
376 { FIXME (shell
, "(%p)->()\n", this);
379 static HRESULT WINAPI
IDataObject_DUnadvise(LPDATAOBJECT
this, DWORD dwConnection
)
380 { FIXME (shell
, "(%p)->()\n", this);
383 static HRESULT WINAPI
IDataObject_EnumDAdvise(LPDATAOBJECT
this, IEnumSTATDATA
**ppenumAdvise
)
384 { FIXME (shell
, "(%p)->()\n", this);