1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <oox/ole/olehelper.hxx>
22 #include <rtl/ustrbuf.hxx>
23 #include <sot/storage.hxx>
24 #include <osl/diagnose.h>
25 #include <oox/helper/binaryinputstream.hxx>
26 #include <oox/helper/binaryoutputstream.hxx>
27 #include <oox/helper/graphichelper.hxx>
28 #include <oox/token/properties.hxx>
29 #include <oox/token/tokens.hxx>
30 #include <oox/ole/axcontrol.hxx>
31 #include <oox/helper/propertymap.hxx>
32 #include <oox/helper/propertyset.hxx>
34 #include <com/sun/star/awt/XControlModel.hpp>
35 #include <com/sun/star/beans/XPropertySet.hpp>
36 #include <com/sun/star/form/FormComponentType.hpp>
37 #include <com/sun/star/form/XFormComponent.hpp>
38 #include <com/sun/star/frame/XFrame.hpp>
39 #include <com/sun/star/frame/XModel.hpp>
40 #include <com/sun/star/lang/XServiceInfo.hpp>
41 #include <com/sun/star/awt/Size.hpp>
42 #include <com/sun/star/uno/XComponentContext.hpp>
44 #include <tools/globname.hxx>
45 #include <unotools/streamwrap.hxx>
46 #include <comphelper/processfactory.hxx>
51 using ::com::sun::star::form::XFormComponent
;
52 using ::com::sun::star::awt::XControlModel
;
53 using ::com::sun::star::awt::Size
;
54 using ::com::sun::star::frame::XModel
;
55 using ::com::sun::star::io::XOutputStream
;
56 using ::com::sun::star::io::XInputStream
;
57 using ::com::sun::star::beans::XPropertySet
;
58 using ::com::sun::star::uno::Reference
;
59 using ::com::sun::star::uno::UNO_QUERY
;
60 using ::com::sun::star::uno::XComponentContext
;
61 using ::com::sun::star::lang::XServiceInfo
;
63 using namespace ::com::sun::star::form
;
67 const sal_uInt32 OLE_COLORTYPE_MASK
= 0xFF000000;
68 const sal_uInt32 OLE_COLORTYPE_CLIENT
= 0x00000000;
69 const sal_uInt32 OLE_COLORTYPE_PALETTE
= 0x01000000;
70 const sal_uInt32 OLE_COLORTYPE_BGR
= 0x02000000;
71 const sal_uInt32 OLE_COLORTYPE_SYSCOLOR
= 0x80000000;
73 const sal_uInt32 OLE_PALETTECOLOR_MASK
= 0x0000FFFF;
74 const sal_uInt32 OLE_SYSTEMCOLOR_MASK
= 0x0000FFFF;
76 /** Swaps the red and blue component of the passed color. */
77 sal_uInt32
lclSwapRedBlue( sal_uInt32 nColor
)
79 return static_cast< sal_uInt32
>( (nColor
& 0xFF00FF00) | ((nColor
& 0x0000FF) << 16) | ((nColor
& 0xFF0000) >> 16) );
82 /** Returns the UNO RGB color from the passed encoded OLE BGR color. */
83 ::Color
lclDecodeBgrColor( sal_uInt32 nOleColor
)
85 return ::Color( ColorTransparency
, lclSwapRedBlue( nOleColor
) & 0xFFFFFF );
88 const sal_uInt32 OLE_STDPIC_ID
= 0x0000746C;
102 const sal_Int16 TOGGLEBUTTON
= -1;
103 const sal_Int16 FORMULAFIELD
= -2;
105 typedef std::map
< sal_Int16
, GUIDCNamePair
> GUIDCNamePairMap
;
106 class classIdToGUIDCNamePairMap
108 GUIDCNamePairMap mnIdToGUIDCNamePairMap
;
109 classIdToGUIDCNamePairMap();
111 static GUIDCNamePairMap
& get();
114 classIdToGUIDCNamePairMap::classIdToGUIDCNamePairMap()
116 static IdCntrlData
const initialCntrlData
[] =
118 // Command button MUST be at index 0
119 { FormComponentType::COMMANDBUTTON
,
120 { AX_GUID_COMMANDBUTTON
, "CommandButton"} ,
122 // Toggle button MUST be at index 1
124 { AX_GUID_TOGGLEBUTTON
, "ToggleButton"},
126 { FormComponentType::FIXEDTEXT
,
127 { AX_GUID_LABEL
, "Label"},
129 { FormComponentType::TEXTFIELD
,
130 { AX_GUID_TEXTBOX
, "TextBox"},
132 { FormComponentType::LISTBOX
,
133 { AX_GUID_LISTBOX
, "ListBox"},
135 { FormComponentType::COMBOBOX
,
136 { AX_GUID_COMBOBOX
, "ComboBox"},
138 { FormComponentType::CHECKBOX
,
139 { AX_GUID_CHECKBOX
, "CheckBox"},
141 { FormComponentType::RADIOBUTTON
,
142 { AX_GUID_OPTIONBUTTON
, "OptionButton"},
144 { FormComponentType::IMAGECONTROL
,
145 { AX_GUID_IMAGE
, "Image"},
147 { FormComponentType::DATEFIELD
,
148 { AX_GUID_TEXTBOX
, "TextBox"},
150 { FormComponentType::TIMEFIELD
,
151 { AX_GUID_TEXTBOX
, "TextBox"},
153 { FormComponentType::NUMERICFIELD
,
154 { AX_GUID_TEXTBOX
, "TextBox"},
156 { FormComponentType::CURRENCYFIELD
,
157 { AX_GUID_TEXTBOX
, "TextBox"},
159 { FormComponentType::PATTERNFIELD
,
160 { AX_GUID_TEXTBOX
, "TextBox"},
163 { AX_GUID_TEXTBOX
, "TextBox"},
165 { FormComponentType::IMAGEBUTTON
,
166 { AX_GUID_COMMANDBUTTON
, "CommandButton"},
168 { FormComponentType::SPINBUTTON
,
169 { AX_GUID_SPINBUTTON
, "SpinButton"},
171 { FormComponentType::SCROLLBAR
,
172 { AX_GUID_SCROLLBAR
, "ScrollBar"},
175 int const length
= std::size( initialCntrlData
);
176 IdCntrlData
const * pData
= initialCntrlData
;
177 for ( int index
= 0; index
< length
; ++index
, ++pData
)
178 mnIdToGUIDCNamePairMap
[ pData
->nId
] = pData
->aData
;
181 GUIDCNamePairMap
& classIdToGUIDCNamePairMap::get()
183 static classIdToGUIDCNamePairMap theInst
;
184 return theInst
.mnIdToGUIDCNamePairMap
;
187 template< typename Type
>
188 void lclAppendHex( OUStringBuffer
& orBuffer
, Type nValue
)
190 const sal_Int32 nWidth
= 2 * sizeof( Type
);
191 static const sal_Unicode spcHexChars
[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
192 orBuffer
.setLength( orBuffer
.getLength() + nWidth
);
193 for( sal_Int32 nCharIdx
= orBuffer
.getLength() - 1, nCharEnd
= nCharIdx
- nWidth
; nCharIdx
> nCharEnd
; --nCharIdx
, nValue
>>= 4 )
194 orBuffer
[nCharIdx
] = spcHexChars
[ nValue
& 0xF ];
199 StdFontInfo::StdFontInfo() :
201 mnWeight( OLE_STDFONT_NORMAL
),
202 mnCharSet( WINDOWS_CHARSET_ANSI
),
207 StdFontInfo::StdFontInfo( OUString aName
, sal_uInt32 nHeight
) :
208 maName(std::move( aName
)),
210 mnWeight( OLE_STDFONT_NORMAL
),
211 mnCharSet( WINDOWS_CHARSET_ANSI
),
216 ::Color
OleHelper::decodeOleColor(
217 const GraphicHelper
& rGraphicHelper
, sal_uInt32 nOleColor
, bool bDefaultColorBgr
)
219 static const sal_Int32 spnSystemColors
[] =
221 XML_scrollBar
, XML_background
, XML_activeCaption
, XML_inactiveCaption
,
222 XML_menu
, XML_window
, XML_windowFrame
, XML_menuText
,
223 XML_windowText
, XML_captionText
, XML_activeBorder
, XML_inactiveBorder
,
224 XML_appWorkspace
, XML_highlight
, XML_highlightText
, XML_btnFace
,
225 XML_btnShadow
, XML_grayText
, XML_btnText
, XML_inactiveCaptionText
,
226 XML_btnHighlight
, XML_3dDkShadow
, XML_3dLight
, XML_infoText
,
230 switch( nOleColor
& OLE_COLORTYPE_MASK
)
232 case OLE_COLORTYPE_CLIENT
:
233 return bDefaultColorBgr
? lclDecodeBgrColor( nOleColor
) : rGraphicHelper
.getPaletteColor( nOleColor
& OLE_PALETTECOLOR_MASK
);
235 case OLE_COLORTYPE_PALETTE
:
236 return rGraphicHelper
.getPaletteColor( nOleColor
& OLE_PALETTECOLOR_MASK
);
238 case OLE_COLORTYPE_BGR
:
239 return lclDecodeBgrColor( nOleColor
);
241 case OLE_COLORTYPE_SYSCOLOR
:
242 return rGraphicHelper
.getSystemColor( STATIC_ARRAY_SELECT( spnSystemColors
, nOleColor
& OLE_SYSTEMCOLOR_MASK
, XML_TOKEN_INVALID
), API_RGB_WHITE
);
244 OSL_FAIL( "OleHelper::decodeOleColor - unknown color type" );
245 return API_RGB_BLACK
;
248 sal_uInt32
OleHelper::encodeOleColor( sal_Int32 nRgbColor
)
250 return OLE_COLORTYPE_BGR
| lclSwapRedBlue( static_cast< sal_uInt32
>( nRgbColor
& 0xFFFFFF ) );
253 void OleHelper::exportGuid( BinaryOutputStream
& rOStr
, const SvGlobalName
& rId
)
255 rOStr
.WriteUInt32( rId
.GetCLSID().Data1
);
256 rOStr
.WriteUInt16( rId
.GetCLSID().Data2
);
257 rOStr
.WriteUInt16( rId
.GetCLSID().Data3
);
258 rOStr
.writeArray( rId
.GetCLSID().Data4
, 8 );
261 OUString
OleHelper::importGuid( BinaryInputStream
& rInStrm
)
263 OUStringBuffer
aBuffer(40);
264 aBuffer
.append( '{' );
265 lclAppendHex( aBuffer
, rInStrm
.readuInt32() );
266 aBuffer
.append( '-' );
267 lclAppendHex( aBuffer
, rInStrm
.readuInt16() );
268 aBuffer
.append( '-' );
269 lclAppendHex( aBuffer
, rInStrm
.readuInt16() );
270 aBuffer
.append( '-' );
271 lclAppendHex( aBuffer
, rInStrm
.readuInt8() );
272 lclAppendHex( aBuffer
, rInStrm
.readuInt8() );
273 aBuffer
.append( '-' );
274 for( int nIndex
= 0; nIndex
< 6; ++nIndex
)
275 lclAppendHex( aBuffer
, rInStrm
.readuInt8() );
276 aBuffer
.append( '}' );
277 return aBuffer
.makeStringAndClear();
280 bool OleHelper::importStdFont( StdFontInfo
& orFontInfo
, BinaryInputStream
& rInStrm
, bool bWithGuid
)
284 bool bIsStdFont
= importGuid( rInStrm
) == OLE_GUID_STDFONT
;
285 OSL_ENSURE( bIsStdFont
, "OleHelper::importStdFont - unexpected header GUID, expected StdFont" );
290 sal_uInt8 nVersion
, nNameLen
;
291 nVersion
= rInStrm
.readuChar();
292 orFontInfo
.mnCharSet
= rInStrm
.readuInt16();
293 orFontInfo
.mnFlags
= rInStrm
.readuChar();
294 orFontInfo
.mnWeight
= rInStrm
.readuInt16();
295 orFontInfo
.mnHeight
= rInStrm
.readuInt32();
296 nNameLen
= rInStrm
.readuChar();
297 // according to spec the name is ASCII
298 orFontInfo
.maName
= rInStrm
.readCharArrayUC( nNameLen
, RTL_TEXTENCODING_ASCII_US
);
299 OSL_ENSURE( nVersion
<= 1, "OleHelper::importStdFont - wrong version" );
300 return !rInStrm
.isEof() && (nVersion
<= 1);
303 bool OleHelper::importStdPic( StreamDataSequence
& orGraphicData
, BinaryInputStream
& rInStrm
)
305 bool bIsStdPic
= importGuid( rInStrm
) == OLE_GUID_STDPIC
;
306 OSL_ENSURE( bIsStdPic
, "OleHelper::importStdPic - unexpected header GUID, expected StdPic" );
310 sal_uInt32 nStdPicId
;
312 nStdPicId
= rInStrm
.readuInt32();
313 nBytes
= rInStrm
.readInt32();
314 OSL_ENSURE( nStdPicId
== OLE_STDPIC_ID
, "OleHelper::importStdPic - unexpected header version" );
315 return !rInStrm
.isEof() && (nStdPicId
== OLE_STDPIC_ID
) && (nBytes
> 0) && (rInStrm
.readData( orGraphicData
, nBytes
) == nBytes
);
318 static Reference
< css::frame::XFrame
> lcl_getFrame( const Reference
< css::frame::XModel
>& rxModel
)
320 Reference
< css::frame::XFrame
> xFrame
;
323 Reference
< css::frame::XController
> xController
= rxModel
->getCurrentController();
324 xFrame
= xController
.is() ? xController
->getFrame() : nullptr;
329 OleFormCtrlExportHelper::OleFormCtrlExportHelper( const Reference
< XComponentContext
>& rxCtx
, const Reference
< XModel
>& rxDocModel
, const Reference
< XControlModel
>& xCntrlModel
) : mpModel( nullptr ), maGrfHelper( rxCtx
, lcl_getFrame( rxDocModel
), StorageRef() ), mxDocModel( rxDocModel
), mxControlModel( xCntrlModel
)
331 // try to get the guid
332 Reference
< css::beans::XPropertySet
> xProps( xCntrlModel
, UNO_QUERY
);
336 sal_Int16 nClassId
= 0;
337 PropertySet
aPropSet( mxControlModel
);
338 if ( !aPropSet
.getProperty( nClassId
, PROP_ClassId
) )
341 /* pseudo ripped from legacy msocximex:
342 "There is a truly horrible thing with EditControls and FormattedField
343 Controls, they both pretend to have an EDITBOX ClassId for compatibility
344 reasons, at some stage in the future hopefully there will be a proper
345 FormulaField ClassId rather than this piggybacking two controls onto the
346 same ClassId, cmc." - when fixed the fake FORMULAFIELD id entry
347 and definition above can be removed/replaced
349 if ( nClassId
== FormComponentType::TEXTFIELD
)
351 Reference
< XServiceInfo
> xInfo( xCntrlModel
,
354 supportsService( "com.sun.star.form.component.FormattedField" ) )
355 nClassId
= FORMULAFIELD
;
357 else if ( nClassId
== FormComponentType::COMMANDBUTTON
)
359 bool bToggle
= false;
360 if ( aPropSet
.getProperty( bToggle
, PROP_Toggle
) && bToggle
)
361 nClassId
= TOGGLEBUTTON
;
363 else if ( nClassId
== FormComponentType::CONTROL
)
365 Reference
< XServiceInfo
> xInfo( xCntrlModel
,
367 if (xInfo
->supportsService("com.sun.star.form.component.ImageControl" ) )
368 nClassId
= FormComponentType::IMAGECONTROL
;
371 GUIDCNamePairMap
& cntrlMap
= classIdToGUIDCNamePairMap::get();
372 GUIDCNamePairMap::iterator it
= cntrlMap
.find( nClassId
);
373 if ( it
!= cntrlMap
.end() )
375 aPropSet
.getProperty(maName
, PROP_Name
);
376 maTypeName
= OUString::createFromAscii( it
->second
.sName
);
377 maFullName
= "Microsoft Forms 2.0 " + maTypeName
;
378 mpControl
.reset(new EmbeddedControl( maName
));
379 maGUID
= OUString::createFromAscii( it
->second
.sGUID
);
380 mpModel
= mpControl
->createModelFromGuid( maGUID
);
384 OleFormCtrlExportHelper::~OleFormCtrlExportHelper()
388 void OleFormCtrlExportHelper::exportName( const Reference
< XOutputStream
>& rxOut
)
390 oox::BinaryXOutputStream
aOut( rxOut
, false );
391 aOut
.writeUnicodeArray( maName
);
395 void OleFormCtrlExportHelper::exportCompObj( const Reference
< XOutputStream
>& rxOut
)
397 oox::BinaryXOutputStream
aOut( rxOut
, false );
399 mpModel
->exportCompObj( aOut
);
402 void OleFormCtrlExportHelper::exportControl( const Reference
< XOutputStream
>& rxOut
, const Size
& rSize
, bool bAutoClose
)
404 oox::BinaryXOutputStream
aOut( rxOut
, bAutoClose
);
407 ::oox::ole::ControlConverter
aConv( mxDocModel
, maGrfHelper
);
409 mpControl
->convertFromProperties( mxControlModel
, aConv
);
410 mpModel
->maSize
.first
= rSize
.Width
;
411 mpModel
->maSize
.second
= rSize
.Height
;
412 mpModel
->exportBinaryModel( aOut
);
416 MSConvertOCXControls::MSConvertOCXControls( const Reference
< css::frame::XModel
>& rxModel
) : SvxMSConvertOCXControls( rxModel
), mxCtx( comphelper::getProcessComponentContext() ), maGrfHelper( mxCtx
, lcl_getFrame( rxModel
), StorageRef() )
420 MSConvertOCXControls::~MSConvertOCXControls()
425 MSConvertOCXControls::importControlFromStream( ::oox::BinaryInputStream
& rInStrm
, Reference
< XFormComponent
>& rxFormComp
, std::u16string_view rGuidString
)
427 ::oox::ole::EmbeddedControl
aControl( "Unknown" );
428 if( ::oox::ole::ControlModelBase
* pModel
= aControl
.createModelFromGuid( rGuidString
) )
430 pModel
->importBinaryModel( rInStrm
);
431 rxFormComp
.set( mxCtx
->getServiceManager()->createInstanceWithContext( pModel
->getServiceName(), mxCtx
), UNO_QUERY
);
432 Reference
< XControlModel
> xCtlModel( rxFormComp
, UNO_QUERY
);
433 ::oox::ole::ControlConverter
aConv( mxModel
, maGrfHelper
);
434 aControl
.convertProperties( xCtlModel
, aConv
);
436 return rxFormComp
.is();
440 MSConvertOCXControls::ReadOCXCtlsStream( tools::SvRef
<SotStorageStream
> const & rSrc1
, Reference
< XFormComponent
> & rxFormComp
,
442 sal_Int32 nStreamSize
)
446 BinaryXInputStream
aCtlsStrm( Reference
< XInputStream
>( new utl::OSeekableInputStreamWrapper( *rSrc1
) ), true );
447 aCtlsStrm
.seek( nPos
);
448 OUString aStrmClassId
= ::oox::ole::OleHelper::importGuid( aCtlsStrm
);
449 return importControlFromStream( aCtlsStrm
, rxFormComp
, aStrmClassId
, nStreamSize
);
454 bool MSConvertOCXControls::importControlFromStream( ::oox::BinaryInputStream
& rInStrm
, Reference
< XFormComponent
>& rxFormComp
, const OUString
& rStrmClassId
,
455 sal_Int32 nStreamSize
)
457 if ( !rInStrm
.isEof() )
459 // Special processing for those html controls
460 bool bOneOfHtmlControls
= false;
461 if ( rStrmClassId
.toAsciiUpperCase() == HTML_GUID_SELECT
462 || rStrmClassId
.toAsciiUpperCase() == HTML_GUID_TEXTBOX
)
463 bOneOfHtmlControls
= true;
465 if ( bOneOfHtmlControls
)
467 // html controls don't seem have a handy record length following the GUID
468 // in the binary stream.
469 // Given the control stream length create a stream of nStreamSize bytes starting from
470 // nPos ( offset by the guid already read in )
473 const int nGuidSize
= 0x10;
474 StreamDataSequence aDataSeq
;
475 sal_Int32 nBytesToRead
= nStreamSize
- nGuidSize
;
476 while ( nBytesToRead
)
477 nBytesToRead
-= rInStrm
.readData( aDataSeq
, nBytesToRead
);
478 SequenceInputStream
aInSeqStream( aDataSeq
);
479 importControlFromStream( aInSeqStream
, rxFormComp
, rStrmClassId
);
483 importControlFromStream( rInStrm
, rxFormComp
, rStrmClassId
);
486 return rxFormComp
.is();
489 bool MSConvertOCXControls::ReadOCXStorage( tools::SvRef
<SotStorage
> const & xOleStg
,
490 Reference
< XFormComponent
> & rxFormComp
)
494 tools::SvRef
<SotStorageStream
> pNameStream
= xOleStg
->OpenSotStream("\3OCXNAME", StreamMode::READ
);
495 BinaryXInputStream
aNameStream( Reference
< XInputStream
>( new utl::OSeekableInputStreamWrapper( *pNameStream
) ), true );
497 tools::SvRef
<SotStorageStream
> pContents
= xOleStg
->OpenSotStream("contents", StreamMode::READ
);
498 BinaryXInputStream
aInStrm( Reference
< XInputStream
>( new utl::OSeekableInputStreamWrapper( *pContents
) ), true );
500 tools::SvRef
<SotStorageStream
> pClsStrm
= xOleStg
->OpenSotStream("\1CompObj", StreamMode::READ
);
501 BinaryXInputStream
aClsStrm( Reference
< XInputStream
>( new utl::OSeekableInputStreamWrapper(*pClsStrm
) ), true );
504 OUString aStrmClassId
= ::oox::ole::OleHelper::importGuid( aClsStrm
);
505 if ( importControlFromStream( aInStrm
, rxFormComp
, aStrmClassId
, aInStrm
.size() ) )
507 OUString aName
= aNameStream
.readNulUnicodeArray();
508 Reference
< XControlModel
> xCtlModel( rxFormComp
, UNO_QUERY
);
509 if ( !aName
.isEmpty() && xCtlModel
.is() )
511 PropertyMap aPropMap
;
512 aPropMap
.setProperty( PROP_Name
, aName
);
513 PropertySet
aPropSet( xCtlModel
);
514 aPropSet
.setProperties( aPropMap
);
516 return rxFormComp
.is();
522 bool MSConvertOCXControls::WriteOCXExcelKludgeStream( const css::uno::Reference
< css::frame::XModel
>& rxModel
, const css::uno::Reference
< css::io::XOutputStream
>& xOutStrm
, const css::uno::Reference
< css::awt::XControlModel
> &rxControlModel
, const css::awt::Size
& rSize
,OUString
&rName
)
524 OleFormCtrlExportHelper
exportHelper( comphelper::getProcessComponentContext(), rxModel
, rxControlModel
);
525 if ( !exportHelper
.isValid() )
527 rName
= exportHelper
.getTypeName();
529 aName
.MakeId(exportHelper
.getGUID());
530 BinaryXOutputStream
aOut( xOutStrm
, false );
531 OleHelper::exportGuid( aOut
, aName
);
532 exportHelper
.exportControl( xOutStrm
, rSize
);
536 bool MSConvertOCXControls::WriteOCXStream( const Reference
< XModel
>& rxModel
, tools::SvRef
<SotStorage
> const &xOleStg
,
537 const Reference
< XControlModel
> &rxControlModel
,
538 const css::awt::Size
& rSize
, OUString
&rName
)
542 OleFormCtrlExportHelper
exportHelper( comphelper::getProcessComponentContext(), rxModel
, rxControlModel
);
544 if ( !exportHelper
.isValid() )
547 aName
.MakeId(exportHelper
.getGUID());
549 OUString sFullName
= exportHelper
.getFullName();
550 rName
= exportHelper
.getTypeName();
551 xOleStg
->SetClass( aName
, SotClipboardFormatId::EMBEDDED_OBJ_OLE
, sFullName
);
553 tools::SvRef
<SotStorageStream
> pNameStream
= xOleStg
->OpenSotStream("\3OCXNAME");
554 Reference
< XOutputStream
> xOut
= new utl::OSeekableOutputStreamWrapper( *pNameStream
);
555 exportHelper
.exportName( xOut
);
558 tools::SvRef
<SotStorageStream
> pObjStream
= xOleStg
->OpenSotStream("\1CompObj");
559 Reference
< XOutputStream
> xOut
= new utl::OSeekableOutputStreamWrapper( *pObjStream
);
560 exportHelper
.exportCompObj( xOut
);
563 tools::SvRef
<SotStorageStream
> pContents
= xOleStg
->OpenSotStream("contents");
564 Reference
< XOutputStream
> xOut
= new utl::OSeekableOutputStreamWrapper( *pContents
);
565 exportHelper
.exportControl( xOut
, rSize
);
572 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */