Release 980927
[wine] / dlls / shell32 / dataobject.c
1 /*
2  *      IEnumFORMATETC, IDataObject
3  *
4  * selecting and droping objects within the shell and/or common dialogs
5  *
6  *      Copyright 1998  <juergen.schmied@metronet.de>
7  */
8 #include "debug.h"
9 #include "shlobj.h"
10 #include "winerror.h"
11 #include "shell32_main.h"
12 /***********************************************************************
13 *   IEnumFORMATETC implementation
14 */
15 static HRESULT WINAPI IEnumFORMATETC_QueryInterface (LPENUMFORMATETC this, REFIID riid, LPVOID * ppvObj);
16 static ULONG WINAPI IEnumFORMATETC_AddRef (LPENUMFORMATETC this);
17 static ULONG WINAPI IEnumFORMATETC_Release (LPENUMFORMATETC this);
18 static HRESULT WINAPI IEnumFORMATETC_Next(LPENUMFORMATETC this, ULONG celt, FORMATETC32 *rgelt, ULONG *pceltFethed);
19 static HRESULT WINAPI IEnumFORMATETC_Skip(LPENUMFORMATETC this, ULONG celt);
20 static HRESULT WINAPI IEnumFORMATETC_Reset(LPENUMFORMATETC this);
21 static HRESULT WINAPI IEnumFORMATETC_Clone(LPENUMFORMATETC this, LPENUMFORMATETC* ppenum);
22
23 static struct IEnumFORMATETC_VTable efvt = 
24 {       IEnumFORMATETC_QueryInterface,
25         IEnumFORMATETC_AddRef,
26         IEnumFORMATETC_Release,
27         IEnumFORMATETC_Next,
28         IEnumFORMATETC_Skip,
29         IEnumFORMATETC_Reset,
30         IEnumFORMATETC_Clone
31 };
32
33 extern LPENUMFORMATETC IEnumFORMATETC_Constructor(UINT32 cfmt, const FORMATETC32 afmt[])
34 {       LPENUMFORMATETC ef;
35         DWORD size=cfmt * sizeof(FORMATETC32);
36         
37         ef=(LPENUMFORMATETC)HeapAlloc(GetProcessHeap(),0,sizeof(IEnumFORMATETC));
38         ef->ref=1;
39         ef->lpvtbl=&efvt;
40
41         ef->posFmt = 0;
42         ef->countFmt = cfmt;
43         ef->pFmt = SHAlloc (size);
44
45         if (ef->pFmt)
46         { memcpy(ef->pFmt, afmt, size);
47         }
48
49         TRACE(shell,"(%p)->()\n",ef);
50         return ef;
51 }
52 static HRESULT WINAPI IEnumFORMATETC_QueryInterface (LPENUMFORMATETC this, REFIID riid, LPVOID * ppvObj)
53 {       char    xriid[50];
54         WINE_StringFromCLSID((LPCLSID)riid,xriid);
55         TRACE(shell,"(%p)->(\n\tIID:\t%s,%p)\n",this,xriid,ppvObj);
56
57                         *ppvObj = NULL;
58
59         if(IsEqualIID(riid, &IID_IUnknown))
60         { *ppvObj = this; 
61         }
62         else if(IsEqualIID(riid, &IID_IEnumFORMATETC))
63         { *ppvObj = (IDataObject*)this;
64         }   
65
66         if(*ppvObj)
67         { (*(LPENUMFORMATETC*)ppvObj)->lpvtbl->fnAddRef(this);      
68           TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
69           return S_OK;
70         }
71         TRACE(shell,"-- Interface: E_NOINTERFACE\n");
72         return E_NOINTERFACE;
73
74 }
75 static ULONG WINAPI IEnumFORMATETC_AddRef (LPENUMFORMATETC this)
76 {       TRACE(shell,"(%p)->(count=%lu)\n",this,(this->ref)+1);
77         return ++(this->ref);
78 }
79 static ULONG WINAPI IEnumFORMATETC_Release (LPENUMFORMATETC this)
80 {       TRACE(shell,"(%p)->()\n",this);
81         if (!--(this->ref)) 
82         { TRACE(shell," destroying IEnumFORMATETC(%p)\n",this);
83           if (this->pFmt)
84           { SHFree (this->pFmt);
85           }
86           HeapFree(GetProcessHeap(),0,this);
87           return 0;
88         }
89         return this->ref;
90 }
91 static HRESULT WINAPI IEnumFORMATETC_Next(LPENUMFORMATETC this, ULONG celt, FORMATETC32 *rgelt, ULONG *pceltFethed)
92 {       UINT32 cfetch;
93         HRESULT hres = S_FALSE;
94
95         TRACE (shell, "(%p)->()\n", this);
96
97         if (this->posFmt < this->countFmt)
98         { cfetch = this->countFmt - this->posFmt;
99           if (cfetch >= celt)
100           { cfetch = celt;
101             hres = S_OK;
102           }
103           memcpy(rgelt, &this->pFmt[this->posFmt], cfetch * sizeof(FORMATETC32));
104           this->posFmt += cfetch;
105         }
106         else
107         { cfetch = 0;
108         }
109
110         if (pceltFethed)
111         { *pceltFethed = cfetch;
112         }
113
114         return hres;
115 }
116 static HRESULT WINAPI IEnumFORMATETC_Skip(LPENUMFORMATETC this, ULONG celt)
117 {       FIXME (shell, "(%p)->(num=%lu)\n", this, celt);
118
119         this->posFmt += celt;
120         if (this->posFmt > this->countFmt)
121         { this->posFmt = this->countFmt;
122           return S_FALSE;
123         }
124         return S_OK;
125 }
126 static HRESULT WINAPI IEnumFORMATETC_Reset(LPENUMFORMATETC this)
127 {       FIXME (shell, "(%p)->()\n", this);
128
129         this->posFmt = 0;
130         return S_OK;
131 }
132 static HRESULT WINAPI IEnumFORMATETC_Clone(LPENUMFORMATETC this, LPENUMFORMATETC* ppenum)
133 {       FIXME (shell, "(%p)->(ppenum=%p)\n", this, ppenum);
134         return E_NOTIMPL;
135 }
136
137 /***********************************************************************
138 *   IDataObject implementation
139 */
140
141 static HRESULT WINAPI IDataObject_QueryInterface (LPDATAOBJECT, REFIID riid, LPVOID * ppvObj);
142 static ULONG WINAPI IDataObject_AddRef (LPDATAOBJECT);
143 static ULONG WINAPI IDataObject_Release (LPDATAOBJECT);
144 static HRESULT WINAPI IDataObject_GetData (LPDATAOBJECT, LPFORMATETC32 pformatetcIn, STGMEDIUM32 *pmedium);
145 static HRESULT WINAPI IDataObject_GetDataHere(LPDATAOBJECT, LPFORMATETC32 pformatetc, STGMEDIUM32 *pmedium);
146 static HRESULT WINAPI IDataObject_QueryGetData(LPDATAOBJECT, LPFORMATETC32 pformatetc);
147 static HRESULT WINAPI IDataObject_GetCanonicalFormatEtc(LPDATAOBJECT, LPFORMATETC32 pformatectIn, LPFORMATETC32 pformatetcOut);
148 static HRESULT WINAPI IDataObject_SetData(LPDATAOBJECT, LPFORMATETC32 pformatetc, STGMEDIUM32 *pmedium, BOOL32 fRelease);
149 static HRESULT WINAPI IDataObject_EnumFormatEtc(LPDATAOBJECT, DWORD dwDirection, IEnumFORMATETC **ppenumFormatEtc);
150 static HRESULT WINAPI IDataObject_DAdvise (LPDATAOBJECT, LPFORMATETC32 *pformatetc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection);
151 static HRESULT WINAPI IDataObject_DUnadvise(LPDATAOBJECT, DWORD dwConnection);
152 static HRESULT WINAPI IDataObject_EnumDAdvise(LPDATAOBJECT, IEnumSTATDATA **ppenumAdvise);
153
154 static struct IDataObject_VTable dtovt = 
155 {       IDataObject_QueryInterface,
156         IDataObject_AddRef,
157         IDataObject_Release,
158         IDataObject_GetData,
159         IDataObject_GetDataHere,
160         IDataObject_QueryGetData,
161         IDataObject_GetCanonicalFormatEtc,
162         IDataObject_SetData,
163         IDataObject_EnumFormatEtc,
164         IDataObject_DAdvise,
165         IDataObject_DUnadvise,
166         IDataObject_EnumDAdvise
167 };
168
169 /**************************************************************************
170 *  IDataObject_Constructor
171 */
172 LPDATAOBJECT IDataObject_Constructor(HWND32 hwndOwner, LPSHELLFOLDER pcf, LPITEMIDLIST * apit, UINT32 cpit)
173 {       LPDATAOBJECT dto;
174         dto=(LPDATAOBJECT)HeapAlloc(GetProcessHeap(),0,sizeof(IDataObject));
175         dto->ref=1;
176         dto->lpvtbl=&dtovt;
177         TRACE(shell,"(%p)->()\n",dto);
178         return dto;
179 }
180 /***************************************************************************
181 *  IDataObject_QueryInterface
182 */
183 static HRESULT WINAPI IDataObject_QueryInterface (LPDATAOBJECT this, REFIID riid, LPVOID * ppvObj)
184 {       char    xriid[50];
185         WINE_StringFromCLSID((LPCLSID)riid,xriid);
186         TRACE(shell,"(%p)->(\n\tIID:\t%s,%p)\n",this,xriid,ppvObj);
187
188         *ppvObj = NULL;
189
190         if(IsEqualIID(riid, &IID_IUnknown))          /*IUnknown*/
191         { *ppvObj = this; 
192         }
193         else if(IsEqualIID(riid, &IID_IDataObject))  /*IDataObject*/
194         { *ppvObj = (IDataObject*)this;
195         }   
196
197         if(*ppvObj)
198         { (*(LPDATAOBJECT*)ppvObj)->lpvtbl->fnAddRef(this);      
199           TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
200           return S_OK;
201         }
202         TRACE(shell,"-- Interface: E_NOINTERFACE\n");
203         return E_NOINTERFACE;
204 }   
205 /**************************************************************************
206 *  IDataObject_AddRef
207 */
208 static ULONG WINAPI IDataObject_AddRef(LPDATAOBJECT this)
209 {       TRACE(shell,"(%p)->(count=%lu)\n",this,(this->ref)+1);
210         return ++(this->ref);
211 }
212 /**************************************************************************
213 *  IDataObject_Release
214 */
215 static ULONG WINAPI IDataObject_Release(LPDATAOBJECT this)
216 {       TRACE(shell,"(%p)->()\n",this);
217         if (!--(this->ref)) 
218         { TRACE(shell," destroying IDataObject(%p)\n",this);
219           HeapFree(GetProcessHeap(),0,this);
220           return 0;
221         }
222         return this->ref;
223 }
224 static HRESULT WINAPI IDataObject_GetData (LPDATAOBJECT this, LPFORMATETC32 pformatetcIn, STGMEDIUM32 *pmedium)
225 {       FIXME (shell, "(%p)->()\n", this);
226         return E_NOTIMPL;
227 }
228 static HRESULT WINAPI IDataObject_GetDataHere(LPDATAOBJECT this, LPFORMATETC32 pformatetc, STGMEDIUM32 *pmedium)
229 {       FIXME (shell, "(%p)->()\n", this);
230         return E_NOTIMPL;
231 }
232 static HRESULT WINAPI IDataObject_QueryGetData(LPDATAOBJECT this, LPFORMATETC32 pformatetc)
233 {       FIXME (shell, "(%p)->()\n", this);
234         return E_NOTIMPL;
235 }
236 static HRESULT WINAPI IDataObject_GetCanonicalFormatEtc(LPDATAOBJECT this, LPFORMATETC32 pformatectIn, LPFORMATETC32 pformatetcOut)
237 {       FIXME (shell, "(%p)->()\n", this);
238         return E_NOTIMPL;
239 }
240 static HRESULT WINAPI IDataObject_SetData(LPDATAOBJECT this, LPFORMATETC32 pformatetc, STGMEDIUM32 *pmedium, BOOL32 fRelease)
241 {       FIXME (shell, "(%p)->()\n", this);
242         return E_NOTIMPL;
243 }
244 static HRESULT WINAPI IDataObject_EnumFormatEtc(LPDATAOBJECT this, DWORD dwDirection, IEnumFORMATETC **ppenumFormatEtc)
245 {       FIXME (shell, "(%p)->()\n", this);
246         return E_NOTIMPL;
247 }
248 static HRESULT WINAPI IDataObject_DAdvise (LPDATAOBJECT this, LPFORMATETC32 *pformatetc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection)
249 {       FIXME (shell, "(%p)->()\n", this);
250         return E_NOTIMPL;
251 }
252 static HRESULT WINAPI IDataObject_DUnadvise(LPDATAOBJECT this, DWORD dwConnection)
253 {       FIXME (shell, "(%p)->()\n", this);
254         return E_NOTIMPL;
255 }
256 static HRESULT WINAPI IDataObject_EnumDAdvise(LPDATAOBJECT this, IEnumSTATDATA **ppenumAdvise)
257 {       FIXME (shell, "(%p)->()\n", this);
258         return E_NOTIMPL;
259 }