2 * IEnumFORMATETC, IDataObject
4 * selecting and droping objects within the shell and/or common dialogs
6 * Copyright 1998, 1999 <juergen.schmied@metronet.de>
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #define NONAMELESSUNION
25 #define NONAMELESSSTRUCT
28 #include "shell32_main.h"
29 #include "wine/debug.h"
30 #include "undocshell.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(shell
);
34 /***********************************************************************
35 * IEnumFORMATETC implementation
41 ICOM_VFIELD(IEnumFORMATETC
);
43 /* IEnumFORMATETC fields */
49 static HRESULT WINAPI
IEnumFORMATETC_fnQueryInterface(LPENUMFORMATETC iface
, REFIID riid
, LPVOID
* ppvObj
);
50 static ULONG WINAPI
IEnumFORMATETC_fnAddRef(LPENUMFORMATETC iface
);
51 static ULONG WINAPI
IEnumFORMATETC_fnRelease(LPENUMFORMATETC iface
);
52 static HRESULT WINAPI
IEnumFORMATETC_fnNext(LPENUMFORMATETC iface
, ULONG celt
, FORMATETC
* rgelt
, ULONG
* pceltFethed
);
53 static HRESULT WINAPI
IEnumFORMATETC_fnSkip(LPENUMFORMATETC iface
, ULONG celt
);
54 static HRESULT WINAPI
IEnumFORMATETC_fnReset(LPENUMFORMATETC iface
);
55 static HRESULT WINAPI
IEnumFORMATETC_fnClone(LPENUMFORMATETC iface
, LPENUMFORMATETC
* ppenum
);
57 static struct ICOM_VTABLE(IEnumFORMATETC
) efvt
=
59 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
60 IEnumFORMATETC_fnQueryInterface
,
61 IEnumFORMATETC_fnAddRef
,
62 IEnumFORMATETC_fnRelease
,
63 IEnumFORMATETC_fnNext
,
64 IEnumFORMATETC_fnSkip
,
65 IEnumFORMATETC_fnReset
,
66 IEnumFORMATETC_fnClone
69 LPENUMFORMATETC
IEnumFORMATETC_Constructor(UINT cfmt
, const FORMATETC afmt
[])
71 IEnumFORMATETCImpl
* ef
;
72 DWORD size
=cfmt
* sizeof(FORMATETC
);
74 ef
=(IEnumFORMATETCImpl
*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IEnumFORMATETCImpl
));
82 ef
->pFmt
= SHAlloc (size
);
86 memcpy(ef
->pFmt
, afmt
, size
);
90 TRACE("(%p)->(%u,%p)\n",ef
, cfmt
, afmt
);
91 return (LPENUMFORMATETC
)ef
;
94 static HRESULT WINAPI
IEnumFORMATETC_fnQueryInterface(LPENUMFORMATETC iface
, REFIID riid
, LPVOID
* ppvObj
)
96 ICOM_THIS(IEnumFORMATETCImpl
,iface
);
97 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This
,debugstr_guid(riid
),ppvObj
);
101 if(IsEqualIID(riid
, &IID_IUnknown
))
105 else if(IsEqualIID(riid
, &IID_IEnumFORMATETC
))
107 *ppvObj
= (IEnumFORMATETC
*)This
;
112 IUnknown_AddRef((IUnknown
*)(*ppvObj
));
113 TRACE("-- Interface: (%p)->(%p)\n",ppvObj
,*ppvObj
);
116 TRACE("-- Interface: E_NOINTERFACE\n");
117 return E_NOINTERFACE
;
121 static ULONG WINAPI
IEnumFORMATETC_fnAddRef(LPENUMFORMATETC iface
)
123 ICOM_THIS(IEnumFORMATETCImpl
,iface
);
124 TRACE("(%p)->(count=%lu)\n",This
, This
->ref
);
125 return ++(This
->ref
);
128 static ULONG WINAPI
IEnumFORMATETC_fnRelease(LPENUMFORMATETC iface
)
130 ICOM_THIS(IEnumFORMATETCImpl
,iface
);
131 TRACE("(%p)->()\n",This
);
135 TRACE(" destroying IEnumFORMATETC(%p)\n",This
);
140 HeapFree(GetProcessHeap(),0,This
);
146 static HRESULT WINAPI
IEnumFORMATETC_fnNext(LPENUMFORMATETC iface
, ULONG celt
, FORMATETC
*rgelt
, ULONG
*pceltFethed
)
148 ICOM_THIS(IEnumFORMATETCImpl
,iface
);
151 TRACE("(%p)->(%lu,%p)\n", This
, celt
, rgelt
);
153 if(!This
->pFmt
)return S_FALSE
;
154 if(!rgelt
) return E_INVALIDARG
;
155 if (pceltFethed
) *pceltFethed
= 0;
157 for(i
= 0; This
->posFmt
< This
->countFmt
&& celt
> i
; i
++)
159 *rgelt
++ = This
->pFmt
[This
->posFmt
++];
162 if (pceltFethed
) *pceltFethed
= i
;
164 return ((i
== celt
) ? S_OK
: S_FALSE
);
167 static HRESULT WINAPI
IEnumFORMATETC_fnSkip(LPENUMFORMATETC iface
, ULONG celt
)
169 ICOM_THIS(IEnumFORMATETCImpl
,iface
);
170 TRACE("(%p)->(num=%lu)\n", This
, celt
);
172 if((This
->posFmt
+ celt
) >= This
->countFmt
) return S_FALSE
;
173 This
->posFmt
+= celt
;
177 static HRESULT WINAPI
IEnumFORMATETC_fnReset(LPENUMFORMATETC iface
)
179 ICOM_THIS(IEnumFORMATETCImpl
,iface
);
180 TRACE("(%p)->()\n", This
);
186 static HRESULT WINAPI
IEnumFORMATETC_fnClone(LPENUMFORMATETC iface
, LPENUMFORMATETC
* ppenum
)
188 ICOM_THIS(IEnumFORMATETCImpl
,iface
);
189 TRACE("(%p)->(ppenum=%p)\n", This
, ppenum
);
191 if (!ppenum
) return E_INVALIDARG
;
192 *ppenum
= IEnumFORMATETC_Constructor(This
->countFmt
, This
->pFmt
);
194 IEnumFORMATETC_fnSkip(*ppenum
, This
->posFmt
);
199 /***********************************************************************
200 * IDataObject implementation
203 /* number of supported formats */
204 #define MAX_FORMATS 3
208 /* IUnknown fields */
209 ICOM_VFIELD(IDataObject
);
212 /* IDataObject fields */
214 LPITEMIDLIST
* apidl
;
217 FORMATETC pFormatEtc
[MAX_FORMATS
];
223 static struct ICOM_VTABLE(IDataObject
) dtovt
;
225 /**************************************************************************
226 * IDataObject_Constructor
228 LPDATAOBJECT
IDataObject_Constructor(HWND hwndOwner
, LPITEMIDLIST pMyPidl
, LPITEMIDLIST
* apidl
, UINT cidl
)
230 IDataObjectImpl
* dto
;
232 dto
= (IDataObjectImpl
*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDataObjectImpl
));
237 ICOM_VTBL(dto
) = &dtovt
;
238 dto
->pidl
= ILClone(pMyPidl
);
239 dto
->apidl
= _ILCopyaPidl(apidl
, cidl
);
242 dto
->cfShellIDList
= RegisterClipboardFormatA(CFSTR_SHELLIDLIST
);
243 dto
->cfFileName
= RegisterClipboardFormatA(CFSTR_FILENAMEA
);
244 InitFormatEtc(dto
->pFormatEtc
[0], dto
->cfShellIDList
, TYMED_HGLOBAL
);
245 InitFormatEtc(dto
->pFormatEtc
[1], CF_HDROP
, TYMED_HGLOBAL
);
246 InitFormatEtc(dto
->pFormatEtc
[2], dto
->cfFileName
, TYMED_HGLOBAL
);
249 TRACE("(%p)->(apidl=%p cidl=%u)\n",dto
, apidl
, cidl
);
250 return (LPDATAOBJECT
)dto
;
253 /***************************************************************************
254 * IDataObject_QueryInterface
256 static HRESULT WINAPI
IDataObject_fnQueryInterface(LPDATAOBJECT iface
, REFIID riid
, LPVOID
* ppvObj
)
258 ICOM_THIS(IDataObjectImpl
,iface
);
259 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This
,debugstr_guid(riid
),ppvObj
);
263 if(IsEqualIID(riid
, &IID_IUnknown
)) /*IUnknown*/
267 else if(IsEqualIID(riid
, &IID_IDataObject
)) /*IDataObject*/
269 *ppvObj
= (IDataObject
*)This
;
274 IUnknown_AddRef((IUnknown
*)*ppvObj
);
275 TRACE("-- Interface: (%p)->(%p)\n",ppvObj
,*ppvObj
);
278 TRACE("-- Interface: E_NOINTERFACE\n");
279 return E_NOINTERFACE
;
282 /**************************************************************************
285 static ULONG WINAPI
IDataObject_fnAddRef(LPDATAOBJECT iface
)
287 ICOM_THIS(IDataObjectImpl
,iface
);
288 TRACE("(%p)->(count=%lu)\n",This
, This
->ref
);
289 return ++(This
->ref
);
292 /**************************************************************************
293 * IDataObject_Release
295 static ULONG WINAPI
IDataObject_fnRelease(LPDATAOBJECT iface
)
297 ICOM_THIS(IDataObjectImpl
,iface
);
298 TRACE("(%p)->()\n",This
);
302 TRACE(" destroying IDataObject(%p)\n",This
);
303 _ILFreeaPidl(This
->apidl
, This
->cidl
);
305 HeapFree(GetProcessHeap(),0,This
);
311 /**************************************************************************
312 * IDataObject_fnGetData
314 static HRESULT WINAPI
IDataObject_fnGetData(LPDATAOBJECT iface
, LPFORMATETC pformatetcIn
, STGMEDIUM
*pmedium
)
316 ICOM_THIS(IDataObjectImpl
,iface
);
321 GetClipboardFormatNameA (pformatetcIn
->cfFormat
, szTemp
, 256);
322 TRACE("(%p)->(%p %p format=%s)\n", This
, pformatetcIn
, pmedium
, szTemp
);
324 if (pformatetcIn
->cfFormat
== This
->cfShellIDList
)
326 if (This
->cidl
< 1) return(E_UNEXPECTED
);
327 pmedium
->u
.hGlobal
= RenderSHELLIDLIST(This
->pidl
, This
->apidl
, This
->cidl
);
329 else if (pformatetcIn
->cfFormat
== CF_HDROP
)
331 if (This
->cidl
< 1) return(E_UNEXPECTED
);
332 pmedium
->u
.hGlobal
= RenderHDROP(This
->pidl
, This
->apidl
, This
->cidl
);
334 else if (pformatetcIn
->cfFormat
== This
->cfFileName
)
336 if (This
->cidl
< 1) return(E_UNEXPECTED
);
337 pmedium
->u
.hGlobal
= RenderFILENAME(This
->pidl
, This
->apidl
, This
->cidl
);
341 FIXME("-- expected clipformat not implemented\n");
342 return (E_INVALIDARG
);
344 if (pmedium
->u
.hGlobal
)
346 pmedium
->tymed
= TYMED_HGLOBAL
;
347 pmedium
->pUnkForRelease
= NULL
;
350 return E_OUTOFMEMORY
;
353 static HRESULT WINAPI
IDataObject_fnGetDataHere(LPDATAOBJECT iface
, LPFORMATETC pformatetc
, STGMEDIUM
*pmedium
)
355 ICOM_THIS(IDataObjectImpl
,iface
);
356 FIXME("(%p)->()\n", This
);
360 static HRESULT WINAPI
IDataObject_fnQueryGetData(LPDATAOBJECT iface
, LPFORMATETC pformatetc
)
362 ICOM_THIS(IDataObjectImpl
,iface
);
365 TRACE("(%p)->(fmt=0x%08x tym=0x%08lx)\n", This
, pformatetc
->cfFormat
, pformatetc
->tymed
);
367 if(!(DVASPECT_CONTENT
& pformatetc
->dwAspect
))
368 return DV_E_DVASPECT
;
370 /* check our formats table what we have */
371 for (i
=0; i
<MAX_FORMATS
; i
++)
373 if ((This
->pFormatEtc
[i
].cfFormat
== pformatetc
->cfFormat
)
374 && (This
->pFormatEtc
[i
].tymed
== pformatetc
->tymed
))
383 static HRESULT WINAPI
IDataObject_fnGetCanonicalFormatEtc(LPDATAOBJECT iface
, LPFORMATETC pformatectIn
, LPFORMATETC pformatetcOut
)
385 ICOM_THIS(IDataObjectImpl
,iface
);
386 FIXME("(%p)->()\n", This
);
390 static HRESULT WINAPI
IDataObject_fnSetData(LPDATAOBJECT iface
, LPFORMATETC pformatetc
, STGMEDIUM
*pmedium
, BOOL fRelease
)
392 ICOM_THIS(IDataObjectImpl
,iface
);
393 FIXME("(%p)->()\n", This
);
397 static HRESULT WINAPI
IDataObject_fnEnumFormatEtc(LPDATAOBJECT iface
, DWORD dwDirection
, IEnumFORMATETC
**ppenumFormatEtc
)
399 ICOM_THIS(IDataObjectImpl
,iface
);
401 TRACE("(%p)->()\n", This
);
402 *ppenumFormatEtc
=NULL
;
405 if (DATADIR_GET
== dwDirection
)
407 *ppenumFormatEtc
= IEnumFORMATETC_Constructor(MAX_FORMATS
, This
->pFormatEtc
);
408 return (*ppenumFormatEtc
) ? S_OK
: E_FAIL
;
414 static HRESULT WINAPI
IDataObject_fnDAdvise(LPDATAOBJECT iface
, FORMATETC
*pformatetc
, DWORD advf
, IAdviseSink
*pAdvSink
, DWORD
*pdwConnection
)
416 ICOM_THIS(IDataObjectImpl
,iface
);
417 FIXME("(%p)->()\n", This
);
420 static HRESULT WINAPI
IDataObject_fnDUnadvise(LPDATAOBJECT iface
, DWORD dwConnection
)
422 ICOM_THIS(IDataObjectImpl
,iface
);
423 FIXME("(%p)->()\n", This
);
426 static HRESULT WINAPI
IDataObject_fnEnumDAdvise(LPDATAOBJECT iface
, IEnumSTATDATA
**ppenumAdvise
)
428 ICOM_THIS(IDataObjectImpl
,iface
);
429 FIXME("(%p)->()\n", This
);
433 static struct ICOM_VTABLE(IDataObject
) dtovt
=
435 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
436 IDataObject_fnQueryInterface
,
437 IDataObject_fnAddRef
,
438 IDataObject_fnRelease
,
439 IDataObject_fnGetData
,
440 IDataObject_fnGetDataHere
,
441 IDataObject_fnQueryGetData
,
442 IDataObject_fnGetCanonicalFormatEtc
,
443 IDataObject_fnSetData
,
444 IDataObject_fnEnumFormatEtc
,
445 IDataObject_fnDAdvise
,
446 IDataObject_fnDUnadvise
,
447 IDataObject_fnEnumDAdvise