2 * IEnumFORMATETC, IDataObject
4 * selecting and droping objects within the shell and/or common dialogs
6 * Copyright 1998 <juergen.schmied@metronet.de>
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,
40 extern LPENUMFORMATETC IEnumFORMATETC_Constructor(UINT32 cfmt, const FORMATETC32 afmt[])
42 DWORD size=cfmt * sizeof(FORMATETC32);
44 ef=(LPENUMFORMATETC)HeapAlloc(GetProcessHeap(),0,sizeof(IEnumFORMATETC));
50 ef->pFmt = SHAlloc (size);
53 { memcpy(ef->pFmt, afmt, size);
56 TRACE(shell,"(%p)->()\n",ef);
59 static HRESULT WINAPI IEnumFORMATETC_QueryInterface (LPENUMFORMATETC this, REFIID riid, LPVOID * ppvObj)
61 WINE_StringFromCLSID((LPCLSID)riid,xriid);
62 TRACE(shell,"(%p)->(\n\tIID:\t%s,%p)\n",this,xriid,ppvObj);
66 if(IsEqualIID(riid, &IID_IUnknown))
69 else if(IsEqualIID(riid, &IID_IEnumFORMATETC))
70 { *ppvObj = (IDataObject*)this;
74 { (*(LPENUMFORMATETC*)ppvObj)->lpvtbl->fnAddRef(this);
75 TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
78 TRACE(shell,"-- Interface: E_NOINTERFACE\n");
82 static ULONG WINAPI IEnumFORMATETC_AddRef (LPENUMFORMATETC this)
83 { TRACE(shell,"(%p)->(count=%lu)\n",this,(this->ref)+1);
86 static ULONG WINAPI IEnumFORMATETC_Release (LPENUMFORMATETC this)
87 { TRACE(shell,"(%p)->()\n",this);
89 { TRACE(shell," destroying IEnumFORMATETC(%p)\n",this);
91 { SHFree (this->pFmt);
93 HeapFree(GetProcessHeap(),0,this);
98 static HRESULT WINAPI IEnumFORMATETC_Next(LPENUMFORMATETC this, ULONG celt, FORMATETC32 *rgelt, ULONG *pceltFethed)
100 HRESULT hres = S_FALSE;
102 TRACE (shell, "(%p)->()\n", this);
104 if (this->posFmt < this->countFmt)
105 { cfetch = this->countFmt - this->posFmt;
110 memcpy(rgelt, &this->pFmt[this->posFmt], cfetch * sizeof(FORMATETC32));
111 this->posFmt += cfetch;
118 { *pceltFethed = cfetch;
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;
133 static HRESULT WINAPI IEnumFORMATETC_Reset(LPENUMFORMATETC this)
134 { FIXME (shell, "(%p)->()\n", this);
139 static HRESULT WINAPI IEnumFORMATETC_Clone(LPENUMFORMATETC this, LPENUMFORMATETC* ppenum)
140 { FIXME (shell, "(%p)->(ppenum=%p)\n", this, ppenum);
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,
166 IDataObject_GetDataHere,
167 IDataObject_QueryGetData,
168 IDataObject_GetCanonicalFormatEtc,
170 IDataObject_EnumFormatEtc,
172 IDataObject_DUnadvise,
173 IDataObject_EnumDAdvise
176 /**************************************************************************
177 * IDataObject_Constructor
179 LPDATAOBJECT IDataObject_Constructor(HWND32 hwndOwner, LPSHELLFOLDER psf, LPITEMIDLIST * apidl, UINT32 cidl)
181 if (!(dto = (LPDATAOBJECT)HeapAlloc(GetProcessHeap(),0,sizeof(IDataObject))))
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);
194 dto->lpill->lpvtbl->fnAddItems(dto->lpill, apidl, cidl);
196 TRACE(shell,"(%p)->(sf=%p apidl=%p cidl=%u)\n",dto, psf, apidl, cidl);
199 /***************************************************************************
200 * IDataObject_QueryInterface
202 static HRESULT WINAPI IDataObject_QueryInterface (LPDATAOBJECT this, REFIID riid, LPVOID * ppvObj)
204 WINE_StringFromCLSID((LPCLSID)riid,xriid);
205 TRACE(shell,"(%p)->(\n\tIID:\t%s,%p)\n",this,xriid,ppvObj);
209 if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/
212 else if(IsEqualIID(riid, &IID_IDataObject)) /*IDataObject*/
213 { *ppvObj = (IDataObject*)this;
217 { (*(LPDATAOBJECT*)ppvObj)->lpvtbl->fnAddRef(this);
218 TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
221 TRACE(shell,"-- Interface: E_NOINTERFACE\n");
222 return E_NOINTERFACE;
224 /**************************************************************************
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);
237 { TRACE(shell," destroying IDataObject(%p)\n",this);
238 IDLList_Destructor(this->lpill);
239 HeapFree(GetProcessHeap(),0,this);
244 /**************************************************************************
245 * DATAOBJECT_InitShellIDList (internal)
248 * get or register the "Shell IDList Array" clipformat
250 static BOOL32 DATAOBJECT_InitShellIDList(void)
255 cfShellIDList = RegisterClipboardFormat32A(CFSTR_SHELLIDLIST);
256 return(cfShellIDList != 0);
259 /**************************************************************************
260 * DATAOBJECT_InitFileGroupDesc (internal)
263 * get or register the "FileGroupDescriptor" clipformat
265 static BOOL32 DATAOBJECT_InitFileGroupDesc(void)
266 { if (cfFileGroupDesc)
270 cfFileGroupDesc = RegisterClipboardFormat32A(CFSTR_FILEDESCRIPTORA);
271 return(cfFileGroupDesc != 0);
273 /**************************************************************************
274 * DATAOBJECT_InitFileContents (internal)
277 * get or register the "FileContents" clipformat
279 static BOOL32 DATAOBJECT_InitFileContents(void)
280 { if (cfFileContents)
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)
295 DWORD size, size1, size2;
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);
314 { return(E_UNEXPECTED);
316 pidl = this->lpill->lpvtbl->fnGetElement(this->lpill, 0);
321 /*hack consider only the first item*/
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);
329 { return(E_OUTOFMEMORY);
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");
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);
360 static HRESULT WINAPI IDataObject_QueryGetData(LPDATAOBJECT this, LPFORMATETC32 pformatetc)
361 { FIXME (shell, "(%p)->()\n", this);
364 static HRESULT WINAPI IDataObject_GetCanonicalFormatEtc(LPDATAOBJECT this, LPFORMATETC32 pformatectIn, LPFORMATETC32 pformatetcOut)
365 { FIXME (shell, "(%p)->()\n", this);
368 static HRESULT WINAPI IDataObject_SetData(LPDATAOBJECT this, LPFORMATETC32 pformatetc, STGMEDIUM32 *pmedium, BOOL32 fRelease)
369 { FIXME (shell, "(%p)->()\n", this);
372 static HRESULT WINAPI IDataObject_EnumFormatEtc(LPDATAOBJECT this, DWORD dwDirection, IEnumFORMATETC **ppenumFormatEtc)
373 { FIXME (shell, "(%p)->()\n", this);
376 static HRESULT WINAPI IDataObject_DAdvise (LPDATAOBJECT this, LPFORMATETC32 *pformatetc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection)
377 { FIXME (shell, "(%p)->()\n", this);
380 static HRESULT WINAPI IDataObject_DUnadvise(LPDATAOBJECT this, DWORD dwConnection)
381 { FIXME (shell, "(%p)->()\n", this);
384 static HRESULT WINAPI IDataObject_EnumDAdvise(LPDATAOBJECT this, IEnumSTATDATA **ppenumAdvise)
385 { FIXME (shell, "(%p)->()\n", this);