~ubuntu-branches/ubuntu/natty/wine1.3/natty

« back to all changes in this revision

Viewing changes to dlls/shell32/dataobject.c

  • Committer: Bazaar Package Importer
  • Author(s): Scott Ritchie
  • Date: 2011-03-09 05:50:55 UTC
  • Revision ID: james.westby@ubuntu.com-20110309055055-oc6dml4hruy8wa4r
Tags: upstream-1.3.15
ImportĀ upstreamĀ versionĀ 1.3.15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *      IEnumFORMATETC, IDataObject
 
3
 *
 
4
 * selecting and dropping objects within the shell and/or common dialogs
 
5
 *
 
6
 *      Copyright 1998, 1999    <juergen.schmied@metronet.de>
 
7
 *
 
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.
 
12
 *
 
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.
 
17
 *
 
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
 
21
 */
 
22
#include <string.h>
 
23
 
 
24
#define COBJMACROS
 
25
#define NONAMELESSUNION
 
26
#define NONAMELESSSTRUCT
 
27
 
 
28
#include "windef.h"
 
29
#include "wingdi.h"
 
30
#include "pidl.h"
 
31
#include "winerror.h"
 
32
#include "shell32_main.h"
 
33
#include "wine/debug.h"
 
34
#include "undocshell.h"
 
35
 
 
36
WINE_DEFAULT_DEBUG_CHANNEL(shell);
 
37
 
 
38
/***********************************************************************
 
39
*   IEnumFORMATETC implementation
 
40
*/
 
41
 
 
42
typedef struct
 
43
{
 
44
    /* IUnknown fields */
 
45
    IEnumFORMATETC IEnumFORMATETC_iface;
 
46
    LONG           ref;
 
47
    /* IEnumFORMATETC fields */
 
48
    UINT        posFmt;
 
49
    UINT        countFmt;
 
50
    LPFORMATETC pFmt;
 
51
} IEnumFORMATETCImpl;
 
52
 
 
53
static inline IEnumFORMATETCImpl *impl_from_IEnumFORMATETC(IEnumFORMATETC *iface)
 
54
{
 
55
        return CONTAINING_RECORD(iface, IEnumFORMATETCImpl, IEnumFORMATETC_iface);
 
56
}
 
57
 
 
58
static HRESULT WINAPI IEnumFORMATETC_fnQueryInterface(
 
59
               LPENUMFORMATETC iface, REFIID riid, LPVOID* ppvObj)
 
60
{
 
61
        IEnumFORMATETCImpl *This = impl_from_IEnumFORMATETC(iface);
 
62
        TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
 
63
 
 
64
        *ppvObj = NULL;
 
65
 
 
66
        if(IsEqualIID(riid, &IID_IUnknown))
 
67
        {
 
68
          *ppvObj = This;
 
69
        }
 
70
        else if(IsEqualIID(riid, &IID_IEnumFORMATETC))
 
71
        {
 
72
          *ppvObj = This;
 
73
        }
 
74
 
 
75
        if(*ppvObj)
 
76
        {
 
77
          IUnknown_AddRef((IUnknown*)(*ppvObj));
 
78
          TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
 
79
          return S_OK;
 
80
        }
 
81
        TRACE("-- Interface: E_NOINTERFACE\n");
 
82
        return E_NOINTERFACE;
 
83
}
 
84
 
 
85
static ULONG WINAPI IEnumFORMATETC_fnAddRef(LPENUMFORMATETC iface)
 
86
{
 
87
        IEnumFORMATETCImpl *This = impl_from_IEnumFORMATETC(iface);
 
88
        ULONG refCount = InterlockedIncrement(&This->ref);
 
89
 
 
90
        TRACE("(%p)->(count=%u)\n", This, refCount - 1);
 
91
 
 
92
        return refCount;
 
93
}
 
94
 
 
95
static ULONG WINAPI IEnumFORMATETC_fnRelease(LPENUMFORMATETC iface)
 
96
{
 
97
        IEnumFORMATETCImpl *This = impl_from_IEnumFORMATETC(iface);
 
98
        ULONG refCount = InterlockedDecrement(&This->ref);
 
99
 
 
100
        TRACE("(%p)->(%u)\n", This, refCount + 1);
 
101
 
 
102
        if (!refCount)
 
103
        {
 
104
          TRACE(" destroying IEnumFORMATETC(%p)\n",This);
 
105
          SHFree (This->pFmt);
 
106
          HeapFree(GetProcessHeap(),0,This);
 
107
          return 0;
 
108
        }
 
109
        return refCount;
 
110
}
 
111
 
 
112
static HRESULT WINAPI IEnumFORMATETC_fnNext(LPENUMFORMATETC iface, ULONG celt, FORMATETC *rgelt, ULONG *pceltFethed)
 
113
{
 
114
        IEnumFORMATETCImpl *This = impl_from_IEnumFORMATETC(iface);
 
115
        UINT i;
 
116
 
 
117
        TRACE("(%p)->(%u,%p)\n", This, celt, rgelt);
 
118
 
 
119
        if(!This->pFmt)return S_FALSE;
 
120
        if(!rgelt) return E_INVALIDARG;
 
121
        if (pceltFethed)  *pceltFethed = 0;
 
122
 
 
123
        for(i = 0; This->posFmt < This->countFmt && celt > i; i++)
 
124
        {
 
125
          *rgelt++ = This->pFmt[This->posFmt++];
 
126
        }
 
127
 
 
128
        if (pceltFethed) *pceltFethed = i;
 
129
 
 
130
        return ((i == celt) ? S_OK : S_FALSE);
 
131
}
 
132
 
 
133
static HRESULT WINAPI IEnumFORMATETC_fnSkip(LPENUMFORMATETC iface, ULONG celt)
 
134
{
 
135
        IEnumFORMATETCImpl *This = impl_from_IEnumFORMATETC(iface);
 
136
        TRACE("(%p)->(num=%u)\n", This, celt);
 
137
 
 
138
        if((This->posFmt + celt) >= This->countFmt) return S_FALSE;
 
139
        This->posFmt += celt;
 
140
        return S_OK;
 
141
}
 
142
 
 
143
static HRESULT WINAPI IEnumFORMATETC_fnReset(LPENUMFORMATETC iface)
 
144
{
 
145
        IEnumFORMATETCImpl *This = impl_from_IEnumFORMATETC(iface);
 
146
        TRACE("(%p)->()\n", This);
 
147
 
 
148
        This->posFmt = 0;
 
149
        return S_OK;
 
150
}
 
151
 
 
152
static HRESULT WINAPI IEnumFORMATETC_fnClone(LPENUMFORMATETC iface, LPENUMFORMATETC* ppenum)
 
153
{
 
154
        IEnumFORMATETCImpl *This = impl_from_IEnumFORMATETC(iface);
 
155
        TRACE("(%p)->(ppenum=%p)\n", This, ppenum);
 
156
 
 
157
        if (!ppenum) return E_INVALIDARG;
 
158
        *ppenum = IEnumFORMATETC_Constructor(This->countFmt, This->pFmt);
 
159
        if(*ppenum)
 
160
           IEnumFORMATETC_fnSkip(*ppenum, This->posFmt);
 
161
        return S_OK;
 
162
}
 
163
 
 
164
static const IEnumFORMATETCVtbl efvt =
 
165
{
 
166
    IEnumFORMATETC_fnQueryInterface,
 
167
    IEnumFORMATETC_fnAddRef,
 
168
    IEnumFORMATETC_fnRelease,
 
169
    IEnumFORMATETC_fnNext,
 
170
    IEnumFORMATETC_fnSkip,
 
171
    IEnumFORMATETC_fnReset,
 
172
    IEnumFORMATETC_fnClone
 
173
};
 
174
 
 
175
LPENUMFORMATETC IEnumFORMATETC_Constructor(UINT cfmt, const FORMATETC afmt[])
 
176
{
 
177
    IEnumFORMATETCImpl* ef;
 
178
    DWORD size=cfmt * sizeof(FORMATETC);
 
179
 
 
180
    ef = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IEnumFORMATETCImpl));
 
181
 
 
182
    if(ef)
 
183
    {
 
184
        ef->ref=1;
 
185
        ef->IEnumFORMATETC_iface.lpVtbl = &efvt;
 
186
 
 
187
        ef->countFmt = cfmt;
 
188
        ef->pFmt = SHAlloc (size);
 
189
 
 
190
        if (ef->pFmt)
 
191
            memcpy(ef->pFmt, afmt, size);
 
192
    }
 
193
 
 
194
    TRACE("(%p)->(%u,%p)\n",ef, cfmt, afmt);
 
195
    return (LPENUMFORMATETC)ef;
 
196
}
 
197
 
 
198
 
 
199
/***********************************************************************
 
200
*   IDataObject implementation
 
201
*/
 
202
 
 
203
/* number of supported formats */
 
204
#define MAX_FORMATS 4
 
205
 
 
206
typedef struct
 
207
{
 
208
        /* IUnknown fields */
 
209
        IDataObject IDataObject_iface;
 
210
        LONG        ref;
 
211
 
 
212
        /* IDataObject fields */
 
213
        LPITEMIDLIST    pidl;
 
214
        LPITEMIDLIST *  apidl;
 
215
        UINT            cidl;
 
216
 
 
217
        FORMATETC       pFormatEtc[MAX_FORMATS];
 
218
        UINT            cfShellIDList;
 
219
        UINT            cfFileNameA;
 
220
        UINT            cfFileNameW;
 
221
 
 
222
} IDataObjectImpl;
 
223
 
 
224
static inline IDataObjectImpl *impl_from_IDataObject(IDataObject *iface)
 
225
{
 
226
        return CONTAINING_RECORD(iface, IDataObjectImpl, IDataObject_iface);
 
227
}
 
228
 
 
229
/***************************************************************************
 
230
*  IDataObject_QueryInterface
 
231
*/
 
232
static HRESULT WINAPI IDataObject_fnQueryInterface(LPDATAOBJECT iface, REFIID riid, LPVOID * ppvObj)
 
233
{
 
234
        IDataObjectImpl *This = impl_from_IDataObject(iface);
 
235
        TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
 
236
 
 
237
        *ppvObj = NULL;
 
238
 
 
239
        if(IsEqualIID(riid, &IID_IUnknown))          /*IUnknown*/
 
240
        {
 
241
          *ppvObj = This;
 
242
        }
 
243
        else if(IsEqualIID(riid, &IID_IDataObject))  /*IDataObject*/
 
244
        {
 
245
          *ppvObj = This;
 
246
        }
 
247
 
 
248
        if(*ppvObj)
 
249
        {
 
250
          IUnknown_AddRef((IUnknown*)*ppvObj);
 
251
          TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
 
252
          return S_OK;
 
253
        }
 
254
        TRACE("-- Interface: E_NOINTERFACE\n");
 
255
        return E_NOINTERFACE;
 
256
}
 
257
 
 
258
/**************************************************************************
 
259
*  IDataObject_AddRef
 
260
*/
 
261
static ULONG WINAPI IDataObject_fnAddRef(LPDATAOBJECT iface)
 
262
{
 
263
        IDataObjectImpl *This = impl_from_IDataObject(iface);
 
264
        ULONG refCount = InterlockedIncrement(&This->ref);
 
265
 
 
266
        TRACE("(%p)->(count=%u)\n", This, refCount - 1);
 
267
 
 
268
        return refCount;
 
269
}
 
270
 
 
271
/**************************************************************************
 
272
*  IDataObject_Release
 
273
*/
 
274
static ULONG WINAPI IDataObject_fnRelease(LPDATAOBJECT iface)
 
275
{
 
276
        IDataObjectImpl *This = impl_from_IDataObject(iface);
 
277
        ULONG refCount = InterlockedDecrement(&This->ref);
 
278
 
 
279
        TRACE("(%p)->(%u)\n", This, refCount + 1);
 
280
 
 
281
        if (!refCount)
 
282
        {
 
283
          TRACE(" destroying IDataObject(%p)\n",This);
 
284
          _ILFreeaPidl(This->apidl, This->cidl);
 
285
          ILFree(This->pidl),
 
286
          HeapFree(GetProcessHeap(),0,This);
 
287
        }
 
288
        return refCount;
 
289
}
 
290
 
 
291
/**************************************************************************
 
292
* IDataObject_fnGetData
 
293
*/
 
294
static HRESULT WINAPI IDataObject_fnGetData(LPDATAOBJECT iface, LPFORMATETC pformatetcIn, STGMEDIUM *pmedium)
 
295
{
 
296
        IDataObjectImpl *This = impl_from_IDataObject(iface);
 
297
 
 
298
        char    szTemp[256];
 
299
 
 
300
        szTemp[0]=0;
 
301
        GetClipboardFormatNameA (pformatetcIn->cfFormat, szTemp, 256);
 
302
        TRACE("(%p)->(%p %p format=%s)\n", This, pformatetcIn, pmedium, szTemp);
 
303
 
 
304
        if (pformatetcIn->cfFormat == This->cfShellIDList)
 
305
        {
 
306
          if (This->cidl < 1) return(E_UNEXPECTED);
 
307
          pmedium->u.hGlobal = RenderSHELLIDLIST(This->pidl, This->apidl, This->cidl);
 
308
        }
 
309
        else if (pformatetcIn->cfFormat == CF_HDROP)
 
310
        {
 
311
          if (This->cidl < 1) return(E_UNEXPECTED);
 
312
          pmedium->u.hGlobal = RenderHDROP(This->pidl, This->apidl, This->cidl);
 
313
        }
 
314
        else if (pformatetcIn->cfFormat == This->cfFileNameA)
 
315
        {
 
316
          if (This->cidl < 1) return(E_UNEXPECTED);
 
317
          pmedium->u.hGlobal = RenderFILENAMEA(This->pidl, This->apidl, This->cidl);
 
318
        }
 
319
        else if (pformatetcIn->cfFormat == This->cfFileNameW)
 
320
        {
 
321
          if (This->cidl < 1) return(E_UNEXPECTED);
 
322
          pmedium->u.hGlobal = RenderFILENAMEW(This->pidl, This->apidl, This->cidl);
 
323
        }
 
324
        else
 
325
        {
 
326
          FIXME("-- expected clipformat not implemented\n");
 
327
          return (E_INVALIDARG);
 
328
        }
 
329
        if (pmedium->u.hGlobal)
 
330
        {
 
331
          pmedium->tymed = TYMED_HGLOBAL;
 
332
          pmedium->pUnkForRelease = NULL;
 
333
          return S_OK;
 
334
        }
 
335
        return E_OUTOFMEMORY;
 
336
}
 
337
 
 
338
static HRESULT WINAPI IDataObject_fnGetDataHere(LPDATAOBJECT iface, LPFORMATETC pformatetc, STGMEDIUM *pmedium)
 
339
{
 
340
        IDataObjectImpl *This = impl_from_IDataObject(iface);
 
341
        FIXME("(%p)->()\n", This);
 
342
        return E_NOTIMPL;
 
343
}
 
344
 
 
345
static HRESULT WINAPI IDataObject_fnQueryGetData(LPDATAOBJECT iface, LPFORMATETC pformatetc)
 
346
{
 
347
        IDataObjectImpl *This = impl_from_IDataObject(iface);
 
348
        UINT i;
 
349
 
 
350
        TRACE("(%p)->(fmt=0x%08x tym=0x%08x)\n", This, pformatetc->cfFormat, pformatetc->tymed);
 
351
 
 
352
        if(!(DVASPECT_CONTENT & pformatetc->dwAspect))
 
353
          return DV_E_DVASPECT;
 
354
 
 
355
        /* check our formats table what we have */
 
356
        for (i=0; i<MAX_FORMATS; i++)
 
357
        {
 
358
          if ((This->pFormatEtc[i].cfFormat == pformatetc->cfFormat)
 
359
           && (This->pFormatEtc[i].tymed == pformatetc->tymed))
 
360
          {
 
361
            return S_OK;
 
362
          }
 
363
        }
 
364
 
 
365
        return DV_E_TYMED;
 
366
}
 
367
 
 
368
static HRESULT WINAPI IDataObject_fnGetCanonicalFormatEtc(LPDATAOBJECT iface, LPFORMATETC pformatectIn, LPFORMATETC pformatetcOut)
 
369
{
 
370
        IDataObjectImpl *This = impl_from_IDataObject(iface);
 
371
        FIXME("(%p)->()\n", This);
 
372
        return E_NOTIMPL;
 
373
}
 
374
 
 
375
static HRESULT WINAPI IDataObject_fnSetData(LPDATAOBJECT iface, LPFORMATETC pformatetc, STGMEDIUM *pmedium, BOOL fRelease)
 
376
{
 
377
        IDataObjectImpl *This = impl_from_IDataObject(iface);
 
378
        FIXME("(%p)->()\n", This);
 
379
        return E_NOTIMPL;
 
380
}
 
381
 
 
382
static HRESULT WINAPI IDataObject_fnEnumFormatEtc(LPDATAOBJECT iface, DWORD dwDirection, IEnumFORMATETC **ppenumFormatEtc)
 
383
{
 
384
        IDataObjectImpl *This = impl_from_IDataObject(iface);
 
385
 
 
386
        TRACE("(%p)->()\n", This);
 
387
        *ppenumFormatEtc=NULL;
 
388
 
 
389
        /* only get data */
 
390
        if (DATADIR_GET == dwDirection)
 
391
        {
 
392
          *ppenumFormatEtc = IEnumFORMATETC_Constructor(MAX_FORMATS, This->pFormatEtc);
 
393
          return (*ppenumFormatEtc) ? S_OK : E_FAIL;
 
394
        }
 
395
 
 
396
        return E_NOTIMPL;
 
397
}
 
398
 
 
399
static HRESULT WINAPI IDataObject_fnDAdvise(LPDATAOBJECT iface, FORMATETC *pformatetc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection)
 
400
{
 
401
        IDataObjectImpl *This = impl_from_IDataObject(iface);
 
402
        FIXME("(%p)->()\n", This);
 
403
        return E_NOTIMPL;
 
404
}
 
405
static HRESULT WINAPI IDataObject_fnDUnadvise(LPDATAOBJECT iface, DWORD dwConnection)
 
406
{
 
407
        IDataObjectImpl *This = impl_from_IDataObject(iface);
 
408
        FIXME("(%p)->()\n", This);
 
409
        return E_NOTIMPL;
 
410
}
 
411
static HRESULT WINAPI IDataObject_fnEnumDAdvise(LPDATAOBJECT iface, IEnumSTATDATA **ppenumAdvise)
 
412
{
 
413
        IDataObjectImpl *This = impl_from_IDataObject(iface);
 
414
        FIXME("(%p)->()\n", This);
 
415
        return E_NOTIMPL;
 
416
}
 
417
 
 
418
static const IDataObjectVtbl dtovt =
 
419
{
 
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
 
432
};
 
433
 
 
434
/**************************************************************************
 
435
*  IDataObject_Constructor
 
436
*/
 
437
LPDATAOBJECT IDataObject_Constructor(HWND hwndOwner,
 
438
               LPCITEMIDLIST pMyPidl, LPCITEMIDLIST * apidl, UINT cidl)
 
439
{
 
440
    IDataObjectImpl* dto;
 
441
 
 
442
    dto = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDataObjectImpl));
 
443
 
 
444
    if (dto)
 
445
    {
 
446
        dto->ref = 1;
 
447
        dto->IDataObject_iface.lpVtbl = &dtovt;
 
448
        dto->pidl = ILClone(pMyPidl);
 
449
        dto->apidl = _ILCopyaPidl(apidl, cidl);
 
450
        dto->cidl = cidl;
 
451
 
 
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);
 
459
    }
 
460
 
 
461
    TRACE("(%p)->(apidl=%p cidl=%u)\n",dto, apidl, cidl);
 
462
    return (LPDATAOBJECT)dto;
 
463
}