2 * IEnumFORMATETC, IDataObject
4 * selecting and droping objects within the shell and/or common dialogs
6 * Copyright 1998, 1999 <juergen.schmied@metronet.de>
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.
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.
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
25 WINE_DEFAULT_DEBUG_CHANNEL(shell
);
27 /***********************************************************************
28 * IEnumFORMATETC implementation
31 class IEnumFORMATETCImpl
:
32 public CComObjectRootEx
<CComMultiThreadModelNoCS
>,
41 ~IEnumFORMATETCImpl();
42 HRESULT WINAPI
Initialize(UINT cfmt
, const FORMATETC afmt
[]);
45 virtual HRESULT WINAPI
Next(ULONG celt
, FORMATETC
*rgelt
, ULONG
*pceltFethed
);
46 virtual HRESULT WINAPI
Skip(ULONG celt
);
47 virtual HRESULT WINAPI
Reset();
48 virtual HRESULT WINAPI
Clone(LPENUMFORMATETC
* ppenum
);
50 BEGIN_COM_MAP(IEnumFORMATETCImpl
)
51 COM_INTERFACE_ENTRY_IID(IID_IEnumFORMATETC
, IEnumFORMATETC
)
55 IEnumFORMATETCImpl::IEnumFORMATETCImpl()
62 IEnumFORMATETCImpl::~IEnumFORMATETCImpl()
66 HRESULT WINAPI
IEnumFORMATETCImpl::Initialize(UINT cfmt
, const FORMATETC afmt
[])
70 size
= cfmt
* sizeof(FORMATETC
);
72 pFmt
= (LPFORMATETC
)SHAlloc(size
);
76 memcpy(pFmt
, afmt
, size
);
80 HRESULT WINAPI
IEnumFORMATETCImpl::Next(ULONG celt
, FORMATETC
*rgelt
, ULONG
*pceltFethed
)
84 TRACE("(%p)->(%u,%p)\n", this, celt
, rgelt
);
86 if(!pFmt
)return S_FALSE
;
87 if(!rgelt
) return E_INVALIDARG
;
88 if (pceltFethed
) *pceltFethed
= 0;
90 for(i
= 0; posFmt
< countFmt
&& celt
> i
; i
++)
92 *rgelt
++ = pFmt
[posFmt
++];
95 if (pceltFethed
) *pceltFethed
= i
;
97 return ((i
== celt
) ? S_OK
: S_FALSE
);
100 HRESULT WINAPI
IEnumFORMATETCImpl::Skip(ULONG celt
)
102 TRACE("(%p)->(num=%u)\n", this, celt
);
104 if (posFmt
+ celt
>= countFmt
) return S_FALSE
;
109 HRESULT WINAPI
IEnumFORMATETCImpl::Reset()
111 TRACE("(%p)->()\n", this);
117 HRESULT WINAPI
IEnumFORMATETCImpl::Clone(LPENUMFORMATETC
* ppenum
)
121 TRACE("(%p)->(ppenum=%p)\n", this, ppenum
);
123 if (!ppenum
) return E_INVALIDARG
;
124 hResult
= IEnumFORMATETC_Constructor(countFmt
, pFmt
, ppenum
);
125 if (FAILED (hResult
))
127 return (*ppenum
)->Skip(posFmt
);
130 HRESULT
IEnumFORMATETC_Constructor(UINT cfmt
, const FORMATETC afmt
[], IEnumFORMATETC
**ppFormat
)
132 return ShellObjectCreatorInit
<IEnumFORMATETCImpl
>(cfmt
, afmt
, IID_IEnumFORMATETC
, ppFormat
);
136 /***********************************************************************
137 * IDataObject implementation
140 /* number of supported formats */
141 #define MAX_FORMATS 5
143 class IDataObjectImpl
:
144 public CComObjectRootEx
<CComMultiThreadModelNoCS
>,
146 public IAsyncOperation
150 LPITEMIDLIST
* apidl
;
154 FORMATETC pFormatEtc
[MAX_FORMATS
];
158 UINT cfPreferredDropEffect
;
163 HRESULT WINAPI
Initialize(HWND hwndOwner
, LPCITEMIDLIST pMyPidl
, LPCITEMIDLIST
* apidlx
, UINT cidlx
);
166 virtual HRESULT WINAPI
GetData(LPFORMATETC pformatetcIn
, STGMEDIUM
*pmedium
);
167 virtual HRESULT WINAPI
GetDataHere(LPFORMATETC pformatetc
, STGMEDIUM
*pmedium
);
168 virtual HRESULT WINAPI
QueryGetData(LPFORMATETC pformatetc
);
169 virtual HRESULT WINAPI
GetCanonicalFormatEtc(LPFORMATETC pformatectIn
, LPFORMATETC pformatetcOut
);
170 virtual HRESULT WINAPI
SetData(LPFORMATETC pformatetc
, STGMEDIUM
*pmedium
, BOOL fRelease
);
171 virtual HRESULT WINAPI
EnumFormatEtc(DWORD dwDirection
, IEnumFORMATETC
**ppenumFormatEtc
);
172 virtual HRESULT WINAPI
DAdvise(FORMATETC
*pformatetc
, DWORD advf
, IAdviseSink
*pAdvSink
, DWORD
*pdwConnection
);
173 virtual HRESULT WINAPI
DUnadvise(DWORD dwConnection
);
174 virtual HRESULT WINAPI
EnumDAdvise(IEnumSTATDATA
**ppenumAdvise
);
175 virtual HRESULT WINAPI
GetAsyncMode(BOOL
*pfIsOpAsync
);
176 virtual HRESULT WINAPI
InOperation(BOOL
*pfInAsyncOp
);
177 virtual HRESULT WINAPI
SetAsyncMode(BOOL fDoOpAsync
);
178 virtual HRESULT WINAPI
StartOperation(IBindCtx
*pbcReserved
);
179 virtual HRESULT WINAPI
EndOperation(HRESULT hResult
, IBindCtx
*pbcReserved
, DWORD dwEffects
);
181 BEGIN_COM_MAP(IDataObjectImpl
)
182 COM_INTERFACE_ENTRY_IID(IID_IDataObject
, IDataObject
)
183 COM_INTERFACE_ENTRY_IID(IID_IAsyncOperation
, IAsyncOperation
)
187 IDataObjectImpl::IDataObjectImpl()
196 cfPreferredDropEffect
= 0;
200 IDataObjectImpl::~IDataObjectImpl()
202 TRACE(" destroying IDataObject(%p)\n",this);
203 _ILFreeaPidl(apidl
, cidl
);
207 HRESULT WINAPI
IDataObjectImpl::Initialize(HWND hwndOwner
, LPCITEMIDLIST pMyPidl
, LPCITEMIDLIST
* apidlx
, UINT cidlx
)
209 pidl
= ILClone(pMyPidl
);
210 apidl
= _ILCopyaPidl(apidlx
, cidlx
);
211 if (pidl
== NULL
|| apidl
== NULL
)
212 return E_OUTOFMEMORY
;
214 dropeffect
= DROPEFFECT_COPY
;
216 cfShellIDList
= RegisterClipboardFormatW(CFSTR_SHELLIDLIST
);
217 cfFileNameA
= RegisterClipboardFormatA(CFSTR_FILENAMEA
);
218 cfFileNameW
= RegisterClipboardFormatW(CFSTR_FILENAMEW
);
219 cfPreferredDropEffect
= RegisterClipboardFormatW(CFSTR_PREFERREDDROPEFFECTW
);
220 InitFormatEtc(pFormatEtc
[0], cfShellIDList
, TYMED_HGLOBAL
);
221 InitFormatEtc(pFormatEtc
[1], CF_HDROP
, TYMED_HGLOBAL
);
222 InitFormatEtc(pFormatEtc
[2], cfFileNameA
, TYMED_HGLOBAL
);
223 InitFormatEtc(pFormatEtc
[3], cfFileNameW
, TYMED_HGLOBAL
);
224 InitFormatEtc(pFormatEtc
[4], cfPreferredDropEffect
, TYMED_HGLOBAL
);
228 /**************************************************************************
229 * IDataObject_fnGetData
231 HRESULT WINAPI
IDataObjectImpl::GetData(LPFORMATETC pformatetcIn
, STGMEDIUM
*pmedium
)
236 GetClipboardFormatNameA (pformatetcIn
->cfFormat
, szTemp
, 256);
237 TRACE("(%p)->(%p %p format=%s)\n", this, pformatetcIn
, pmedium
, szTemp
);
239 if (pformatetcIn
->cfFormat
== cfShellIDList
)
241 if (cidl
< 1) return(E_UNEXPECTED
);
242 pmedium
->hGlobal
= RenderSHELLIDLIST(pidl
, apidl
, cidl
);
244 else if (pformatetcIn
->cfFormat
== CF_HDROP
)
246 if (cidl
< 1) return(E_UNEXPECTED
);
247 pmedium
->hGlobal
= RenderHDROP(pidl
, apidl
, cidl
);
249 else if (pformatetcIn
->cfFormat
== cfFileNameA
)
251 if (cidl
< 1) return(E_UNEXPECTED
);
252 pmedium
->hGlobal
= RenderFILENAMEA(pidl
, apidl
, cidl
);
254 else if (pformatetcIn
->cfFormat
== cfFileNameW
)
256 if (cidl
< 1) return(E_UNEXPECTED
);
257 pmedium
->hGlobal
= RenderFILENAMEW(pidl
, apidl
, cidl
);
259 else if (pformatetcIn
->cfFormat
== cfPreferredDropEffect
)
261 pmedium
->hGlobal
= RenderPREFEREDDROPEFFECT(dropeffect
);
265 FIXME("-- expected clipformat not implemented\n");
266 return (E_INVALIDARG
);
268 if (pmedium
->hGlobal
)
270 pmedium
->tymed
= TYMED_HGLOBAL
;
271 pmedium
->pUnkForRelease
= NULL
;
274 return E_OUTOFMEMORY
;
277 HRESULT WINAPI
IDataObjectImpl::GetDataHere(LPFORMATETC pformatetc
, STGMEDIUM
*pmedium
)
279 FIXME("(%p)->()\n", this);
283 HRESULT WINAPI
IDataObjectImpl::QueryGetData(LPFORMATETC pformatetc
)
287 TRACE("(%p)->(fmt=0x%08x tym=0x%08x)\n", this, pformatetc
->cfFormat
, pformatetc
->tymed
);
289 if(!(DVASPECT_CONTENT
& pformatetc
->dwAspect
))
290 return DV_E_DVASPECT
;
292 /* check our formats table what we have */
293 for (i
=0; i
<MAX_FORMATS
; i
++)
295 if ((pFormatEtc
[i
].cfFormat
== pformatetc
->cfFormat
)
296 && (pFormatEtc
[i
].tymed
== pformatetc
->tymed
))
305 HRESULT WINAPI
IDataObjectImpl::GetCanonicalFormatEtc(LPFORMATETC pformatectIn
, LPFORMATETC pformatetcOut
)
307 FIXME("(%p)->()\n", this);
311 HRESULT WINAPI
IDataObjectImpl::SetData(LPFORMATETC pformatetc
, STGMEDIUM
*pmedium
, BOOL fRelease
)
313 if (pformatetc
->cfFormat
== cfPreferredDropEffect
)
315 const DWORD
*src
= (const DWORD
*)GlobalLock(pmedium
->hGlobal
);
319 GlobalUnlock(pmedium
->hGlobal
);
322 FIXME("Error setting data");
326 FIXME("(%p)->()\n", this);
330 HRESULT WINAPI
IDataObjectImpl::EnumFormatEtc(DWORD dwDirection
, IEnumFORMATETC
**ppenumFormatEtc
)
332 TRACE("(%p)->()\n", this);
333 *ppenumFormatEtc
= NULL
;
336 if (DATADIR_GET
== dwDirection
)
338 return IEnumFORMATETC_Constructor(MAX_FORMATS
, pFormatEtc
, ppenumFormatEtc
);
344 HRESULT WINAPI
IDataObjectImpl::DAdvise(FORMATETC
*pformatetc
, DWORD advf
, IAdviseSink
*pAdvSink
, DWORD
*pdwConnection
)
346 FIXME("(%p)->()\n", this);
350 HRESULT WINAPI
IDataObjectImpl::DUnadvise(DWORD dwConnection
)
352 FIXME("(%p)->()\n", this);
356 HRESULT WINAPI
IDataObjectImpl::EnumDAdvise(IEnumSTATDATA
**ppenumAdvise
)
358 FIXME("(%p)->()\n", this);
362 HRESULT WINAPI
IDataObjectImpl::GetAsyncMode(BOOL
*pfIsOpAsync
)
364 TRACE("(%p)->()\n", this);
365 *pfIsOpAsync
= doasync
;
368 HRESULT WINAPI
IDataObjectImpl::InOperation(BOOL
*pfInAsyncOp
)
370 FIXME("(%p)->()\n", this);
373 HRESULT WINAPI
IDataObjectImpl::SetAsyncMode(BOOL fDoOpAsync
)
375 TRACE("(%p)->()\n", this);
376 doasync
= fDoOpAsync
;
380 HRESULT WINAPI
IDataObjectImpl::StartOperation(IBindCtx
*pbcReserved
)
382 FIXME("(%p)->()\n", this);
385 HRESULT WINAPI
IDataObjectImpl::EndOperation(HRESULT hResult
, IBindCtx
*pbcReserved
, DWORD dwEffects
)
387 FIXME("(%p)->()\n", this);
393 /**************************************************************************
394 * IDataObject_Constructor
396 HRESULT
IDataObject_Constructor(HWND hwndOwner
, LPCITEMIDLIST pMyPidl
, LPCITEMIDLIST
* apidl
, UINT cidl
, IDataObject
**dataObject
)
398 return ShellObjectCreatorInit
<IDataObjectImpl
>(hwndOwner
, pMyPidl
, apidl
, cidl
, IID_IDataObject
, dataObject
);
401 /*************************************************************************
402 * SHCreateDataObject [SHELL32.@]
406 HRESULT WINAPI
SHCreateDataObject(LPCITEMIDLIST pidlFolder
, UINT cidl
, LPCITEMIDLIST
* apidl
, IDataObject
*pdtInner
, REFIID riid
, void **ppv
)
408 if (IsEqualIID(riid
, IID_IDataObject
))
410 return CIDLData_CreateFromIDArray(pidlFolder
, cidl
, apidl
, (IDataObject
**)ppv
);