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_extensions.hxx"
26
27 #pragma warning(disable: 4917)
28 #include <windows.h>
29 #include <comdef.h>
30 #include <tchar.h>
31 #include <atlbase.h>
32 #include<atlcom.h>
33 #include <stdio.h>
34 #include <com/sun/star/bridge/ModelDependent.hpp>
35 #include <com/sun/star/bridge/XBridgeSupplier2.hpp>
36 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
37 #include <com/sun/star/script/XInvocation.hpp>
38 #include <oletest/XCallback.hpp>
39 #include <rtl/process.h>
40 #include <com/sun/star/uno/Reference.h>
41 #include <cppuhelper/servicefactory.hxx>
42 #include <rtl/string.h>
43
44
45
46 using namespace com::sun::star::lang;
47 using namespace com::sun::star::uno;
48 using namespace com::sun::star::script;
49 using namespace com::sun::star::bridge;
50 using namespace com::sun::star::bridge::ModelDependent;
51 using namespace cppu;
52 using namespace rtl;
53 HRESULT doTest();
54 bool incrementMultidimensionalIndex(
55 sal_Int32 dimensions,
56 const sal_Int32 * parDimensionLengths,
57 sal_Int32 * parMultidimensionalIndex);
58
_tmain(int,_TCHAR *)59 int __cdecl _tmain( int /*argc*/, _TCHAR * /*argv[]*/ )
60 {
61 HRESULT hr;
62 if( FAILED( hr=CoInitialize(NULL)))
63 {
64 _tprintf(_T("CoInitialize failed \n"));
65 return -1;
66 }
67
68
69 if( FAILED(hr=doTest()))
70 {
71 _com_error err( hr);
72 const TCHAR * errMsg= err.ErrorMessage();
73 MessageBox( NULL, errMsg, "Test failed", MB_ICONERROR);
74 }
75
76 CoUninitialize();
77 return 0;
78 }
79
80
81
82
doTest()83 HRESULT doTest()
84 {
85 HRESULT hr= S_OK;
86 long j = 0;
87 SAFEARRAY* par;
88 CComDispatchDriver disp;
89 CComVariant result;
90 CComVariant param1;
91 CComPtr<IUnknown> spUnkFactory;
92 if( SUCCEEDED( spUnkFactory.CoCreateInstance(L"com.sun.star.ServiceManager")))
93 {
94 disp= spUnkFactory;
95 param1= L"oletest.OleTest";
96 disp.Invoke1( L"createInstance", ¶m1, &result);
97
98 disp= result.pdispVal;
99
100 // disp contains now oletest.OleTest
101
102 // one dimensional array
103 par= SafeArrayCreateVector( VT_UI1, 0, 5);
104 unsigned char arbyte[]= { 1,2,3,4,5};
105 for(long i= 0; i < 5;i++)
106 hr= SafeArrayPutElement( par, &i, &arbyte[i]);
107
108 result.Clear();
109 param1.vt= VT_ARRAY| VT_UI1;
110 param1.byref= par;
111 disp.Invoke1(L"methodByte", ¶m1, &result);
112 SafeArrayDestroy( par);
113
114
115 // two dimensional array
116 SAFEARRAYBOUND bounds[2];
117 // least significant dimension first, Dimension 1
118 bounds[0].cElements= 3;
119 bounds[0].lLbound= 0;
120 // Dimension 2
121 bounds[1].cElements= 2;
122 bounds[1].lLbound= 0;
123 par= SafeArrayCreate( VT_I4, 2, bounds );
124
125 long uBound1;
126 long uBound2;
127 hr= SafeArrayGetUBound( par, 1, &uBound1);
128 hr= SafeArrayGetUBound( par, 2, &uBound2);
129
130 long index2[2];
131 memset( index2, 0, 2 * sizeof( long) );
132 long dimLengths[]={3,2};
133
134 long data;
135 do
136 {
137 data= index2[1] * 3 + index2[0] +1;
138 hr= SafeArrayPutElement( par, index2, &data);
139 }while( incrementMultidimensionalIndex( 2, dimLengths, index2) );
140
141 long* pdata;
142 long (*dataL)[2][3];
143 hr= SafeArrayAccessData( par, (void**)&pdata);
144 dataL= (long(*)[2][3])pdata;
145
146 for (long i= 0; i < 2; i ++)
147 {
148 for(long j= 0; j < 3; j++)
149 data= (*dataL)[i][j];
150 }
151 hr= SafeArrayUnaccessData(par);
152
153 result.Clear();
154 param1.vt= VT_ARRAY | VT_I4;
155 param1.byref= par;
156 disp.Invoke1(L"methodSequence", ¶m1, &result);
157
158 SAFEARRAY* arRet= result.parray;
159
160 for(long i= 0; i < 2 ; i++)
161 {
162 CComVariant varx;
163 varx.Clear();
164 hr= SafeArrayGetElement( arRet, &i, &varx);
165 SAFEARRAY* ari= varx.parray;
166
167 for( j= 0; j < 3; j++)
168 {
169 CComVariant varj;
170 varj.Clear();
171 hr= SafeArrayGetElement( ari, &j, &varj);
172 }
173
174
175
176 }
177 SafeArrayDestroy( par);
178 }
179
180 return hr;
181 }
182
183 // left index is least significant
incrementMultidimensionalIndex(sal_Int32 dimensions,const sal_Int32 * parDimensionLengths,sal_Int32 * parMultidimensionalIndex)184 bool incrementMultidimensionalIndex(
185 sal_Int32 dimensions,
186 const sal_Int32 * parDimensionLengths,
187 sal_Int32 * parMultidimensionalIndex)
188 {
189 if( dimensions < 1)
190 return sal_False;
191
192 bool ret= sal_True;
193 bool carry= sal_True; // to get into the while loop
194
195 sal_Int32 currentDimension= 0; //most significant is 1
196 while( carry)
197 {
198 parMultidimensionalIndex[ currentDimension ]++;
199 // if carryover, set index to 0 and handle carry on a level above
200 if( parMultidimensionalIndex[ currentDimension] > (parDimensionLengths[ currentDimension] - 1))
201 parMultidimensionalIndex[ currentDimension]= 0;
202 else
203 carry= sal_False;
204
205 currentDimension ++;
206 // if dimensions drops below 1 and carry is set than then all indices are 0 again
207 // this is signalled by returning sal_False
208 if( currentDimension > dimensions - 1 && carry)
209 {
210 carry= sal_False;
211 ret= sal_False;
212 }
213 }
214 return ret;
215 }
216