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 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_dtrans.hxx" 26 27 //------------------------------------------------------------------------ 28 // includes 29 //------------------------------------------------------------------------ 30 #include <osl/diagnose.h> 31 32 #ifndef _TXDATAOBJECT_HXX_ 33 #include "XTDataObject.hxx" 34 #endif 35 #include <com/sun/star/datatransfer/DataFlavor.hpp> 36 #include "..\misc\ImplHelper.hxx" 37 #include "DTransHelper.hxx" 38 #include "TxtCnvtHlp.hxx" 39 #include <com/sun/star/datatransfer/clipboard/XClipboardEx.hpp> 40 #include "FmtFilter.hxx" 41 42 #if defined _MSC_VER 43 #pragma warning(push,1) 44 #pragma warning(disable:4917) 45 #endif 46 #include <windows.h> 47 #include <shlobj.h> 48 #if defined _MSC_VER 49 #pragma warning(pop) 50 #endif 51 52 #ifdef __MINGW32__ 53 #define __uuidof(I) IID_##I 54 #endif 55 56 //------------------------------------------------------------------------ 57 // namespace directives 58 //------------------------------------------------------------------------ 59 60 using namespace com::sun::star::datatransfer; 61 using namespace com::sun::star::datatransfer::clipboard; 62 using namespace com::sun::star::uno; 63 using namespace com::sun::star::lang; 64 using namespace rtl; 65 66 //------------------------------------------------------------------------ 67 // a helper class that will be thrown by the function validateFormatEtc 68 //------------------------------------------------------------------------ 69 70 class CInvalidFormatEtcException 71 { 72 public: 73 HRESULT m_hr; 74 CInvalidFormatEtcException( HRESULT hr ) : m_hr( hr ) {}; 75 }; 76 77 //------------------------------------------------------------------------ 78 // ctor 79 //------------------------------------------------------------------------ 80 81 CXTDataObject::CXTDataObject( const Reference< XMultiServiceFactory >& aServiceManager, 82 const Reference< XTransferable >& aXTransferable ) : 83 m_nRefCnt( 0 ), 84 m_SrvMgr( aServiceManager ), 85 m_XTransferable( aXTransferable ), 86 m_DataFormatTranslator( aServiceManager ), 87 m_bFormatEtcContainerInitialized( sal_False ), 88 m_FormatRegistrar( m_SrvMgr, m_DataFormatTranslator ) 89 { 90 } 91 92 //------------------------------------------------------------------------ 93 // IUnknown->QueryInterface 94 //------------------------------------------------------------------------ 95 96 STDMETHODIMP CXTDataObject::QueryInterface( REFIID iid, LPVOID* ppvObject ) 97 { 98 if ( NULL == ppvObject ) 99 return E_INVALIDARG; 100 101 HRESULT hr = E_NOINTERFACE; 102 103 *ppvObject = NULL; 104 if ( ( __uuidof( IUnknown ) == iid ) || 105 ( __uuidof( IDataObject ) == iid ) ) 106 { 107 *ppvObject = static_cast< IUnknown* >( this ); 108 ( (LPUNKNOWN)*ppvObject )->AddRef( ); 109 hr = S_OK; 110 } 111 112 return hr; 113 } 114 115 //------------------------------------------------------------------------ 116 // IUnknown->AddRef 117 //------------------------------------------------------------------------ 118 119 STDMETHODIMP_(ULONG) CXTDataObject::AddRef( ) 120 { 121 return static_cast< ULONG >( InterlockedIncrement( &m_nRefCnt ) ); 122 } 123 124 //------------------------------------------------------------------------ 125 // IUnknown->Release 126 //------------------------------------------------------------------------ 127 128 STDMETHODIMP_(ULONG) CXTDataObject::Release( ) 129 { 130 ULONG nRefCnt = 131 static_cast< ULONG >( InterlockedDecrement( &m_nRefCnt ) ); 132 133 if ( 0 == nRefCnt ) 134 delete this; 135 136 return nRefCnt; 137 } 138 139 //------------------------------------------------------------------------ 140 // 141 //------------------------------------------------------------------------ 142 143 STDMETHODIMP CXTDataObject::GetData( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium ) 144 { 145 if ( !(pFormatetc && pmedium) ) 146 return E_INVALIDARG; 147 148 try 149 { 150 // prepare data transfer 151 invalidateStgMedium( *pmedium ); 152 validateFormatEtc( pFormatetc ); 153 154 // handle locale request, because locale is a artificial format for us 155 if ( CF_LOCALE == pFormatetc->cfFormat ) 156 renderLocaleAndSetupStgMedium( *pFormatetc, *pmedium ); 157 else if ( CF_UNICODETEXT == pFormatetc->cfFormat ) 158 renderUnicodeAndSetupStgMedium( *pFormatetc, *pmedium ); 159 else 160 renderAnyDataAndSetupStgMedium( *pFormatetc, *pmedium ); 161 } 162 catch(UnsupportedFlavorException&) 163 { 164 HRESULT hr = DV_E_FORMATETC; 165 166 if ( m_FormatRegistrar.isSynthesizeableFormat( *pFormatetc ) ) 167 hr = renderSynthesizedFormatAndSetupStgMedium( *pFormatetc, *pmedium ); 168 169 return hr; 170 } 171 catch( CInvalidFormatEtcException& ex ) 172 { 173 return ex.m_hr; 174 } 175 catch( CStgTransferHelper::CStgTransferException& ex ) 176 { 177 return translateStgExceptionCode( ex.m_hr ); 178 } 179 catch(...) 180 { 181 return E_UNEXPECTED; 182 } 183 184 return S_OK; 185 } 186 187 //------------------------------------------------------------------------ 188 // 189 //------------------------------------------------------------------------ 190 191 // inline 192 void SAL_CALL CXTDataObject::renderDataAndSetupStgMedium( 193 const sal_Int8* lpStorage, const FORMATETC& fetc, sal_uInt32 nInitStgSize, 194 sal_uInt32 nBytesToTransfer, STGMEDIUM& stgmedium ) 195 { 196 OSL_PRECOND( !nInitStgSize || nInitStgSize && (nInitStgSize >= nBytesToTransfer), 197 "Memory size less than number of bytes to transfer" ); 198 199 CStgTransferHelper stgTransfHelper( AUTO_INIT ); 200 201 // setup storage size 202 if ( nInitStgSize > 0 ) 203 stgTransfHelper.init( nInitStgSize, GHND ); 204 205 #if OSL_DEBUG_LEVEL > 0 206 sal_uInt32 nBytesWritten = 0; 207 stgTransfHelper.write( lpStorage, nBytesToTransfer, &nBytesWritten ); 208 OSL_ASSERT( nBytesWritten == nBytesToTransfer ); 209 #else 210 stgTransfHelper.write( lpStorage, nBytesToTransfer ); 211 #endif 212 213 setupStgMedium( fetc, stgTransfHelper, stgmedium ); 214 } 215 216 //------------------------------------------------------------------------ 217 // 218 //------------------------------------------------------------------------ 219 220 //inline 221 void SAL_CALL CXTDataObject::renderLocaleAndSetupStgMedium( 222 FORMATETC& fetc, STGMEDIUM& stgmedium ) 223 { 224 if ( m_FormatRegistrar.hasSynthesizedLocale( ) ) 225 { 226 LCID lcid = m_FormatRegistrar.getSynthesizedLocale( ); 227 renderDataAndSetupStgMedium( 228 reinterpret_cast< sal_Int8* >( &lcid ), 229 fetc, 230 0, 231 sizeof( LCID ), 232 stgmedium ); 233 } 234 else 235 throw CInvalidFormatEtcException( DV_E_FORMATETC ); 236 } 237 238 //------------------------------------------------------------------------ 239 // 240 //------------------------------------------------------------------------ 241 242 //inline 243 void SAL_CALL CXTDataObject::renderUnicodeAndSetupStgMedium( 244 FORMATETC& fetc, STGMEDIUM& stgmedium ) 245 { 246 DataFlavor aFlavor = formatEtcToDataFlavor( fetc ); 247 248 Any aAny = m_XTransferable->getTransferData( aFlavor ); 249 250 // unfortunately not all transferables fulfill the 251 // spec. an do throw an UnsupportedFlavorException 252 // so we must check the any 253 if ( !aAny.hasValue( ) ) 254 { 255 OSL_ENSURE( sal_False, "XTransferable should throw an exception if ask for an unsupported flavor" ); 256 throw UnsupportedFlavorException( ); 257 } 258 259 OUString aText; 260 aAny >>= aText; 261 262 sal_uInt32 nBytesToTransfer = aText.getLength( ) * sizeof( sal_Unicode ); 263 264 // to be sure there is an ending 0 265 sal_uInt32 nRequiredMemSize = nBytesToTransfer + sizeof( sal_Unicode ); 266 267 renderDataAndSetupStgMedium( 268 reinterpret_cast< const sal_Int8* >( aText.getStr( ) ), 269 fetc, 270 nRequiredMemSize, 271 nBytesToTransfer, 272 stgmedium ); 273 } 274 275 //------------------------------------------------------------------------ 276 // 277 //------------------------------------------------------------------------ 278 279 //inline 280 void SAL_CALL CXTDataObject::renderAnyDataAndSetupStgMedium( 281 FORMATETC& fetc, STGMEDIUM& stgmedium ) 282 { 283 DataFlavor aFlavor = formatEtcToDataFlavor( fetc ); 284 285 Any aAny = m_XTransferable->getTransferData( aFlavor ); 286 287 // unfortunately not all transferables fulfill the 288 // spec. an do throw an UnsupportedFlavorException 289 // so we must check the any 290 if ( !aAny.hasValue( ) ) 291 { 292 OSL_ENSURE( sal_False, "XTransferable should throw an exception if ask for an unsupported flavor" ); 293 throw UnsupportedFlavorException( ); 294 } 295 296 // unfortunately not all transferables fulfill the 297 // spec. an do throw an UnsupportedFlavorException 298 // so we must check the any 299 if ( !aAny.hasValue( ) ) 300 throw UnsupportedFlavorException( ); 301 302 Sequence< sal_Int8 > clipDataStream; 303 aAny >>= clipDataStream; 304 305 sal_uInt32 nRequiredMemSize = 0; 306 if ( m_DataFormatTranslator.isOemOrAnsiTextFormat( fetc.cfFormat ) ) 307 nRequiredMemSize = sizeof( sal_Int8 ) * clipDataStream.getLength( ) + 1; 308 309 // prepare data for transmision 310 if ( CF_DIB == fetc.cfFormat ) 311 clipDataStream = OOBmpToWinDIB( clipDataStream ); 312 313 if ( CF_METAFILEPICT == fetc.cfFormat ) 314 { 315 stgmedium.tymed = TYMED_MFPICT; 316 stgmedium.hMetaFilePict = OOMFPictToWinMFPict( clipDataStream ); 317 stgmedium.pUnkForRelease = NULL; 318 } 319 else if( CF_ENHMETAFILE == fetc.cfFormat ) 320 { 321 stgmedium.tymed = TYMED_ENHMF; 322 stgmedium.hMetaFilePict = OOMFPictToWinENHMFPict( clipDataStream ); 323 stgmedium.pUnkForRelease = NULL; 324 } 325 else 326 renderDataAndSetupStgMedium( 327 clipDataStream.getArray( ), 328 fetc, 329 nRequiredMemSize, 330 clipDataStream.getLength( ), 331 stgmedium ); 332 } 333 334 //------------------------------------------------------------------------ 335 // 336 //------------------------------------------------------------------------ 337 338 HRESULT SAL_CALL CXTDataObject::renderSynthesizedFormatAndSetupStgMedium( FORMATETC& fetc, STGMEDIUM& stgmedium ) 339 { 340 HRESULT hr = S_OK; 341 342 try 343 { 344 if ( CF_UNICODETEXT == fetc.cfFormat ) 345 // the transferable seems to have only text 346 renderSynthesizedUnicodeAndSetupStgMedium( fetc, stgmedium ); 347 else if ( m_DataFormatTranslator.isOemOrAnsiTextFormat( fetc.cfFormat ) ) 348 // the transferable seems to have only unicode text 349 renderSynthesizedTextAndSetupStgMedium( fetc, stgmedium ); 350 else 351 // the transferable seems to have only text/html 352 renderSynthesizedHtmlAndSetupStgMedium( fetc, stgmedium ); 353 } 354 catch(UnsupportedFlavorException&) 355 { 356 hr = DV_E_FORMATETC; 357 } 358 catch( CInvalidFormatEtcException& ) 359 { 360 OSL_ENSURE( sal_False, "Unexpected exception" ); 361 } 362 catch( CStgTransferHelper::CStgTransferException& ex ) 363 { 364 return translateStgExceptionCode( ex.m_hr ); 365 } 366 catch(...) 367 { 368 hr = E_UNEXPECTED; 369 } 370 371 return hr; 372 } 373 374 //------------------------------------------------------------------------ 375 // the transferable must have only text, so we will synthesize unicode text 376 //------------------------------------------------------------------------ 377 378 void SAL_CALL CXTDataObject::renderSynthesizedUnicodeAndSetupStgMedium( FORMATETC& fetc, STGMEDIUM& stgmedium ) 379 { 380 OSL_ASSERT( CF_UNICODETEXT == fetc.cfFormat ); 381 382 Any aAny = m_XTransferable->getTransferData( m_FormatRegistrar.getRegisteredTextFlavor( ) ); 383 384 // unfortunately not all transferables fulfill the 385 // spec. an do throw an UnsupportedFlavorException 386 // so we must check the any 387 if ( !aAny.hasValue( ) ) 388 { 389 OSL_ENSURE( sal_False, "XTransferable should throw an exception if ask for an unsupported flavor" ); 390 throw UnsupportedFlavorException( ); 391 } 392 393 Sequence< sal_Int8 > aText; 394 aAny >>= aText; 395 396 CStgTransferHelper stgTransfHelper; 397 398 MultiByteToWideCharEx( 399 m_FormatRegistrar.getRegisteredTextCodePage( ), 400 reinterpret_cast< char* >( aText.getArray( ) ), 401 aText.getLength( ), 402 stgTransfHelper ); 403 404 setupStgMedium( fetc, stgTransfHelper, stgmedium ); 405 } 406 407 //------------------------------------------------------------------------ 408 // the transferable must have only unicode text so we will sythesize text 409 //------------------------------------------------------------------------ 410 411 void SAL_CALL CXTDataObject::renderSynthesizedTextAndSetupStgMedium( FORMATETC& fetc, STGMEDIUM& stgmedium ) 412 { 413 OSL_ASSERT( m_DataFormatTranslator.isOemOrAnsiTextFormat( fetc.cfFormat ) ); 414 415 DataFlavor aFlavor = formatEtcToDataFlavor( 416 m_DataFormatTranslator.getFormatEtcForClipformat( CF_UNICODETEXT ) ); 417 418 Any aAny = m_XTransferable->getTransferData( aFlavor ); 419 420 // unfortunately not all transferables fulfill the 421 // spec. an do throw an UnsupportedFlavorException 422 // so we must check the any 423 if ( !aAny.hasValue( ) ) 424 { 425 OSL_ENSURE( sal_False, "XTransferable should throw an exception if ask for an unsupported flavor" ); 426 throw UnsupportedFlavorException( ); 427 } 428 429 OUString aUnicodeText; 430 aAny >>= aUnicodeText; 431 432 CStgTransferHelper stgTransfHelper; 433 434 WideCharToMultiByteEx( 435 GetACP( ), 436 reinterpret_cast<LPCWSTR>( aUnicodeText.getStr( ) ), 437 aUnicodeText.getLength( ), 438 stgTransfHelper ); 439 440 setupStgMedium( fetc, stgTransfHelper, stgmedium ); 441 } 442 443 //------------------------------------------------------------------------ 444 // 445 //------------------------------------------------------------------------ 446 447 void SAL_CALL CXTDataObject::renderSynthesizedHtmlAndSetupStgMedium( FORMATETC& fetc, STGMEDIUM& stgmedium ) 448 { 449 OSL_ASSERT( m_DataFormatTranslator.isHTMLFormat( fetc.cfFormat ) ); 450 451 DataFlavor aFlavor; 452 453 // creating a DataFlavor on the fly 454 aFlavor.MimeType = OUString::createFromAscii( "text/html" ); 455 aFlavor.DataType = getCppuType( (Sequence< sal_Int8 >*)0 ); 456 457 Any aAny = m_XTransferable->getTransferData( aFlavor ); 458 459 // unfortunately not all transferables fulfill the 460 // spec. an do throw an UnsupportedFlavorException 461 // so we must check the any 462 if ( !aAny.hasValue( ) ) 463 { 464 OSL_ENSURE( sal_False, "XTransferable should throw an exception if ask for an unsupported flavor" ); 465 throw UnsupportedFlavorException( ); 466 } 467 468 Sequence< sal_Int8 > aTextHtmlSequence; 469 aAny >>= aTextHtmlSequence; 470 471 Sequence< sal_Int8 > aHTMLFormatSequence = TextHtmlToHTMLFormat( aTextHtmlSequence ); 472 473 sal_uInt32 nBytesToTransfer = aHTMLFormatSequence.getLength( ); 474 475 renderDataAndSetupStgMedium( 476 reinterpret_cast< const sal_Int8* >( aHTMLFormatSequence.getArray( ) ), 477 fetc, 478 0, 479 nBytesToTransfer, 480 stgmedium ); 481 } 482 483 //------------------------------------------------------------------------ 484 // IDataObject->EnumFormatEtc 485 //------------------------------------------------------------------------ 486 487 STDMETHODIMP CXTDataObject::EnumFormatEtc( 488 DWORD dwDirection, IEnumFORMATETC** ppenumFormatetc ) 489 { 490 if ( NULL == ppenumFormatetc ) 491 return E_INVALIDARG; 492 493 if ( DATADIR_SET == dwDirection ) 494 return E_NOTIMPL; 495 496 *ppenumFormatetc = NULL; 497 498 InitializeFormatEtcContainer( ); 499 500 HRESULT hr; 501 if ( DATADIR_GET == dwDirection ) 502 { 503 *ppenumFormatetc = new CEnumFormatEtc( this, m_FormatEtcContainer ); 504 if ( NULL != *ppenumFormatetc ) 505 static_cast< LPUNKNOWN >( *ppenumFormatetc )->AddRef( ); 506 507 hr = ( NULL != *ppenumFormatetc ) ? S_OK : E_OUTOFMEMORY; 508 } 509 else 510 hr = E_INVALIDARG; 511 512 return hr; 513 } 514 515 //------------------------------------------------------------------------ 516 // IDataObject->QueryGetData 517 //------------------------------------------------------------------------ 518 519 STDMETHODIMP CXTDataObject::QueryGetData( LPFORMATETC pFormatetc ) 520 { 521 if ( (NULL == pFormatetc) || IsBadReadPtr( pFormatetc, sizeof( FORMATETC ) ) ) 522 return E_INVALIDARG; 523 524 InitializeFormatEtcContainer( ); 525 526 return m_FormatEtcContainer.hasFormatEtc( *pFormatetc ) ? S_OK : S_FALSE; 527 } 528 529 //------------------------------------------------------------------------ 530 // IDataObject->GetDataHere 531 //------------------------------------------------------------------------ 532 533 STDMETHODIMP CXTDataObject::GetDataHere( LPFORMATETC, LPSTGMEDIUM ) 534 { 535 return E_NOTIMPL; 536 } 537 538 //------------------------------------------------------------------------ 539 // IDataObject->GetCanonicalFormatEtc 540 //------------------------------------------------------------------------ 541 542 STDMETHODIMP CXTDataObject::GetCanonicalFormatEtc( LPFORMATETC, LPFORMATETC ) 543 { 544 return E_NOTIMPL; 545 } 546 547 //------------------------------------------------------------------------ 548 // IDataObject->SetData 549 //------------------------------------------------------------------------ 550 551 STDMETHODIMP CXTDataObject::SetData( LPFORMATETC, LPSTGMEDIUM, BOOL ) 552 { 553 return E_NOTIMPL; 554 } 555 556 //------------------------------------------------------------------------ 557 // IDataObject->DAdvise 558 //------------------------------------------------------------------------ 559 560 STDMETHODIMP CXTDataObject::DAdvise( LPFORMATETC, DWORD, LPADVISESINK, DWORD * ) 561 { 562 return E_NOTIMPL; 563 } 564 565 //------------------------------------------------------------------------ 566 // IDataObject->DUnadvise 567 //------------------------------------------------------------------------ 568 569 STDMETHODIMP CXTDataObject::DUnadvise( DWORD ) 570 { 571 return E_NOTIMPL; 572 } 573 574 //------------------------------------------------------------------------ 575 // IDataObject->EnumDAdvise 576 //------------------------------------------------------------------------ 577 578 STDMETHODIMP CXTDataObject::EnumDAdvise( LPENUMSTATDATA * ) 579 { 580 return E_NOTIMPL; 581 } 582 583 //------------------------------------------------------------------------ 584 // for our convenience 585 //------------------------------------------------------------------------ 586 587 CXTDataObject::operator IDataObject*( ) 588 { 589 return static_cast< IDataObject* >( this ); 590 } 591 592 //------------------------------------------------------------------------ 593 // 594 //------------------------------------------------------------------------ 595 596 inline 597 DataFlavor SAL_CALL CXTDataObject::formatEtcToDataFlavor( const FORMATETC& aFormatEtc ) const 598 { 599 DataFlavor aFlavor; 600 601 if ( m_FormatRegistrar.hasSynthesizedLocale( ) ) 602 aFlavor = 603 m_DataFormatTranslator.getDataFlavorFromFormatEtc( aFormatEtc, m_FormatRegistrar.getSynthesizedLocale( ) ); 604 else 605 aFlavor = m_DataFormatTranslator.getDataFlavorFromFormatEtc( aFormatEtc ); 606 607 if ( !aFlavor.MimeType.getLength( ) ) 608 throw UnsupportedFlavorException( ); 609 610 return aFlavor; 611 } 612 613 //------------------------------------------------------------------------ 614 // 615 //------------------------------------------------------------------------ 616 617 inline 618 void CXTDataObject::validateFormatEtc( LPFORMATETC lpFormatEtc ) const 619 { 620 OSL_ASSERT( lpFormatEtc ); 621 622 if ( lpFormatEtc->lindex != -1 ) 623 throw CInvalidFormatEtcException( DV_E_LINDEX ); 624 625 if ( !(lpFormatEtc->dwAspect & DVASPECT_CONTENT) && 626 !(lpFormatEtc->dwAspect & DVASPECT_SHORTNAME) ) 627 throw CInvalidFormatEtcException( DV_E_DVASPECT ); 628 629 if ( !(lpFormatEtc->tymed & TYMED_HGLOBAL) && 630 !(lpFormatEtc->tymed & TYMED_ISTREAM) && 631 !(lpFormatEtc->tymed & TYMED_MFPICT) && 632 !(lpFormatEtc->tymed & TYMED_ENHMF) ) 633 throw CInvalidFormatEtcException( DV_E_TYMED ); 634 635 if ( lpFormatEtc->cfFormat == CF_METAFILEPICT && 636 !(lpFormatEtc->tymed & TYMED_MFPICT) ) 637 throw CInvalidFormatEtcException( DV_E_TYMED ); 638 639 if ( lpFormatEtc->cfFormat == CF_ENHMETAFILE && 640 !(lpFormatEtc->tymed & TYMED_ENHMF) ) 641 throw CInvalidFormatEtcException( DV_E_TYMED ); 642 } 643 644 //------------------------------------------------------------------------ 645 // 646 //------------------------------------------------------------------------ 647 648 //inline 649 void SAL_CALL CXTDataObject::setupStgMedium( const FORMATETC& fetc, 650 CStgTransferHelper& stgTransHlp, 651 STGMEDIUM& stgmedium ) 652 { 653 stgmedium.pUnkForRelease = NULL; 654 655 if ( fetc.cfFormat == CF_METAFILEPICT ) 656 { 657 stgmedium.tymed = TYMED_MFPICT; 658 stgmedium.hMetaFilePict = static_cast< HMETAFILEPICT >( stgTransHlp.getHGlobal( ) ); 659 } 660 else if ( fetc.cfFormat == CF_ENHMETAFILE ) 661 { 662 stgmedium.tymed = TYMED_ENHMF; 663 stgmedium.hEnhMetaFile = static_cast< HENHMETAFILE >( stgTransHlp.getHGlobal( ) ); 664 } 665 else if ( fetc.tymed & TYMED_HGLOBAL ) 666 { 667 stgmedium.tymed = TYMED_HGLOBAL; 668 stgmedium.hGlobal = stgTransHlp.getHGlobal( ); 669 } 670 else if ( fetc.tymed & TYMED_ISTREAM ) 671 { 672 stgmedium.tymed = TYMED_ISTREAM; 673 stgTransHlp.getIStream( &stgmedium.pstm ); 674 } 675 else 676 OSL_ASSERT( sal_False ); 677 } 678 679 //------------------------------------------------------------------------ 680 // 681 //------------------------------------------------------------------------ 682 683 inline 684 void SAL_CALL CXTDataObject::invalidateStgMedium( STGMEDIUM& stgmedium ) const 685 { 686 stgmedium.tymed = TYMED_NULL; 687 } 688 689 //------------------------------------------------------------------------ 690 // 691 //------------------------------------------------------------------------ 692 693 inline 694 HRESULT SAL_CALL CXTDataObject::translateStgExceptionCode( HRESULT hr ) const 695 { 696 HRESULT hrTransl; 697 698 switch( hr ) 699 { 700 case STG_E_MEDIUMFULL: 701 hrTransl = hr; 702 break; 703 704 default: 705 hrTransl = E_UNEXPECTED; 706 break; 707 } 708 709 return hrTransl; 710 } 711 712 //------------------------------------------------------------------------ 713 // 714 //------------------------------------------------------------------------ 715 716 inline void SAL_CALL CXTDataObject::InitializeFormatEtcContainer( ) 717 { 718 if ( !m_bFormatEtcContainerInitialized ) 719 { 720 m_FormatRegistrar.RegisterFormats( m_XTransferable, m_FormatEtcContainer ); 721 m_bFormatEtcContainerInitialized = sal_True; 722 } 723 } 724 725 //============================================================================ 726 // CEnumFormatEtc 727 //============================================================================ 728 729 //---------------------------------------------------------------------------- 730 // ctor 731 //---------------------------------------------------------------------------- 732 733 CEnumFormatEtc::CEnumFormatEtc( LPUNKNOWN lpUnkOuter, const CFormatEtcContainer& aFormatEtcContainer ) : 734 m_nRefCnt( 0 ), 735 m_lpUnkOuter( lpUnkOuter ), 736 m_FormatEtcContainer( aFormatEtcContainer ) 737 { 738 Reset( ); 739 } 740 741 //---------------------------------------------------------------------------- 742 // IUnknown->QueryInterface 743 //---------------------------------------------------------------------------- 744 745 STDMETHODIMP CEnumFormatEtc::QueryInterface( REFIID iid, LPVOID* ppvObject ) 746 { 747 if ( NULL == ppvObject ) 748 return E_INVALIDARG; 749 750 HRESULT hr = E_NOINTERFACE; 751 752 *ppvObject = NULL; 753 754 if ( ( __uuidof( IUnknown ) == iid ) || 755 ( __uuidof( IEnumFORMATETC ) == iid ) ) 756 { 757 *ppvObject = static_cast< IUnknown* >( this ); 758 static_cast< LPUNKNOWN >( *ppvObject )->AddRef( ); 759 hr = S_OK; 760 } 761 762 return hr; 763 } 764 765 //---------------------------------------------------------------------------- 766 // IUnknown->AddRef 767 //---------------------------------------------------------------------------- 768 769 STDMETHODIMP_(ULONG) CEnumFormatEtc::AddRef( ) 770 { 771 // keep the dataobject alive 772 m_lpUnkOuter->AddRef( ); 773 return InterlockedIncrement( &m_nRefCnt ); 774 } 775 776 //---------------------------------------------------------------------------- 777 // IUnknown->Release 778 //---------------------------------------------------------------------------- 779 780 STDMETHODIMP_(ULONG) CEnumFormatEtc::Release( ) 781 { 782 // release the outer dataobject 783 m_lpUnkOuter->Release( ); 784 785 ULONG nRefCnt = InterlockedDecrement( &m_nRefCnt ); 786 if ( 0 == nRefCnt ) 787 delete this; 788 789 return nRefCnt; 790 } 791 792 //---------------------------------------------------------------------------- 793 // IEnumFORMATETC->Next 794 //---------------------------------------------------------------------------- 795 796 STDMETHODIMP CEnumFormatEtc::Next( ULONG nRequested, LPFORMATETC lpDest, ULONG* lpFetched ) 797 { 798 if ( ( nRequested < 1 ) || 799 (( nRequested > 1 ) && ( NULL == lpFetched )) || 800 IsBadWritePtr( lpDest, sizeof( FORMATETC ) * nRequested ) ) 801 return E_INVALIDARG; 802 803 sal_uInt32 nFetched = m_FormatEtcContainer.nextFormatEtc( lpDest, nRequested ); 804 805 if ( NULL != lpFetched ) 806 *lpFetched = nFetched; 807 808 return (nFetched == nRequested) ? S_OK : S_FALSE; 809 } 810 811 //---------------------------------------------------------------------------- 812 // IEnumFORMATETC->Skip 813 //---------------------------------------------------------------------------- 814 815 STDMETHODIMP CEnumFormatEtc::Skip( ULONG celt ) 816 { 817 return m_FormatEtcContainer.skipFormatEtc( celt ) ? S_OK : S_FALSE; 818 } 819 820 //---------------------------------------------------------------------------- 821 // IEnumFORMATETC->Reset 822 //---------------------------------------------------------------------------- 823 824 STDMETHODIMP CEnumFormatEtc::Reset( ) 825 { 826 m_FormatEtcContainer.beginEnumFormatEtc( ); 827 return S_OK; 828 } 829 830 //---------------------------------------------------------------------------- 831 // IEnumFORMATETC->Clone 832 //---------------------------------------------------------------------------- 833 834 STDMETHODIMP CEnumFormatEtc::Clone( IEnumFORMATETC** ppenum ) 835 { 836 if ( NULL == ppenum ) 837 return E_INVALIDARG; 838 839 *ppenum = new CEnumFormatEtc( m_lpUnkOuter, m_FormatEtcContainer ); 840 if ( NULL != ppenum ) 841 static_cast< LPUNKNOWN >( *ppenum )->AddRef( ); 842 843 return ( NULL != *ppenum ) ? S_OK : E_OUTOFMEMORY; 844 } 845