1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 #if defined(_MSC_VER) && (_MSC_VER > 1310) 24 #pragma warning(disable : 4917 4555) 25 #endif 26 27 // actually this workaround should be in presys.h! 28 //#define UINT64 USE_WIN_UINT64 29 //#define INT64 USE_WIN_INT64 30 //#define UINT32 USE_WIN_UINT32 31 //#define INT32 USE_WIN_INT32 32 33 //#include <tools/presys.h> 34 #include "embeddoc.hxx" 35 //#include <tools/postsys.h> 36 37 //#undef UINT64 38 //#undef INT64 39 //#undef UINT32 40 //#undef INT32 41 42 43 #include <com/sun/star/uno/Any.h> 44 #include <com/sun/star/uno/Exception.hpp> 45 #include <com/sun/star/datatransfer/XTransferable.hpp> 46 47 48 #include <osl/thread.h> 49 50 using namespace ::com::sun::star; 51 52 //=============================================================================== 53 // EmbedDocument_Impl 54 //=============================================================================== 55 56 sal_uInt64 EmbedDocument_Impl::getMetaFileHandle_Impl( sal_Bool isEnhMeta ) 57 { 58 sal_uInt64 pResult = NULL; 59 60 uno::Reference< datatransfer::XTransferable > xTransferable( m_pDocHolder->GetDocument(), uno::UNO_QUERY ); 61 if ( xTransferable.is() ) 62 { 63 uno::Sequence< sal_Int8 > aMetaBuffer; 64 datatransfer::DataFlavor aFlavor; 65 66 if ( isEnhMeta ) 67 { 68 aFlavor.MimeType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( 69 "application/x-openoffice-emf;windows_formatname=\"Image EMF\"" ) ); 70 aFlavor.HumanPresentableName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Enhanced Windows MetaFile" ) ); 71 } 72 else 73 { 74 aFlavor.MimeType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( 75 "application/x-openoffice-wmf;windows_formatname=\"Image WMF\"" ) ); 76 aFlavor.HumanPresentableName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Windows GDIMetaFile" ) ); 77 } 78 79 aFlavor.DataType = getCppuType( (const sal_uInt64*) 0 ); 80 81 uno::Any aAny = xTransferable->getTransferData( aFlavor ); 82 aAny >>= pResult; 83 } 84 85 return pResult; 86 } 87 88 //------------------------------------------------------------------------------- 89 // IDataObject 90 91 STDMETHODIMP EmbedDocument_Impl::GetData( FORMATETC * pFormatetc, STGMEDIUM * pMedium ) 92 { 93 if ( !pFormatetc ) 94 return DV_E_FORMATETC; 95 96 if ( !pMedium ) 97 return STG_E_MEDIUMFULL; 98 99 if ( pFormatetc->dwAspect == DVASPECT_THUMBNAIL 100 || pFormatetc->dwAspect == DVASPECT_ICON 101 || pFormatetc->dwAspect == DVASPECT_DOCPRINT ) 102 return DV_E_DVASPECT; 103 104 if ( pFormatetc->cfFormat == CF_ENHMETAFILE ) 105 { 106 if ( !( pFormatetc->tymed & TYMED_ENHMF ) ) 107 return DV_E_TYMED; 108 109 HENHMETAFILE hMeta = reinterpret_cast<HENHMETAFILE>( getMetaFileHandle_Impl( sal_True ) ); 110 111 if ( hMeta ) 112 { 113 pMedium->tymed = TYMED_ENHMF; 114 pMedium->hEnhMetaFile = hMeta; 115 pMedium->pUnkForRelease = NULL; 116 117 return S_OK; 118 } 119 120 return STG_E_MEDIUMFULL; 121 } 122 else if ( pFormatetc->cfFormat == CF_METAFILEPICT ) 123 { 124 if ( !( pFormatetc->tymed & TYMED_MFPICT ) ) 125 return DV_E_TYMED; 126 127 HGLOBAL hMeta = reinterpret_cast<HGLOBAL>( getMetaFileHandle_Impl( sal_False ) ); 128 129 if ( hMeta ) 130 { 131 pMedium->tymed = TYMED_MFPICT; 132 pMedium->hMetaFilePict = hMeta; 133 pMedium->pUnkForRelease = NULL; 134 135 return S_OK; 136 } 137 138 return STG_E_MEDIUMFULL; 139 } 140 else 141 { 142 CLIPFORMAT cf_embSource = (CLIPFORMAT)RegisterClipboardFormatA( "Embed Source" ); 143 CLIPFORMAT cf_embObj = (CLIPFORMAT)RegisterClipboardFormatA( "Embedded Object" ); 144 if ( pFormatetc->cfFormat == cf_embSource || pFormatetc->cfFormat == cf_embObj ) 145 { 146 if ( !( pFormatetc->tymed & TYMED_ISTORAGE ) ) 147 return DV_E_TYMED; 148 149 CComPtr< IStorage > pNewStg; 150 HRESULT hr = StgCreateDocfile( NULL, STGM_CREATE | STGM_READWRITE | STGM_DELETEONRELEASE, 0, &pNewStg ); 151 if ( FAILED( hr ) || !pNewStg ) return STG_E_MEDIUMFULL; 152 153 hr = SaveTo_Impl( pNewStg ); 154 if ( FAILED( hr ) ) return STG_E_MEDIUMFULL; 155 156 pMedium->tymed = TYMED_ISTORAGE; 157 pMedium->pstg = pNewStg; 158 pMedium->pstg->AddRef(); 159 pMedium->pUnkForRelease = ( IUnknown* )pNewStg; 160 161 return S_OK; 162 } 163 } 164 165 return DV_E_FORMATETC; 166 } 167 168 STDMETHODIMP EmbedDocument_Impl::GetDataHere( FORMATETC * pFormatetc, STGMEDIUM * pMedium ) 169 { 170 if ( !pFormatetc ) 171 return DV_E_FORMATETC; 172 173 if ( !pMedium ) 174 return STG_E_MEDIUMFULL; 175 176 if ( pFormatetc->dwAspect == DVASPECT_THUMBNAIL 177 || pFormatetc->dwAspect == DVASPECT_ICON 178 || pFormatetc->dwAspect == DVASPECT_DOCPRINT ) 179 return DV_E_DVASPECT; 180 181 CLIPFORMAT cf_embSource = (CLIPFORMAT)RegisterClipboardFormatA( "Embed Source" ); 182 CLIPFORMAT cf_embObj = (CLIPFORMAT)RegisterClipboardFormatA( "Embedded Object" ); 183 184 if ( pFormatetc->cfFormat == cf_embSource || pFormatetc->cfFormat == cf_embObj ) 185 { 186 if ( !( pFormatetc->tymed & TYMED_ISTORAGE ) ) 187 return DV_E_TYMED; 188 189 if ( !pMedium->pstg ) return STG_E_MEDIUMFULL; 190 191 HRESULT hr = SaveTo_Impl( pMedium->pstg ); 192 if ( FAILED( hr ) ) return STG_E_MEDIUMFULL; 193 194 pMedium->tymed = TYMED_ISTORAGE; 195 pMedium->pUnkForRelease = NULL; 196 197 return S_OK; 198 } 199 200 return DV_E_FORMATETC; 201 } 202 203 STDMETHODIMP EmbedDocument_Impl::QueryGetData( FORMATETC * pFormatetc ) 204 { 205 if ( pFormatetc ) 206 { 207 if ( pFormatetc->dwAspect == DVASPECT_THUMBNAIL 208 || pFormatetc->dwAspect == DVASPECT_ICON 209 || pFormatetc->dwAspect == DVASPECT_DOCPRINT ) 210 return DV_E_DVASPECT; 211 212 if ( pFormatetc->cfFormat == CF_ENHMETAFILE ) 213 { 214 if ( !( pFormatetc->tymed & TYMED_ENHMF ) ) 215 return DV_E_TYMED; 216 217 return S_OK; 218 } 219 else if ( pFormatetc->cfFormat == CF_METAFILEPICT ) 220 { 221 if ( !( pFormatetc->tymed & TYMED_MFPICT ) ) 222 return DV_E_TYMED; 223 224 return S_OK; 225 } 226 else 227 { 228 CLIPFORMAT cf_embSource = (CLIPFORMAT)RegisterClipboardFormatA( "Embed Source" ); 229 CLIPFORMAT cf_embObj = (CLIPFORMAT)RegisterClipboardFormatA( "Embedded Object" ); 230 if ( pFormatetc->cfFormat == cf_embSource || pFormatetc->cfFormat == cf_embObj ) 231 { 232 if ( !( pFormatetc->tymed & TYMED_ISTORAGE ) ) 233 return DV_E_TYMED; 234 235 return S_OK; 236 } 237 } 238 } 239 240 return DV_E_FORMATETC; 241 242 } 243 244 STDMETHODIMP EmbedDocument_Impl::GetCanonicalFormatEtc( FORMATETC * pFormatetcIn, FORMATETC * pFormatetcOut ) 245 { 246 if ( !pFormatetcIn || !pFormatetcOut ) 247 return DV_E_FORMATETC; 248 249 pFormatetcOut->ptd = NULL; 250 pFormatetcOut->cfFormat = pFormatetcIn->cfFormat; 251 pFormatetcOut->dwAspect = DVASPECT_CONTENT; 252 253 if ( pFormatetcIn->cfFormat == CF_ENHMETAFILE ) 254 { 255 pFormatetcOut->tymed = TYMED_ENHMF; 256 return S_OK; 257 } 258 else if ( pFormatetcIn->cfFormat == CF_METAFILEPICT ) 259 { 260 pFormatetcOut->tymed = TYMED_MFPICT; 261 return S_OK; 262 } 263 else 264 { 265 CLIPFORMAT cf_embSource = (CLIPFORMAT)RegisterClipboardFormatA( "Embed Source" ); 266 CLIPFORMAT cf_embObj = (CLIPFORMAT)RegisterClipboardFormatA( "Embedded Object" ); 267 if ( pFormatetcIn->cfFormat == cf_embSource || pFormatetcIn->cfFormat == cf_embObj ) 268 { 269 pFormatetcOut->tymed = TYMED_ISTORAGE; 270 return S_OK; 271 } 272 } 273 274 return DV_E_FORMATETC; 275 } 276 277 STDMETHODIMP EmbedDocument_Impl::SetData( FORMATETC * /*pFormatetc*/, STGMEDIUM * /*pMedium*/, BOOL /*fRelease*/ ) 278 { 279 return E_NOTIMPL; 280 } 281 282 STDMETHODIMP EmbedDocument_Impl::EnumFormatEtc( DWORD dwDirection, IEnumFORMATETC ** /*ppFormatetc*/ ) 283 { 284 if ( dwDirection == DATADIR_GET ) 285 return OLE_S_USEREG; 286 287 return E_NOTIMPL; 288 } 289 290 STDMETHODIMP EmbedDocument_Impl::DAdvise( FORMATETC * pFormatetc, DWORD advf, IAdviseSink * pAdvSink, DWORD * pdwConnection ) 291 { 292 if ( !m_pDAdviseHolder ) 293 if ( !SUCCEEDED( CreateDataAdviseHolder( &m_pDAdviseHolder ) ) || !m_pDAdviseHolder ) 294 return E_OUTOFMEMORY; 295 296 return m_pDAdviseHolder->Advise( (IDataObject*)this, pFormatetc, advf, pAdvSink, pdwConnection ); 297 } 298 299 STDMETHODIMP EmbedDocument_Impl::DUnadvise( DWORD dwConnection ) 300 { 301 if ( !m_pDAdviseHolder ) 302 if ( !SUCCEEDED( CreateDataAdviseHolder( &m_pDAdviseHolder ) ) || !m_pDAdviseHolder ) 303 return E_OUTOFMEMORY; 304 305 return m_pDAdviseHolder->Unadvise( dwConnection ); 306 } 307 308 STDMETHODIMP EmbedDocument_Impl::EnumDAdvise( IEnumSTATDATA ** ppenumAdvise ) 309 { 310 if ( !m_pDAdviseHolder ) 311 if ( !SUCCEEDED( CreateDataAdviseHolder( &m_pDAdviseHolder ) ) || !m_pDAdviseHolder ) 312 return E_OUTOFMEMORY; 313 314 return m_pDAdviseHolder->EnumAdvise( ppenumAdvise ); 315 } 316 317 // Fix strange warnings about some 318 // ATL::CAxHostWindow::QueryInterface|AddRef|Releae functions. 319 // warning C4505: 'xxx' : unreferenced local function has been removed 320 #if defined(_MSC_VER) 321 #pragma warning(disable: 4505) 322 #endif 323