1 diff --git svx/inc/svx/msocximex.hxx svx/inc/svx/msocximex.hxx
2 index 3d52e4d..1b2b811 100644
3 --- svx/inc/svx/msocximex.hxx
4 +++ svx/inc/svx/msocximex.hxx
5 @@ -532,8 +532,9 @@ public:
6 SotStorageStreamRef getContainerStream() { return mContainerStream; }
8 virtual void ProcessControl( OCX_Control* pControl, SvStorageStream* pS, ContainerRecord& rec );
9 - bool createFromContainerRecord( const ContainerRecord& record,
10 + bool createFromContainerRecord( ContainerRecord& record,
12 + SotStorageStreamRef getContainedControlsStream(){ return mContainedControlsStream; }
14 // This class not meant to be instantiated
15 // needs to be subclassed
16 @@ -548,6 +549,7 @@ protected:
17 com::sun::star::uno::Reference<
18 com::sun::star::container::XNameContainer > mxParent;
19 std::vector<OCX_Control*> mpControls;
20 + std::hash_map<sal_uInt16, sal_uInt16> mActiveXIDMap;
21 SotStorageRef mContainerStorage;
22 SotStorageStreamRef mContainerStream;
23 SotStorageStreamRef mContainedControlsStream;
24 diff --git svx/source/msfilter/msocximex.cxx svx/source/msfilter/msocximex.cxx
25 index 85cabda..a771d13 100644
26 --- svx/source/msfilter/msocximex.cxx
27 +++ svx/source/msfilter/msocximex.cxx
28 @@ -572,8 +572,129 @@ const sal_uInt16 TOGGLEBUTTON = (sal_uIn
29 const sal_uInt16 SCROLLBAR = (sal_uInt16)0x2F;
31 const sal_uInt16 MULTIPAGE = (sal_uInt16)0x39;
32 +// The IDs with bit 0x8000 set appear to be generated.
33 +// It looks like these ID's are used with the non-toolbox [1]
34 +// ActiveX controls that can be present in a Userform
35 +// ( note: RefEdit seems to be an exception )
36 +// In UserForm::Read just before the Container record starts
37 +// you will notice there can be sometimes trailing records,
38 +// it seems that these records have a 1:1 relationship with the non-toolbox
39 +// controls present in the Userform. An id in the trailing record
40 +// seems to identify the specific ActiveX control and an artificial nTypeIdent
41 +// e.g. 0x8000, 0x8001 etc. is created so as to be able to associate
42 +// the ActiveX control when referenced later
43 +// [1] Such ActiveX controls are added via Tools/AddionalControls
46 +// create a fixed set of those special id(s)
47 +// ahem, we can only read one Progress bars at the moment so....
48 const sal_uInt16 PROGRESSBAR = (sal_uInt16)0x8000;
50 +// A set of IDs from the trailing records mentioned above that seem to
51 +// identify the following ActiveX controls
52 +// Currently we only can process ( in a limited way ) the ProgressBar
53 +// the other ID's are for reference ( & future )
55 +// RefEdit control {00024512-0000-0000-c000-000000000046}
56 +const sal_uInt8 aRefEditID[] =
58 +0x12, 0x45, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
61 +// Microsoft ProgressBar Control, version 6.0 {35053A22-8589-11D1-B16A-00C0F0283628}
62 +const sal_uInt8 aProgressID[] =
64 +0x22, 0x3a, 0x05, 0x35, 0x89, 0x85, 0xd1, 0x11, 0xb1, 0x6a, 0x00, 0xc0, 0xf0, 0x28, 0x36, 0x28,
67 +// Calendar Control 10.0
68 +const sal_uInt8 aCalendarID[] =
70 +0x2b, 0xc9, 0x27, 0x8e, 0x64, 0x12, 0x1c, 0x10, 0x8a, 0x2f, 0x04, 0x02, 0x24, 0x00, 0x9c, 0x02,
74 +// Microsoft ImageComboxBox Control, version 6.0 {DD9DA666-8594-11D1-B16A-00C0F0283628}
75 +const sal_uInt8 aImageComboID[] =
77 +0x66, 0xa6, 0x9d, 0xdd, 0x94, 0x85, 0xd1, 0x11, 0xb1, 0x6a, 0x00, 0xc0, 0xf0, 0x28, 0x36, 0x28,
80 +// Microsoft ImageList Control, version 6.0 {2C247F23-8591-11D1-B16A-00C0F0283628}
81 +const sal_uInt8 aImageListID[] =
83 +0x23, 0x7f, 0x24, 0x2c, 0x91, 0x85, 0xd1, 0x11, 0xb1, 0x6a, 0x00, 0xc0, 0xf0, 0x28, 0x36, 0x28,
86 +// Microsoft Slider Control, version 6.0 {F08DF954-8592-11D1-B16A-00C0F0283628}
87 +const sal_uInt8 aSliderID[] =
89 +0x54, 0xf9, 0x8d, 0xf0, 0x92, 0x85, 0xd1, 0x11, 0xb1, 0x6a, 0x00, 0xc0, 0xf0, 0x28, 0x36, 0x28,
92 +// Microsoft StatusBar Control, version 6.0 {8E3867A3-8586-11D1-B16A-00C0F0283628}
93 +const sal_uInt8 aStatusBarID[] =
95 +0xa3, 0x67, 0x38, 0x8e, 0x86, 0x85, 0xd1, 0x11, 0xb1, 0x6a, 0x00, 0xc0, 0xf0, 0x28, 0x36, 0x28,
98 +// Microsoft Office Chart 10.0
99 +const sal_uInt8 aChartSpaceID[] =
101 +0x46, 0xe5, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
104 +const sal_Int16 ActiveXIDLen = 0x10; // CLSID len
105 +const sal_Int16 ActiveXIDBlockLen = 0x30; // the block len that contains the CLSID
107 +bool lcl_handleActiveXControl( SvStorageStream *pS, sal_uInt16& nTypeID )
109 + nTypeID = 0; // Illegal ActiveX ID
111 + sal_uInt16 nIdentifier, nFixedAreaLen;
112 + *pS >> nIdentifier;
113 + *pS >> nFixedAreaLen;
114 + pS->SeekRel( ( nFixedAreaLen - ActiveXIDBlockLen ) );
115 + sal_uInt8 aID[ ActiveXIDLen ];
116 + if ( !pS->IsEof() )
118 + pS->Read( aID, ActiveXIDLen );
119 + pS->SeekRel( ActiveXIDBlockLen - ActiveXIDLen ); // read remainer of record
120 + if ( memcmp( aID, aProgressID, ActiveXIDLen ) == 0 )
122 + nTypeID = PROGRESSBAR;
123 + OSL_TRACE("Found supported ***PROGRESSBAR*** ActiveX control");
126 +#if (OSL_DEBUG_LEVEL > 0)
127 + // If we really want to process these more controls we should put them in
128 + // a list or array and have a single loop testing each id. For the moment
129 + // as we only can process PROGRESSBAR, not much point doing that until
130 + // we add support for at least another activex control
132 + else if ( memcmp( aID, aCalendarID, ActiveXIDLen ) == 0 )
133 + OSL_TRACE("Found unsupported ***CALENDAR*** ActiveX control");
134 + else if ( memcmp( aID, aRefEditID, ActiveXIDLen ) == 0 )
135 + OSL_TRACE("Found unsupported ***REFEDIT*** ActiveX control");
136 + else if ( memcmp( aID, aImageComboID, ActiveXIDLen ) == 0 )
137 + OSL_TRACE("Found unsupported ***IMAGECOMBO*** ActiveX control");
138 + else if ( memcmp( aID, aImageListID, ActiveXIDLen ) == 0 )
139 + OSL_TRACE("Found unsupported ***IMAGELIST*** ActiveX control");
140 + else if ( memcmp( aID, aChartSpaceID, ActiveXIDLen ) == 0 )
141 + OSL_TRACE("Found unsupported ***CHARTSPACE*** ActiveX control");
142 + else if ( memcmp( aID, aSliderID, ActiveXIDLen ) == 0 )
143 + OSL_TRACE("Found unsupported ***SLIDER*** ActiveX control");
144 + else if ( memcmp( aID, aStatusBarID, ActiveXIDLen ) == 0 )
145 + OSL_TRACE("Found unsupported ***STATUSBAR*** ActiveX control");
149 + OSL_TRACE("Unknown activeX ID !");
155 typedef std::vector< ContainerRecord > ContainerRecordList;
157 class ContainerRecReader
158 @@ -750,6 +887,13 @@ class ContainerRecReader
159 pControl->pDocSh = pContainerControl->pDocSh;
160 pContainerControl->ProcessControl( pControl, pS, rec );
162 + else if ( rec.nTypeIdent & 0x8000 )
164 + // Skip ActiveX Controls we can't import
165 + SotStorageStreamRef oStream = pContainerControl->getContainedControlsStream();
166 + ULONG nStrmPos = oStream->Tell();
167 + oStream->Seek( nStrmPos + rec.nSubStreamLen );
171 DBG_ERROR("Terminating import, unexpected error");
172 @@ -3412,9 +3561,18 @@ OUString OCX_ContainerControl::createSub
173 return buf.makeStringAndClear();
176 -bool OCX_ContainerControl::createFromContainerRecord( const ContainerRecord& record, OCX_Control*& pControl )
178 +bool OCX_ContainerControl::createFromContainerRecord( ContainerRecord& record, OCX_Control*& pControl )
181 + if ( record.nTypeIdent & 0x8000 )
183 + std::hash_map<sal_uInt16, sal_uInt16>::iterator it = mActiveXIDMap.find( record.nTypeIdent );
184 + if ( it == mActiveXIDMap.end() )
186 + // replace the generated id with our hardcoded one
187 + record.nTypeIdent = it->second;
189 switch ( record.nTypeIdent)
192 @@ -4153,10 +4311,14 @@ sal_Bool OCX_UserForm::Read(SvStorageStr
193 // ( unknown what these trailing records are for)
194 if ( numTrailingRecs )
196 - for ( ; numTrailingRecs ; --numTrailingRecs )
197 + for ( sal_Int16 i = 0 ; numTrailingRecs ; --numTrailingRecs, ++i )
199 - OCX_Control skip(C2S("dummy")) ;
201 + sal_uInt16 nTypeID = 0;
202 + if ( lcl_handleActiveXControl( pS, nTypeID ) )
204 + if ( nTypeID & 0x8000 ) // valid ActiveXID
205 + mActiveXIDMap[ ( i | 0x8000 ) ] = nTypeID;
209 return OCX_ContainerControl::Read( pS );