Moved more things to the X11 driver.
[wine/multimedia.git] / dlls / shell32 / dataobject.c
blob0bc6bf56b78360cb7ccb3adaaeac5a628b8ec492
1 /*
2 * IEnumFORMATETC, IDataObject
4 * selecting and droping objects within the shell and/or common dialogs
6 * Copyright 1998 <juergen.schmied@metronet.de>
7 */
8 #include "debug.h"
9 #include "wintypes.h"
10 #include "shlobj.h"
11 #include "pidl.h"
12 #include "winerror.h"
13 #include "shell32_main.h"
15 UINT32 cfShellIDList=0;
16 UINT32 cfFileGroupDesc=0;
17 UINT32 cfFileContents=0;
19 /***********************************************************************
20 * IEnumFORMATETC implementation
22 static HRESULT WINAPI IEnumFORMATETC_QueryInterface (LPENUMFORMATETC this, REFIID riid, LPVOID * ppvObj);
23 static ULONG WINAPI IEnumFORMATETC_AddRef (LPENUMFORMATETC this);
24 static ULONG WINAPI IEnumFORMATETC_Release (LPENUMFORMATETC this);
25 static HRESULT WINAPI IEnumFORMATETC_Next(LPENUMFORMATETC this, ULONG celt, FORMATETC32 *rgelt, ULONG *pceltFethed);
26 static HRESULT WINAPI IEnumFORMATETC_Skip(LPENUMFORMATETC this, ULONG celt);
27 static HRESULT WINAPI IEnumFORMATETC_Reset(LPENUMFORMATETC this);
28 static HRESULT WINAPI IEnumFORMATETC_Clone(LPENUMFORMATETC this, LPENUMFORMATETC* ppenum);
30 static struct IEnumFORMATETC_VTable efvt =
31 { IEnumFORMATETC_QueryInterface,
32 IEnumFORMATETC_AddRef,
33 IEnumFORMATETC_Release,
34 IEnumFORMATETC_Next,
35 IEnumFORMATETC_Skip,
36 IEnumFORMATETC_Reset,
37 IEnumFORMATETC_Clone
40 extern LPENUMFORMATETC IEnumFORMATETC_Constructor(UINT32 cfmt, const FORMATETC32 afmt[])
41 { LPENUMFORMATETC ef;
42 DWORD size=cfmt * sizeof(FORMATETC32);
44 ef=(LPENUMFORMATETC)HeapAlloc(GetProcessHeap(),0,sizeof(IEnumFORMATETC));
45 ef->ref=1;
46 ef->lpvtbl=&efvt;
48 ef->posFmt = 0;
49 ef->countFmt = cfmt;
50 ef->pFmt = SHAlloc (size);
52 if (ef->pFmt)
53 { memcpy(ef->pFmt, afmt, size);
56 TRACE(shell,"(%p)->()\n",ef);
57 return ef;
59 static HRESULT WINAPI IEnumFORMATETC_QueryInterface (LPENUMFORMATETC this, REFIID riid, LPVOID * ppvObj)
60 { char xriid[50];
61 WINE_StringFromCLSID((LPCLSID)riid,xriid);
62 TRACE(shell,"(%p)->(\n\tIID:\t%s,%p)\n",this,xriid,ppvObj);
64 *ppvObj = NULL;
66 if(IsEqualIID(riid, &IID_IUnknown))
67 { *ppvObj = this;
69 else if(IsEqualIID(riid, &IID_IEnumFORMATETC))
70 { *ppvObj = (IDataObject*)this;
73 if(*ppvObj)
74 { (*(LPENUMFORMATETC*)ppvObj)->lpvtbl->fnAddRef(this);
75 TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
76 return S_OK;
78 TRACE(shell,"-- Interface: E_NOINTERFACE\n");
79 return E_NOINTERFACE;
82 static ULONG WINAPI IEnumFORMATETC_AddRef (LPENUMFORMATETC this)
83 { TRACE(shell,"(%p)->(count=%lu)\n",this,(this->ref)+1);
84 return ++(this->ref);
86 static ULONG WINAPI IEnumFORMATETC_Release (LPENUMFORMATETC this)
87 { TRACE(shell,"(%p)->()\n",this);
88 if (!--(this->ref))
89 { TRACE(shell," destroying IEnumFORMATETC(%p)\n",this);
90 if (this->pFmt)
91 { SHFree (this->pFmt);
93 HeapFree(GetProcessHeap(),0,this);
94 return 0;
96 return this->ref;
98 static HRESULT WINAPI IEnumFORMATETC_Next(LPENUMFORMATETC this, ULONG celt, FORMATETC32 *rgelt, ULONG *pceltFethed)
99 { UINT32 cfetch;
100 HRESULT hres = S_FALSE;
102 TRACE (shell, "(%p)->()\n", this);
104 if (this->posFmt < this->countFmt)
105 { cfetch = this->countFmt - this->posFmt;
106 if (cfetch >= celt)
107 { cfetch = celt;
108 hres = S_OK;
110 memcpy(rgelt, &this->pFmt[this->posFmt], cfetch * sizeof(FORMATETC32));
111 this->posFmt += cfetch;
113 else
114 { cfetch = 0;
117 if (pceltFethed)
118 { *pceltFethed = cfetch;
121 return hres;
123 static HRESULT WINAPI IEnumFORMATETC_Skip(LPENUMFORMATETC this, ULONG celt)
124 { FIXME (shell, "(%p)->(num=%lu)\n", this, celt);
126 this->posFmt += celt;
127 if (this->posFmt > this->countFmt)
128 { this->posFmt = this->countFmt;
129 return S_FALSE;
131 return S_OK;
133 static HRESULT WINAPI IEnumFORMATETC_Reset(LPENUMFORMATETC this)
134 { FIXME (shell, "(%p)->()\n", this);
136 this->posFmt = 0;
137 return S_OK;
139 static HRESULT WINAPI IEnumFORMATETC_Clone(LPENUMFORMATETC this, LPENUMFORMATETC* ppenum)
140 { FIXME (shell, "(%p)->(ppenum=%p)\n", this, ppenum);
141 return E_NOTIMPL;
144 /***********************************************************************
145 * IDataObject implementation
148 static HRESULT WINAPI IDataObject_QueryInterface (LPDATAOBJECT, REFIID riid, LPVOID * ppvObj);
149 static ULONG WINAPI IDataObject_AddRef (LPDATAOBJECT);
150 static ULONG WINAPI IDataObject_Release (LPDATAOBJECT);
151 static HRESULT WINAPI IDataObject_GetData (LPDATAOBJECT, LPFORMATETC32 pformatetcIn, STGMEDIUM32 *pmedium);
152 static HRESULT WINAPI IDataObject_GetDataHere(LPDATAOBJECT, LPFORMATETC32 pformatetc, STGMEDIUM32 *pmedium);
153 static HRESULT WINAPI IDataObject_QueryGetData(LPDATAOBJECT, LPFORMATETC32 pformatetc);
154 static HRESULT WINAPI IDataObject_GetCanonicalFormatEtc(LPDATAOBJECT, LPFORMATETC32 pformatectIn, LPFORMATETC32 pformatetcOut);
155 static HRESULT WINAPI IDataObject_SetData(LPDATAOBJECT, LPFORMATETC32 pformatetc, STGMEDIUM32 *pmedium, BOOL32 fRelease);
156 static HRESULT WINAPI IDataObject_EnumFormatEtc(LPDATAOBJECT, DWORD dwDirection, IEnumFORMATETC **ppenumFormatEtc);
157 static HRESULT WINAPI IDataObject_DAdvise (LPDATAOBJECT, LPFORMATETC32 *pformatetc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection);
158 static HRESULT WINAPI IDataObject_DUnadvise(LPDATAOBJECT, DWORD dwConnection);
159 static HRESULT WINAPI IDataObject_EnumDAdvise(LPDATAOBJECT, IEnumSTATDATA **ppenumAdvise);
161 static struct IDataObject_VTable dtovt =
162 { IDataObject_QueryInterface,
163 IDataObject_AddRef,
164 IDataObject_Release,
165 IDataObject_GetData,
166 IDataObject_GetDataHere,
167 IDataObject_QueryGetData,
168 IDataObject_GetCanonicalFormatEtc,
169 IDataObject_SetData,
170 IDataObject_EnumFormatEtc,
171 IDataObject_DAdvise,
172 IDataObject_DUnadvise,
173 IDataObject_EnumDAdvise
176 /**************************************************************************
177 * IDataObject_Constructor
179 LPDATAOBJECT IDataObject_Constructor(HWND32 hwndOwner, LPSHELLFOLDER psf, LPITEMIDLIST * apidl, UINT32 cidl)
180 { LPDATAOBJECT dto;
181 if (!(dto = (LPDATAOBJECT)HeapAlloc(GetProcessHeap(),0,sizeof(IDataObject))))
182 return NULL;
184 dto->ref=1;
185 dto->lpvtbl=&dtovt;
186 dto->psf=psf;
187 dto->pidl=ILClone(psf->mpidl); /* FIXME:add a reference and don't copy*/
189 /* fill the ItemID List List */
190 dto->lpill = IDLList_Constructor (8);
191 if (! dto->lpill )
192 return NULL;
194 dto->lpill->lpvtbl->fnAddItems(dto->lpill, apidl, cidl);
196 TRACE(shell,"(%p)->(sf=%p apidl=%p cidl=%u)\n",dto, psf, apidl, cidl);
197 return dto;
199 /***************************************************************************
200 * IDataObject_QueryInterface
202 static HRESULT WINAPI IDataObject_QueryInterface (LPDATAOBJECT this, REFIID riid, LPVOID * ppvObj)
203 { char xriid[50];
204 WINE_StringFromCLSID((LPCLSID)riid,xriid);
205 TRACE(shell,"(%p)->(\n\tIID:\t%s,%p)\n",this,xriid,ppvObj);
207 *ppvObj = NULL;
209 if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/
210 { *ppvObj = this;
212 else if(IsEqualIID(riid, &IID_IDataObject)) /*IDataObject*/
213 { *ppvObj = (IDataObject*)this;
216 if(*ppvObj)
217 { (*(LPDATAOBJECT*)ppvObj)->lpvtbl->fnAddRef(this);
218 TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
219 return S_OK;
221 TRACE(shell,"-- Interface: E_NOINTERFACE\n");
222 return E_NOINTERFACE;
224 /**************************************************************************
225 * IDataObject_AddRef
227 static ULONG WINAPI IDataObject_AddRef(LPDATAOBJECT this)
228 { TRACE(shell,"(%p)->(count=%lu)\n",this,(this->ref)+1);
229 return ++(this->ref);
231 /**************************************************************************
232 * IDataObject_Release
234 static ULONG WINAPI IDataObject_Release(LPDATAOBJECT this)
235 { TRACE(shell,"(%p)->()\n",this);
236 if (!--(this->ref))
237 { TRACE(shell," destroying IDataObject(%p)\n",this);
238 IDLList_Destructor(this->lpill);
239 HeapFree(GetProcessHeap(),0,this);
240 return 0;
242 return this->ref;
244 /**************************************************************************
245 * DATAOBJECT_InitShellIDList (internal)
247 * NOTES
248 * get or register the "Shell IDList Array" clipformat
250 static BOOL32 DATAOBJECT_InitShellIDList(void)
251 { if (cfShellIDList)
252 { return(TRUE);
255 cfShellIDList = RegisterClipboardFormat32A(CFSTR_SHELLIDLIST);
256 return(cfShellIDList != 0);
259 /**************************************************************************
260 * DATAOBJECT_InitFileGroupDesc (internal)
262 * NOTES
263 * get or register the "FileGroupDescriptor" clipformat
265 static BOOL32 DATAOBJECT_InitFileGroupDesc(void)
266 { if (cfFileGroupDesc)
267 { return(TRUE);
270 cfFileGroupDesc = RegisterClipboardFormat32A(CFSTR_FILEDESCRIPTORA);
271 return(cfFileGroupDesc != 0);
273 /**************************************************************************
274 * DATAOBJECT_InitFileContents (internal)
276 * NOTES
277 * get or register the "FileContents" clipformat
279 static BOOL32 DATAOBJECT_InitFileContents(void)
280 { if (cfFileContents)
281 { return(TRUE);
284 cfFileContents = RegisterClipboardFormat32A(CFSTR_FILECONTENTS);
285 return(cfFileContents != 0);
289 /**************************************************************************
290 * interface implementation
292 static HRESULT WINAPI IDataObject_GetData (LPDATAOBJECT this, LPFORMATETC32 pformatetcIn, STGMEDIUM32 *pmedium)
293 { char temp[256];
294 UINT32 cItems;
295 DWORD size, size1, size2;
296 LPITEMIDLIST pidl;
297 LPCIDA pcida;
298 HGLOBAL32 hmem;
300 GetClipboardFormatName32A (pformatetcIn->cfFormat, temp, 256);
301 WARN (shell, "(%p)->(%p %p format=%s)semi-stub\n", this, pformatetcIn, pmedium, temp);
303 if (!DATAOBJECT_InitShellIDList()) /* is the clipformat registred? */
304 { return(E_UNEXPECTED);
307 if (pformatetcIn->cfFormat == cfShellIDList)
308 { if (pformatetcIn->ptd==NULL
309 && (pformatetcIn->dwAspect & DVASPECT_CONTENT)
310 && pformatetcIn->lindex==-1
311 && (pformatetcIn->tymed&TYMED_HGLOBAL))
312 { cItems = this->lpill->lpvtbl->fnGetCount(this->lpill);
313 if (cItems < 1)
314 { return(E_UNEXPECTED);
316 pidl = this->lpill->lpvtbl->fnGetElement(this->lpill, 0);
318 pdump(this->pidl);
319 pdump(pidl);
321 /*hack consider only the first item*/
322 cItems = 2;
323 size = sizeof(CIDA) + sizeof (UINT32)*(cItems-1);
324 size1 = ILGetSize (this->pidl);
325 size2 = ILGetSize (pidl);
326 hmem = GlobalAlloc32(GMEM_FIXED, size+size1+size2);
327 pcida = GlobalLock32 (hmem);
328 if (!pcida)
329 { return(E_OUTOFMEMORY);
332 pcida->cidl = 1;
333 pcida->aoffset[0] = size;
334 pcida->aoffset[1] = size+size1;
336 TRACE(shell,"-- %lu %lu %lu\n",size, size1, size2 );
337 TRACE(shell,"-- %p %p\n",this->pidl, pidl);
338 TRACE(shell,"-- %p %p %p\n",pcida, (LPBYTE)pcida+size,(LPBYTE)pcida+size+size1);
340 memcpy ((LPBYTE)pcida+size, this->pidl, size1);
341 memcpy ((LPBYTE)pcida+size+size1, pidl, size2);
342 TRACE(shell,"-- after copy\n");
344 GlobalUnlock32(hmem);
346 pmedium->tymed = TYMED_HGLOBAL;
347 pmedium->u.hGlobal = (HGLOBAL32)pcida;
348 pmedium->pUnkForRelease = NULL;
349 TRACE(shell,"-- ready\n");
350 return(NOERROR);
353 FIXME (shell, "-- clipformat not implemented\n");
354 return (E_INVALIDARG);
356 static HRESULT WINAPI IDataObject_GetDataHere(LPDATAOBJECT this, LPFORMATETC32 pformatetc, STGMEDIUM32 *pmedium)
357 { FIXME (shell, "(%p)->()\n", this);
358 return E_NOTIMPL;
360 static HRESULT WINAPI IDataObject_QueryGetData(LPDATAOBJECT this, LPFORMATETC32 pformatetc)
361 { FIXME (shell, "(%p)->()\n", this);
362 return E_NOTIMPL;
364 static HRESULT WINAPI IDataObject_GetCanonicalFormatEtc(LPDATAOBJECT this, LPFORMATETC32 pformatectIn, LPFORMATETC32 pformatetcOut)
365 { FIXME (shell, "(%p)->()\n", this);
366 return E_NOTIMPL;
368 static HRESULT WINAPI IDataObject_SetData(LPDATAOBJECT this, LPFORMATETC32 pformatetc, STGMEDIUM32 *pmedium, BOOL32 fRelease)
369 { FIXME (shell, "(%p)->()\n", this);
370 return E_NOTIMPL;
372 static HRESULT WINAPI IDataObject_EnumFormatEtc(LPDATAOBJECT this, DWORD dwDirection, IEnumFORMATETC **ppenumFormatEtc)
373 { FIXME (shell, "(%p)->()\n", this);
374 return E_NOTIMPL;
376 static HRESULT WINAPI IDataObject_DAdvise (LPDATAOBJECT this, LPFORMATETC32 *pformatetc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection)
377 { FIXME (shell, "(%p)->()\n", this);
378 return E_NOTIMPL;
380 static HRESULT WINAPI IDataObject_DUnadvise(LPDATAOBJECT this, DWORD dwConnection)
381 { FIXME (shell, "(%p)->()\n", this);
382 return E_NOTIMPL;
384 static HRESULT WINAPI IDataObject_EnumDAdvise(LPDATAOBJECT this, IEnumSTATDATA **ppenumAdvise)
385 { FIXME (shell, "(%p)->()\n", this);
386 return E_NOTIMPL;