2
* IEnumFORMATETC, IDataObject
4
* selecting and dropping 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25
#define NONAMELESSUNION
26
#define NONAMELESSSTRUCT
32
#include "shell32_main.h"
33
#include "wine/debug.h"
34
#include "undocshell.h"
36
WINE_DEFAULT_DEBUG_CHANNEL(shell);
38
/***********************************************************************
39
* IEnumFORMATETC implementation
45
IEnumFORMATETC IEnumFORMATETC_iface;
47
/* IEnumFORMATETC fields */
53
static inline IEnumFORMATETCImpl *impl_from_IEnumFORMATETC(IEnumFORMATETC *iface)
55
return CONTAINING_RECORD(iface, IEnumFORMATETCImpl, IEnumFORMATETC_iface);
58
static HRESULT WINAPI IEnumFORMATETC_fnQueryInterface(
59
LPENUMFORMATETC iface, REFIID riid, LPVOID* ppvObj)
61
IEnumFORMATETCImpl *This = impl_from_IEnumFORMATETC(iface);
62
TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
66
if(IsEqualIID(riid, &IID_IUnknown))
70
else if(IsEqualIID(riid, &IID_IEnumFORMATETC))
77
IUnknown_AddRef((IUnknown*)(*ppvObj));
78
TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
81
TRACE("-- Interface: E_NOINTERFACE\n");
85
static ULONG WINAPI IEnumFORMATETC_fnAddRef(LPENUMFORMATETC iface)
87
IEnumFORMATETCImpl *This = impl_from_IEnumFORMATETC(iface);
88
ULONG refCount = InterlockedIncrement(&This->ref);
90
TRACE("(%p)->(count=%u)\n", This, refCount - 1);
95
static ULONG WINAPI IEnumFORMATETC_fnRelease(LPENUMFORMATETC iface)
97
IEnumFORMATETCImpl *This = impl_from_IEnumFORMATETC(iface);
98
ULONG refCount = InterlockedDecrement(&This->ref);
100
TRACE("(%p)->(%u)\n", This, refCount + 1);
104
TRACE(" destroying IEnumFORMATETC(%p)\n",This);
106
HeapFree(GetProcessHeap(),0,This);
112
static HRESULT WINAPI IEnumFORMATETC_fnNext(LPENUMFORMATETC iface, ULONG celt, FORMATETC *rgelt, ULONG *pceltFethed)
114
IEnumFORMATETCImpl *This = impl_from_IEnumFORMATETC(iface);
117
TRACE("(%p)->(%u,%p)\n", This, celt, rgelt);
119
if(!This->pFmt)return S_FALSE;
120
if(!rgelt) return E_INVALIDARG;
121
if (pceltFethed) *pceltFethed = 0;
123
for(i = 0; This->posFmt < This->countFmt && celt > i; i++)
125
*rgelt++ = This->pFmt[This->posFmt++];
128
if (pceltFethed) *pceltFethed = i;
130
return ((i == celt) ? S_OK : S_FALSE);
133
static HRESULT WINAPI IEnumFORMATETC_fnSkip(LPENUMFORMATETC iface, ULONG celt)
135
IEnumFORMATETCImpl *This = impl_from_IEnumFORMATETC(iface);
136
TRACE("(%p)->(num=%u)\n", This, celt);
138
if((This->posFmt + celt) >= This->countFmt) return S_FALSE;
139
This->posFmt += celt;
143
static HRESULT WINAPI IEnumFORMATETC_fnReset(LPENUMFORMATETC iface)
145
IEnumFORMATETCImpl *This = impl_from_IEnumFORMATETC(iface);
146
TRACE("(%p)->()\n", This);
152
static HRESULT WINAPI IEnumFORMATETC_fnClone(LPENUMFORMATETC iface, LPENUMFORMATETC* ppenum)
154
IEnumFORMATETCImpl *This = impl_from_IEnumFORMATETC(iface);
155
TRACE("(%p)->(ppenum=%p)\n", This, ppenum);
157
if (!ppenum) return E_INVALIDARG;
158
*ppenum = IEnumFORMATETC_Constructor(This->countFmt, This->pFmt);
160
IEnumFORMATETC_fnSkip(*ppenum, This->posFmt);
164
static const IEnumFORMATETCVtbl efvt =
166
IEnumFORMATETC_fnQueryInterface,
167
IEnumFORMATETC_fnAddRef,
168
IEnumFORMATETC_fnRelease,
169
IEnumFORMATETC_fnNext,
170
IEnumFORMATETC_fnSkip,
171
IEnumFORMATETC_fnReset,
172
IEnumFORMATETC_fnClone
175
LPENUMFORMATETC IEnumFORMATETC_Constructor(UINT cfmt, const FORMATETC afmt[])
177
IEnumFORMATETCImpl* ef;
178
DWORD size=cfmt * sizeof(FORMATETC);
180
ef = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IEnumFORMATETCImpl));
185
ef->IEnumFORMATETC_iface.lpVtbl = &efvt;
188
ef->pFmt = SHAlloc (size);
191
memcpy(ef->pFmt, afmt, size);
194
TRACE("(%p)->(%u,%p)\n",ef, cfmt, afmt);
195
return (LPENUMFORMATETC)ef;
199
/***********************************************************************
200
* IDataObject implementation
203
/* number of supported formats */
204
#define MAX_FORMATS 4
208
/* IUnknown fields */
209
IDataObject IDataObject_iface;
212
/* IDataObject fields */
214
LPITEMIDLIST * apidl;
217
FORMATETC pFormatEtc[MAX_FORMATS];
224
static inline IDataObjectImpl *impl_from_IDataObject(IDataObject *iface)
226
return CONTAINING_RECORD(iface, IDataObjectImpl, IDataObject_iface);
229
/***************************************************************************
230
* IDataObject_QueryInterface
232
static HRESULT WINAPI IDataObject_fnQueryInterface(LPDATAOBJECT iface, REFIID riid, LPVOID * ppvObj)
234
IDataObjectImpl *This = impl_from_IDataObject(iface);
235
TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
239
if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/
243
else if(IsEqualIID(riid, &IID_IDataObject)) /*IDataObject*/
250
IUnknown_AddRef((IUnknown*)*ppvObj);
251
TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
254
TRACE("-- Interface: E_NOINTERFACE\n");
255
return E_NOINTERFACE;
258
/**************************************************************************
261
static ULONG WINAPI IDataObject_fnAddRef(LPDATAOBJECT iface)
263
IDataObjectImpl *This = impl_from_IDataObject(iface);
264
ULONG refCount = InterlockedIncrement(&This->ref);
266
TRACE("(%p)->(count=%u)\n", This, refCount - 1);
271
/**************************************************************************
272
* IDataObject_Release
274
static ULONG WINAPI IDataObject_fnRelease(LPDATAOBJECT iface)
276
IDataObjectImpl *This = impl_from_IDataObject(iface);
277
ULONG refCount = InterlockedDecrement(&This->ref);
279
TRACE("(%p)->(%u)\n", This, refCount + 1);
283
TRACE(" destroying IDataObject(%p)\n",This);
284
_ILFreeaPidl(This->apidl, This->cidl);
286
HeapFree(GetProcessHeap(),0,This);
291
/**************************************************************************
292
* IDataObject_fnGetData
294
static HRESULT WINAPI IDataObject_fnGetData(LPDATAOBJECT iface, LPFORMATETC pformatetcIn, STGMEDIUM *pmedium)
296
IDataObjectImpl *This = impl_from_IDataObject(iface);
301
GetClipboardFormatNameA (pformatetcIn->cfFormat, szTemp, 256);
302
TRACE("(%p)->(%p %p format=%s)\n", This, pformatetcIn, pmedium, szTemp);
304
if (pformatetcIn->cfFormat == This->cfShellIDList)
306
if (This->cidl < 1) return(E_UNEXPECTED);
307
pmedium->u.hGlobal = RenderSHELLIDLIST(This->pidl, This->apidl, This->cidl);
309
else if (pformatetcIn->cfFormat == CF_HDROP)
311
if (This->cidl < 1) return(E_UNEXPECTED);
312
pmedium->u.hGlobal = RenderHDROP(This->pidl, This->apidl, This->cidl);
314
else if (pformatetcIn->cfFormat == This->cfFileNameA)
316
if (This->cidl < 1) return(E_UNEXPECTED);
317
pmedium->u.hGlobal = RenderFILENAMEA(This->pidl, This->apidl, This->cidl);
319
else if (pformatetcIn->cfFormat == This->cfFileNameW)
321
if (This->cidl < 1) return(E_UNEXPECTED);
322
pmedium->u.hGlobal = RenderFILENAMEW(This->pidl, This->apidl, This->cidl);
326
FIXME("-- expected clipformat not implemented\n");
327
return (E_INVALIDARG);
329
if (pmedium->u.hGlobal)
331
pmedium->tymed = TYMED_HGLOBAL;
332
pmedium->pUnkForRelease = NULL;
335
return E_OUTOFMEMORY;
338
static HRESULT WINAPI IDataObject_fnGetDataHere(LPDATAOBJECT iface, LPFORMATETC pformatetc, STGMEDIUM *pmedium)
340
IDataObjectImpl *This = impl_from_IDataObject(iface);
341
FIXME("(%p)->()\n", This);
345
static HRESULT WINAPI IDataObject_fnQueryGetData(LPDATAOBJECT iface, LPFORMATETC pformatetc)
347
IDataObjectImpl *This = impl_from_IDataObject(iface);
350
TRACE("(%p)->(fmt=0x%08x tym=0x%08x)\n", This, pformatetc->cfFormat, pformatetc->tymed);
352
if(!(DVASPECT_CONTENT & pformatetc->dwAspect))
353
return DV_E_DVASPECT;
355
/* check our formats table what we have */
356
for (i=0; i<MAX_FORMATS; i++)
358
if ((This->pFormatEtc[i].cfFormat == pformatetc->cfFormat)
359
&& (This->pFormatEtc[i].tymed == pformatetc->tymed))
368
static HRESULT WINAPI IDataObject_fnGetCanonicalFormatEtc(LPDATAOBJECT iface, LPFORMATETC pformatectIn, LPFORMATETC pformatetcOut)
370
IDataObjectImpl *This = impl_from_IDataObject(iface);
371
FIXME("(%p)->()\n", This);
375
static HRESULT WINAPI IDataObject_fnSetData(LPDATAOBJECT iface, LPFORMATETC pformatetc, STGMEDIUM *pmedium, BOOL fRelease)
377
IDataObjectImpl *This = impl_from_IDataObject(iface);
378
FIXME("(%p)->()\n", This);
382
static HRESULT WINAPI IDataObject_fnEnumFormatEtc(LPDATAOBJECT iface, DWORD dwDirection, IEnumFORMATETC **ppenumFormatEtc)
384
IDataObjectImpl *This = impl_from_IDataObject(iface);
386
TRACE("(%p)->()\n", This);
387
*ppenumFormatEtc=NULL;
390
if (DATADIR_GET == dwDirection)
392
*ppenumFormatEtc = IEnumFORMATETC_Constructor(MAX_FORMATS, This->pFormatEtc);
393
return (*ppenumFormatEtc) ? S_OK : E_FAIL;
399
static HRESULT WINAPI IDataObject_fnDAdvise(LPDATAOBJECT iface, FORMATETC *pformatetc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection)
401
IDataObjectImpl *This = impl_from_IDataObject(iface);
402
FIXME("(%p)->()\n", This);
405
static HRESULT WINAPI IDataObject_fnDUnadvise(LPDATAOBJECT iface, DWORD dwConnection)
407
IDataObjectImpl *This = impl_from_IDataObject(iface);
408
FIXME("(%p)->()\n", This);
411
static HRESULT WINAPI IDataObject_fnEnumDAdvise(LPDATAOBJECT iface, IEnumSTATDATA **ppenumAdvise)
413
IDataObjectImpl *This = impl_from_IDataObject(iface);
414
FIXME("(%p)->()\n", This);
418
static const IDataObjectVtbl dtovt =
420
IDataObject_fnQueryInterface,
421
IDataObject_fnAddRef,
422
IDataObject_fnRelease,
423
IDataObject_fnGetData,
424
IDataObject_fnGetDataHere,
425
IDataObject_fnQueryGetData,
426
IDataObject_fnGetCanonicalFormatEtc,
427
IDataObject_fnSetData,
428
IDataObject_fnEnumFormatEtc,
429
IDataObject_fnDAdvise,
430
IDataObject_fnDUnadvise,
431
IDataObject_fnEnumDAdvise
434
/**************************************************************************
435
* IDataObject_Constructor
437
LPDATAOBJECT IDataObject_Constructor(HWND hwndOwner,
438
LPCITEMIDLIST pMyPidl, LPCITEMIDLIST * apidl, UINT cidl)
440
IDataObjectImpl* dto;
442
dto = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDataObjectImpl));
447
dto->IDataObject_iface.lpVtbl = &dtovt;
448
dto->pidl = ILClone(pMyPidl);
449
dto->apidl = _ILCopyaPidl(apidl, cidl);
452
dto->cfShellIDList = RegisterClipboardFormatW(CFSTR_SHELLIDLISTW);
453
dto->cfFileNameA = RegisterClipboardFormatA(CFSTR_FILENAMEA);
454
dto->cfFileNameW = RegisterClipboardFormatW(CFSTR_FILENAMEW);
455
InitFormatEtc(dto->pFormatEtc[0], dto->cfShellIDList, TYMED_HGLOBAL);
456
InitFormatEtc(dto->pFormatEtc[1], CF_HDROP, TYMED_HGLOBAL);
457
InitFormatEtc(dto->pFormatEtc[2], dto->cfFileNameA, TYMED_HGLOBAL);
458
InitFormatEtc(dto->pFormatEtc[3], dto->cfFileNameW, TYMED_HGLOBAL);
461
TRACE("(%p)->(apidl=%p cidl=%u)\n",dto, apidl, cidl);
462
return (LPDATAOBJECT)dto;