source: trunk/src/shell32/dataobject.c@ 5087

Last change on this file since 5087 was 4121, checked in by sandervl, 25 years ago

complete merge with shell32 from wine 20000801

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