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