Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygendataobject.cpp
Go to the documentation of this file.
00001 /* 00002 * IEnumFORMATETC, IDataObject 00003 * 00004 * selecting and droping objects within the shell and/or common dialogs 00005 * 00006 * Copyright 1998, 1999 <juergen.schmied@metronet.de> 00007 * 00008 * This library is free software; you can redistribute it and/or 00009 * modify it under the terms of the GNU Lesser General Public 00010 * License as published by the Free Software Foundation; either 00011 * version 2.1 of the License, or (at your option) any later version. 00012 * 00013 * This library is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 * Lesser General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public 00019 * License along with this library; if not, write to the Free Software 00020 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00021 */ 00022 00023 #include <precomp.h> 00024 00025 WINE_DEFAULT_DEBUG_CHANNEL(shell); 00026 00027 /*********************************************************************** 00028 * IEnumFORMATETC implementation 00029 */ 00030 00031 class IEnumFORMATETCImpl : 00032 public CComObjectRootEx<CComMultiThreadModelNoCS>, 00033 public IEnumFORMATETC 00034 { 00035 private: 00036 UINT posFmt; 00037 UINT countFmt; 00038 LPFORMATETC pFmt; 00039 public: 00040 IEnumFORMATETCImpl(); 00041 ~IEnumFORMATETCImpl(); 00042 HRESULT WINAPI Initialize(UINT cfmt, const FORMATETC afmt[]); 00043 00044 // ***************** 00045 virtual HRESULT WINAPI Next(ULONG celt, FORMATETC *rgelt, ULONG *pceltFethed); 00046 virtual HRESULT WINAPI Skip(ULONG celt); 00047 virtual HRESULT WINAPI Reset(); 00048 virtual HRESULT WINAPI Clone(LPENUMFORMATETC* ppenum); 00049 00050 BEGIN_COM_MAP(IEnumFORMATETCImpl) 00051 COM_INTERFACE_ENTRY_IID(IID_IEnumFORMATETC, IEnumFORMATETC) 00052 END_COM_MAP() 00053 }; 00054 00055 IEnumFORMATETCImpl::IEnumFORMATETCImpl() 00056 { 00057 posFmt = 0; 00058 countFmt = 0; 00059 pFmt = NULL; 00060 } 00061 00062 IEnumFORMATETCImpl::~IEnumFORMATETCImpl() 00063 { 00064 } 00065 00066 HRESULT WINAPI IEnumFORMATETCImpl::Initialize(UINT cfmt, const FORMATETC afmt[]) 00067 { 00068 DWORD size; 00069 00070 size = cfmt * sizeof(FORMATETC); 00071 countFmt = cfmt; 00072 pFmt = (LPFORMATETC)SHAlloc(size); 00073 if (pFmt == NULL) 00074 return E_OUTOFMEMORY; 00075 00076 memcpy(pFmt, afmt, size); 00077 return S_OK; 00078 } 00079 00080 HRESULT WINAPI IEnumFORMATETCImpl::Next(ULONG celt, FORMATETC *rgelt, ULONG *pceltFethed) 00081 { 00082 UINT i; 00083 00084 TRACE("(%p)->(%u,%p)\n", this, celt, rgelt); 00085 00086 if(!pFmt)return S_FALSE; 00087 if(!rgelt) return E_INVALIDARG; 00088 if (pceltFethed) *pceltFethed = 0; 00089 00090 for(i = 0; posFmt < countFmt && celt > i; i++) 00091 { 00092 *rgelt++ = pFmt[posFmt++]; 00093 } 00094 00095 if (pceltFethed) *pceltFethed = i; 00096 00097 return ((i == celt) ? S_OK : S_FALSE); 00098 } 00099 00100 HRESULT WINAPI IEnumFORMATETCImpl::Skip(ULONG celt) 00101 { 00102 TRACE("(%p)->(num=%u)\n", this, celt); 00103 00104 if (posFmt + celt >= countFmt) return S_FALSE; 00105 posFmt += celt; 00106 return S_OK; 00107 } 00108 00109 HRESULT WINAPI IEnumFORMATETCImpl::Reset() 00110 { 00111 TRACE("(%p)->()\n", this); 00112 00113 posFmt = 0; 00114 return S_OK; 00115 } 00116 00117 HRESULT WINAPI IEnumFORMATETCImpl::Clone(LPENUMFORMATETC* ppenum) 00118 { 00119 HRESULT hResult; 00120 00121 TRACE("(%p)->(ppenum=%p)\n", this, ppenum); 00122 00123 if (!ppenum) return E_INVALIDARG; 00124 hResult = IEnumFORMATETC_Constructor(countFmt, pFmt, ppenum); 00125 if (FAILED (hResult)) 00126 return hResult; 00127 return (*ppenum)->Skip(posFmt); 00128 } 00129 00130 HRESULT IEnumFORMATETC_Constructor(UINT cfmt, const FORMATETC afmt[], IEnumFORMATETC **enumerator) 00131 { 00132 CComObject<IEnumFORMATETCImpl> *theEnumerator; 00133 CComPtr<IEnumFORMATETC> result; 00134 HRESULT hResult; 00135 00136 if (enumerator == NULL) 00137 return E_POINTER; 00138 *enumerator = NULL; 00139 ATLTRY (theEnumerator = new CComObject<IEnumFORMATETCImpl>); 00140 if (theEnumerator == NULL) 00141 return E_OUTOFMEMORY; 00142 hResult = theEnumerator->QueryInterface (IID_IEnumFORMATETC, (void **)&result); 00143 if (FAILED (hResult)) 00144 { 00145 delete theEnumerator; 00146 return hResult; 00147 } 00148 hResult = theEnumerator->Initialize (cfmt, afmt); 00149 if (FAILED (hResult)) 00150 return hResult; 00151 *enumerator = result.Detach (); 00152 TRACE("(%p)->(%u,%p)\n", *enumerator, cfmt, afmt); 00153 return S_OK; 00154 } 00155 00156 00157 /*********************************************************************** 00158 * IDataObject implementation 00159 */ 00160 00161 /* number of supported formats */ 00162 #define MAX_FORMATS 4 00163 00164 class IDataObjectImpl : 00165 public CComObjectRootEx<CComMultiThreadModelNoCS>, 00166 public IDataObject 00167 { 00168 private: 00169 LPITEMIDLIST pidl; 00170 LPITEMIDLIST * apidl; 00171 UINT cidl; 00172 00173 FORMATETC pFormatEtc[MAX_FORMATS]; 00174 UINT cfShellIDList; 00175 UINT cfFileNameA; 00176 UINT cfFileNameW; 00177 public: 00178 IDataObjectImpl(); 00179 ~IDataObjectImpl(); 00180 HRESULT WINAPI Initialize(HWND hwndOwner, LPCITEMIDLIST pMyPidl, LPCITEMIDLIST * apidlx, UINT cidlx); 00181 00183 virtual HRESULT WINAPI GetData(LPFORMATETC pformatetcIn, STGMEDIUM *pmedium); 00184 virtual HRESULT WINAPI GetDataHere(LPFORMATETC pformatetc, STGMEDIUM *pmedium); 00185 virtual HRESULT WINAPI QueryGetData(LPFORMATETC pformatetc); 00186 virtual HRESULT WINAPI GetCanonicalFormatEtc(LPFORMATETC pformatectIn, LPFORMATETC pformatetcOut); 00187 virtual HRESULT WINAPI SetData(LPFORMATETC pformatetc, STGMEDIUM *pmedium, BOOL fRelease); 00188 virtual HRESULT WINAPI EnumFormatEtc(DWORD dwDirection, IEnumFORMATETC **ppenumFormatEtc); 00189 virtual HRESULT WINAPI DAdvise(FORMATETC *pformatetc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection); 00190 virtual HRESULT WINAPI DUnadvise(DWORD dwConnection); 00191 virtual HRESULT WINAPI EnumDAdvise(IEnumSTATDATA **ppenumAdvise); 00192 00193 BEGIN_COM_MAP(IDataObjectImpl) 00194 COM_INTERFACE_ENTRY_IID(IID_IDataObject, IDataObject) 00195 END_COM_MAP() 00196 }; 00197 00198 IDataObjectImpl::IDataObjectImpl() 00199 { 00200 pidl = NULL; 00201 apidl = NULL; 00202 cidl = 0; 00203 cfShellIDList = 0; 00204 cfFileNameA = 0; 00205 cfFileNameW = 0; 00206 } 00207 00208 IDataObjectImpl::~IDataObjectImpl() 00209 { 00210 TRACE(" destroying IDataObject(%p)\n",this); 00211 _ILFreeaPidl(apidl, cidl); 00212 ILFree(pidl); 00213 } 00214 00215 HRESULT WINAPI IDataObjectImpl::Initialize(HWND hwndOwner, LPCITEMIDLIST pMyPidl, LPCITEMIDLIST * apidlx, UINT cidlx) 00216 { 00217 pidl = ILClone(pMyPidl); 00218 apidl = _ILCopyaPidl(apidlx, cidlx); 00219 if (pidl == NULL || apidl == NULL) 00220 return E_OUTOFMEMORY; 00221 cidl = cidlx; 00222 00223 cfShellIDList = RegisterClipboardFormatW(CFSTR_SHELLIDLIST); 00224 cfFileNameA = RegisterClipboardFormatA(CFSTR_FILENAMEA); 00225 cfFileNameW = RegisterClipboardFormatW(CFSTR_FILENAMEW); 00226 InitFormatEtc(pFormatEtc[0], cfShellIDList, TYMED_HGLOBAL); 00227 InitFormatEtc(pFormatEtc[1], CF_HDROP, TYMED_HGLOBAL); 00228 InitFormatEtc(pFormatEtc[2], cfFileNameA, TYMED_HGLOBAL); 00229 InitFormatEtc(pFormatEtc[3], cfFileNameW, TYMED_HGLOBAL); 00230 return S_OK; 00231 } 00232 00233 /************************************************************************** 00234 * IDataObject_fnGetData 00235 */ 00236 HRESULT WINAPI IDataObjectImpl::GetData(LPFORMATETC pformatetcIn, STGMEDIUM *pmedium) 00237 { 00238 char szTemp[256]; 00239 00240 szTemp[0] = 0; 00241 GetClipboardFormatNameA (pformatetcIn->cfFormat, szTemp, 256); 00242 TRACE("(%p)->(%p %p format=%s)\n", this, pformatetcIn, pmedium, szTemp); 00243 00244 if (pformatetcIn->cfFormat == cfShellIDList) 00245 { 00246 if (cidl < 1) return(E_UNEXPECTED); 00247 pmedium->hGlobal = RenderSHELLIDLIST(pidl, apidl, cidl); 00248 } 00249 else if (pformatetcIn->cfFormat == CF_HDROP) 00250 { 00251 if (cidl < 1) return(E_UNEXPECTED); 00252 pmedium->hGlobal = RenderHDROP(pidl, apidl, cidl); 00253 } 00254 else if (pformatetcIn->cfFormat == cfFileNameA) 00255 { 00256 if (cidl < 1) return(E_UNEXPECTED); 00257 pmedium->hGlobal = RenderFILENAMEA(pidl, apidl, cidl); 00258 } 00259 else if (pformatetcIn->cfFormat == cfFileNameW) 00260 { 00261 if (cidl < 1) return(E_UNEXPECTED); 00262 pmedium->hGlobal = RenderFILENAMEW(pidl, apidl, cidl); 00263 } 00264 else 00265 { 00266 FIXME("-- expected clipformat not implemented\n"); 00267 return (E_INVALIDARG); 00268 } 00269 if (pmedium->hGlobal) 00270 { 00271 pmedium->tymed = TYMED_HGLOBAL; 00272 pmedium->pUnkForRelease = NULL; 00273 return S_OK; 00274 } 00275 return E_OUTOFMEMORY; 00276 } 00277 00278 HRESULT WINAPI IDataObjectImpl::GetDataHere(LPFORMATETC pformatetc, STGMEDIUM *pmedium) 00279 { 00280 FIXME("(%p)->()\n", this); 00281 return E_NOTIMPL; 00282 } 00283 00284 HRESULT WINAPI IDataObjectImpl::QueryGetData(LPFORMATETC pformatetc) 00285 { 00286 UINT i; 00287 00288 TRACE("(%p)->(fmt=0x%08x tym=0x%08x)\n", this, pformatetc->cfFormat, pformatetc->tymed); 00289 00290 if(!(DVASPECT_CONTENT & pformatetc->dwAspect)) 00291 return DV_E_DVASPECT; 00292 00293 /* check our formats table what we have */ 00294 for (i=0; i<MAX_FORMATS; i++) 00295 { 00296 if ((pFormatEtc[i].cfFormat == pformatetc->cfFormat) 00297 && (pFormatEtc[i].tymed == pformatetc->tymed)) 00298 { 00299 return S_OK; 00300 } 00301 } 00302 00303 return DV_E_TYMED; 00304 } 00305 00306 HRESULT WINAPI IDataObjectImpl::GetCanonicalFormatEtc(LPFORMATETC pformatectIn, LPFORMATETC pformatetcOut) 00307 { 00308 FIXME("(%p)->()\n", this); 00309 return E_NOTIMPL; 00310 } 00311 00312 HRESULT WINAPI IDataObjectImpl::SetData(LPFORMATETC pformatetc, STGMEDIUM *pmedium, BOOL fRelease) 00313 { 00314 FIXME("(%p)->()\n", this); 00315 return E_NOTIMPL; 00316 } 00317 00318 HRESULT WINAPI IDataObjectImpl::EnumFormatEtc(DWORD dwDirection, IEnumFORMATETC **ppenumFormatEtc) 00319 { 00320 TRACE("(%p)->()\n", this); 00321 *ppenumFormatEtc = NULL; 00322 00323 /* only get data */ 00324 if (DATADIR_GET == dwDirection) 00325 { 00326 return IEnumFORMATETC_Constructor(MAX_FORMATS, pFormatEtc, ppenumFormatEtc); 00327 } 00328 00329 return E_NOTIMPL; 00330 } 00331 00332 HRESULT WINAPI IDataObjectImpl::DAdvise(FORMATETC *pformatetc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection) 00333 { 00334 FIXME("(%p)->()\n", this); 00335 return E_NOTIMPL; 00336 } 00337 00338 HRESULT WINAPI IDataObjectImpl::DUnadvise(DWORD dwConnection) 00339 { 00340 FIXME("(%p)->()\n", this); 00341 return E_NOTIMPL; 00342 } 00343 00344 HRESULT WINAPI IDataObjectImpl::EnumDAdvise(IEnumSTATDATA **ppenumAdvise) 00345 { 00346 FIXME("(%p)->()\n", this); 00347 return E_NOTIMPL; 00348 } 00349 00350 /************************************************************************** 00351 * IDataObject_Constructor 00352 */ 00353 HRESULT IDataObject_Constructor(HWND hwndOwner, LPCITEMIDLIST pMyPidl, LPCITEMIDLIST * apidl, UINT cidl, IDataObject **dataObject) 00354 { 00355 CComObject<IDataObjectImpl> *theDataObject; 00356 CComPtr<IDataObject> result; 00357 HRESULT hResult; 00358 00359 if (dataObject == NULL) 00360 return E_POINTER; 00361 *dataObject = NULL; 00362 ATLTRY (theDataObject = new CComObject<IDataObjectImpl>); 00363 if (theDataObject == NULL) 00364 return E_OUTOFMEMORY; 00365 hResult = theDataObject->QueryInterface (IID_IDataObject, (void **)&result); 00366 if (FAILED (hResult)) 00367 { 00368 delete theDataObject; 00369 return hResult; 00370 } 00371 hResult = theDataObject->Initialize (hwndOwner, pMyPidl, apidl, cidl); 00372 if (FAILED (hResult)) 00373 return hResult; 00374 *dataObject = result.Detach (); 00375 TRACE("(%p)->(apidl=%p cidl=%u)\n", *dataObject, apidl, cidl); 00376 return S_OK; 00377 } 00378 00379 /************************************************************************* 00380 * SHCreateDataObject [SHELL32.@] 00381 * 00382 */ 00383 00384 HRESULT WINAPI SHCreateDataObject(LPCITEMIDLIST pidlFolder, UINT cidl, LPCITEMIDLIST* apidl, IDataObject *pdtInner, REFIID riid, void **ppv) 00385 { 00386 if (IsEqualIID(riid, IID_IDataObject)) 00387 { 00388 return CIDLData_CreateFromIDArray(pidlFolder, cidl, apidl, (IDataObject **)ppv); 00389 } 00390 return E_FAIL; 00391 } Generated on Sun May 27 2012 04:26:16 for ReactOS by
1.7.6.1
|