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 extern CComModule _Module;
33 #include<atlcom.h>
34 
35 #include <stdio.h>
36 #include <com/sun/star/bridge/ModelDependent.hpp>
37 #include <com/sun/star/bridge/XBridgeSupplier2.hpp>
38 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
39 #include <com/sun/star/uno/XComponentContext.hpp>
40 #include <com/sun/star/lang/XMultiComponentFactory.hpp>
41 
42 #include <oletest/XTestSequence.hpp>
43 #include <rtl/process.h>
44 #include <com/sun/star/uno/Reference.h>
45 #include <cppuhelper/servicefactory.hxx>
46 #include <cppuhelper/bootstrap.hxx>
47 #include <rtl/string.h>
48 
49 
50 CComModule _Module;
51 BEGIN_OBJECT_MAP(ObjectMap)
52 END_OBJECT_MAP()
53 
54 #include "smartarray.h"
55 using namespace com::sun::star::bridge;
56 using namespace com::sun::star::bridge::ModelDependent;
57 using namespace com::sun::star::lang;
58 using namespace com::sun::star::uno;
59 using namespace oletest;
60 using namespace cppu;
61 using namespace rtl;
62 HRESULT doTest();
63 HRESULT InitializeParameter();
64 void printResultVariantArray( VARIANT & var);
65 void printVariant( VARIANT & var);
66 
67 
68 
69 
_tmain(int argc,_TCHAR * argv[])70 int __cdecl _tmain( int argc, _TCHAR * argv[] )
71 {
72 	HRESULT hr;
73 	if( FAILED( hr=CoInitialize(NULL)))
74 	{
75 		_tprintf(_T("CoInitialize failed \n"));
76 		return -1;
77 	}
78 
79 
80 	_Module.Init( ObjectMap, GetModuleHandle( NULL));
81 
82 	if( FAILED(hr=doTest()))
83 	{
84 		_com_error err( hr);
85 		const TCHAR * errMsg= err.ErrorMessage();
86 		MessageBox( NULL, errMsg, "Test failed", MB_ICONERROR);
87 	}
88 
89 
90 	_Module.Term();
91 	CoUninitialize();
92 	return 0;
93 }
94 char _c[]={ 1,2,3,4,5};
95 short _short[]={0xffff, 1, 11 ,111, 1111 };
96 unsigned short _ushort[]={0xffff, 1, 11 ,111, 1111 };
97 long _long[]= { 0xffffffff, 11, 111 ,1111, 1111 };
98 unsigned long _ulong[]= { 0xffffffff, 11, 111 ,1111, 1111 };
99 float _float[]= { 12345.f, 1234.5f, 123.45f, 12.345f, 1.2345f};
100 double _double[]= {12345, 1234.5, 123.45, 12.345, 1.2345};
101 
102 CComVariant _variant[]= {L"variant 1", L"variant2", L"variant3"};
103 wchar_t _wchar[]= {L'1', L'2', L'3', L'A', L' '};
104 BSTR _bstr[]={L"Ich", L"bin", L"ein", L"Hamburger", L"Jung"};
105 SmartArray<char>			arByte( _c, 5, VT_I1);
106 SmartArray< short>			arShort( _short, 5, VT_I2);
107 //SmartArray< unsigned short> arUShort( _ushort, 5, VT_UI2);
108 SmartArray< long>			arLong( _long, 5, VT_I4);
109 //SmartArray< unsigned long>	arULong( _ulong, 5, VT_UI4);
110 //SmartArray< float>			arFloat( _float, 5, VT_R4 );
111 SmartArray< double>			arDouble( _double, 5, VT_R8 );
112 //SmartArray< unsigned short> arWChar( _wchar, 5, VT_UI2 );
113 SmartArray< wchar_t* >		arString( _bstr, 5, VT_BSTR);
114 SmartArray< VARIANT >		 arVariant( _variant, 3, VT_VARIANT);
115 
116 
doTest()117 HRESULT doTest()
118 {
119 	HRESULT hr;
120 	USES_CONVERSION;
121 	CComPtr<IUnknown> spUnkMgr;
122 
123     putenv("UNO_TYPES=types.rdb");
124     putenv("UNO_SERVICES=services.rdb");
125     Reference<XComponentContext> xContext = defaultBootstrap_InitialComponentContext();
126 
127 	Reference< XMultiComponentFactory > mgr = xContext->getServiceManager();//createRegistryServiceFactory( OUString(L"services.rdb"));
128 	Reference< XInterface > xIntSupplier= mgr->createInstanceWithContext(
129         OUString(L"com.sun.star.bridge.OleBridgeSupplierVar1"), xContext);
130 	Reference< XBridgeSupplier2 > xSuppl( xIntSupplier, UNO_QUERY);
131 	Reference <XInterface> xOletest= mgr->createInstanceWithContext(
132         OUString(L"oletest.OleTest"), xContext);
133 	Any any;
134 	any <<= xOletest;
135 	sal_uInt8 arId[16];
136 	rtl_getGlobalProcessId( arId);
137 	Any target=	xSuppl->createBridge( any, Sequence<sal_Int8>( (sal_Int8*)arId, 16), UNO, OLE);
138 	CComDispatchDriver oletest;
139 	if (target.getValueTypeClass() == getCppuType((sal_uInt32*) 0).getTypeClass())
140 	{
141 		VARIANT* pVariant = *(VARIANT**)target.getValue();
142 
143 		oletest= pVariant->pdispVal;
144 
145 		VariantClear(pVariant);
146 		CoTaskMemFree(pVariant);
147 	}
148 
149 	CComVariant varRet;
150 	CComVariant varParam1;
151 	CComVariant varParam2;
152 	CComVariant varParam3;
153 	CComVariant varParam4;
154 
155 	long value= 100;
156 	varParam1.vt= VT_I1 | VT_BYREF;
157 	varParam1.plVal= &value;
158 
159 	// Testing the caching of DISPIDs and the process of acquiring member information
160 	// on demand in IDispatch::Invoke
161 	// Step through the corresponding IDispatch implementation of the ole bridge
162 	hr=	oletest.Invoke1(static_cast<LPCOLESTR>(L"testinout_methodByte"), &varParam1, &varRet);
163 	hr=	oletest.Invoke1(static_cast<LPCOLESTR>(L"testinout_methodByte"), &varParam1, &varRet);
164 	// Name ok but different case
165 	hr=	oletest.Invoke1(static_cast<LPCOLESTR>(L"Testinout_methodByte"), &varParam1, &varRet);
166 	hr=	oletest.Invoke1(static_cast<LPCOLESTR>(L"Testinout_methodByte"), &varParam1, &varRet);
167 	// not existing member
168 	hr=	oletest.Invoke1(static_cast<LPCOLESTR>(L"Testinout"), &varParam1, &varRet);
169 	hr=	oletest.Invoke1(static_cast<LPCOLESTR>(L"Testinout"), &varParam1, &varRet);
170 
171 	// Property
172 	varParam1.vt= VT_ARRAY | VT_I1;
173 	varParam1.parray= (SAFEARRAY*)arByte;
174 	hr= oletest.PutPropertyByName( static_cast<LPCOLESTR>(L"AttrByte"), &varParam1);
175 	hr= oletest.PutPropertyByName( static_cast<LPCOLESTR>(L"AttrByte"), &varParam1);
176 	// Name ok but different case
177 	hr= oletest.PutPropertyByName( static_cast<LPCOLESTR>(L"attrByte"), &varParam1);
178 	hr= oletest.PutPropertyByName( static_cast<LPCOLESTR>(L"attrByte"), &varParam1);
179 	// not existing member
180 	hr= oletest.PutPropertyByName( static_cast<LPCOLESTR>(L"attr"), &varParam1);
181 	hr= oletest.PutPropertyByName( static_cast<LPCOLESTR>(L"attr"), &varParam1);
182 
183 	// PropertyGet
184 	hr= oletest.GetPropertyByName( static_cast<LPCOLESTR>(L"AttrByte"), &varRet);
185 
186 	hr= oletest.GetPropertyByName( static_cast<LPCOLESTR>(L"attrByte"), &varRet);
187 	hr= oletest.GetPropertyByName( static_cast<LPCOLESTR>(L"attrByte"), &varRet);
188 	//not existing member
189 	hr= oletest.GetPropertyByName( static_cast<LPCOLESTR>(L"attrBy"), &varRet);
190 	hr= oletest.GetPropertyByName( static_cast<LPCOLESTR>(L"attrBy"), &varRet);
191 
192 	DISPID dispid;
193 	LPOLESTR method= L"methodByte";
194 	hr = oletest.p->GetIDsOfNames(IID_NULL, &method, 1, LOCALE_USER_DEFAULT, &dispid);
195 
196 
197 	CComVariant arg[1];
198 	arg[0].vt= VT_ARRAY | VT_I1;
199 	arg[0].parray= (SAFEARRAY*)arByte;
200 	DISPPARAMS params={ arg,0,1,0};
201 
202 	hr = oletest.p->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT,
203 		DISPATCH_METHOD | DISPATCH_PROPERTYPUT, &params, &varRet, NULL, NULL);
204 
205 	hr = oletest.p->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT,
206 		DISPATCH_METHOD | DISPATCH_PROPERTYPUT, &params, &varRet, NULL, NULL);
207 
208 	// different case
209 	LPOLESTR method2= L"MEthodByte";
210 	hr = oletest.p->GetIDsOfNames(IID_NULL, &method2, 1, LOCALE_USER_DEFAULT, &dispid);
211 
212 	hr = oletest.p->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT,
213 		DISPATCH_METHOD | DISPATCH_PROPERTYPUT, &params, &varRet, NULL, NULL);
214 
215 	hr = oletest.p->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT,
216 		DISPATCH_METHOD | DISPATCH_PROPERTYPUT, &params, &varRet, NULL, NULL);
217 
218 	LPOLESTR attrib= L"AttrByte";
219 	hr = oletest.p->GetIDsOfNames(IID_NULL, &attrib, 1, LOCALE_USER_DEFAULT, &dispid);
220 
221 	hr = oletest.p->Invoke( dispid, IID_NULL, LOCALE_USER_DEFAULT,
222 		DISPATCH_METHOD | DISPATCH_PROPERTYPUTREF, &params, &varRet, NULL, NULL);
223 
224 	hr = oletest.p->Invoke( dispid, IID_NULL, LOCALE_USER_DEFAULT,
225 		DISPATCH_METHOD | DISPATCH_PROPERTYGET, &params, &varRet, NULL, NULL);
226 
227 
228 
229 	CComVariant varByteArray;
230 	varByteArray.vt= VT_ARRAY | VT_I1;
231 	varByteArray.parray= (SAFEARRAY*)arByte;
232 	CComVariant varShortArray;
233 	varShortArray.vt= VT_ARRAY | VT_I2;
234 	varShortArray.parray= (SAFEARRAY*)arShort;
235 	CComVariant varLongArray;
236 	varLongArray.vt= VT_ARRAY | VT_I4;
237 	varLongArray.parray= (SAFEARRAY*)arLong;
238 	CComVariant varDoubleArray;
239 	varDoubleArray.vt= VT_ARRAY | VT_R8;
240 	varDoubleArray.parray= (SAFEARRAY*)arDouble;
241 	CComVariant varStringArray;
242 	varStringArray.vt= VT_ARRAY | VT_BSTR;
243 	varStringArray.parray= (SAFEARRAY*)arString;
244 	CComVariant varArray;
245 	varArray.vt= VT_ARRAY | VT_VARIANT;
246 	varArray.parray= (SAFEARRAY*)arVariant;
247 
248 	FONTDESC fd={ sizeof( fd), L"ARIAL", 10, FW_NORMAL, 0, 0, 0, 0};
249 
250 
251 	CComPtr< IUnknown > unk1;
252 	CComPtr< IUnknown > unk2;
253 	CComPtr< IUnknown > unk3;
254 
255 	IUnknown* _unknown[3];
256 	hr= OleCreateFontIndirect( &fd, __uuidof( IUnknown), (void**)&unk1.p);
257 	hr= OleCreateFontIndirect( &fd, __uuidof( IUnknown), (void**)&unk2.p);
258 	hr= OleCreateFontIndirect( &fd, __uuidof( IUnknown), (void**)&unk3.p);
259 	_unknown[0]= unk1;
260 	_unknown[1]= unk2;
261 	_unknown[2]= unk3;
262 	SmartArray<IUnknown*> arUnknown( _unknown, 3, VT_UNKNOWN);
263 
264 	CComVariant varUnkArray;
265 	varUnkArray.vt= VT_ARRAY | VT_UNKNOWN;
266 	varUnkArray.parray= (SAFEARRAY*)arUnknown;
267 
268 	// preparing out parameter;
269 	char byteOut;
270 	CComVariant varOutByte;		//###
271 	varOutByte.vt= VT_BYREF | VT_UI1;
272 	V_I1REF(&varOutByte)= &byteOut;
273 	short shortOut;
274 	CComVariant varOutShort;	//###
275 	varOutShort.vt= VT_BYREF | VT_I2;
276 	V_I2REF( &varOutShort)= &shortOut;
277 	long longOut;
278 	CComVariant varOutLong;		//###
279 	varOutLong.vt= VT_BYREF | VT_I4;
280 	V_I4REF( &varOutLong)= &longOut;
281 	double doubleOut;
282 	CComVariant varOutDouble;	//###
283 	varOutDouble.vt= VT_BYREF | VT_R8;
284 	V_R8REF( &varOutDouble)= &doubleOut;
285 	BSTR bstrOut= NULL;
286 	CComVariant varOutString;	//###
287 	varOutString.vt= VT_BYREF | VT_BSTR;
288 	V_BSTRREF(&varOutString)= &bstrOut;
289 	CComVariant variantOut;
290 	CComVariant varOutAny;		//###
291 	varOutAny.vt= VT_BYREF | VT_VARIANT;
292 	V_VARIANTREF(&varOutAny)= &variantOut;
293 
294 	CComPtr<IDispatch> dispOut;
295 	CComVariant varOutXInterface; //###
296 	varOutXInterface.vt= VT_BYREF |VT_DISPATCH;
297 	V_DISPATCHREF(&varOutXInterface)= &dispOut.p;
298 
299 	// In Parameter ( all of type Sequence ###########################################################
300 	OutputDebugString( _T("In parameter of type Sequence ###########################################\n"
301 		"The functions return the Sequence parameter \n\n"));
302 
303 	OutputDebugStringA("methodByte | Params: \n");
304 	printVariant( varByteArray);
305 	hr=	oletest.Invoke1(static_cast<LPCOLESTR>(L"methodByte"), &varByteArray, &varRet);
306 	OutputDebugStringA("methodByte  | return value \n");
307 	printVariant( varRet);
308 
309 	OutputDebugStringA("methodShort | Params: \n");
310 	printVariant( varShortArray);
311 	hr=	oletest.Invoke1(static_cast<LPCOLESTR>(L"methodShort"), &varShortArray, &varRet);
312 	OutputDebugStringA("methodShort  | return value \n");
313 	printVariant( varRet);
314 
315 	OutputDebugStringA("methodLong | Params: \n");
316 	printVariant( varLongArray);
317 	hr=	oletest.Invoke1(static_cast<LPCOLESTR>(L"methodLong"), &varLongArray, &varRet);
318 	OutputDebugStringA("methodLong  | return value \n");
319 	printVariant( varRet);
320 
321 	OutputDebugStringA("methodDouble | Params: \n");
322 	printVariant( varDoubleArray);
323 	hr=	oletest.Invoke1(static_cast<LPCOLESTR>(L"methodDouble"), &varDoubleArray, &varRet);
324 	OutputDebugStringA("methodDouble  | return value \n");
325 	printVariant( varRet);
326 
327 	OutputDebugStringA("methodString | Params: \n");
328 	printVariant( varStringArray);
329 	hr=	oletest.Invoke1(static_cast<LPCOLESTR>(L"methodString"), &varStringArray, &varRet);
330 	OutputDebugStringA("methodString  | return value \n");
331 	printVariant( varRet);
332 
333 	OutputDebugStringA("methodAny | Params: \n");
334 	printVariant( varArray);
335 	hr=	oletest.Invoke1(static_cast<LPCOLESTR>(L"methodAny"), &varArray, &varRet);
336 	OutputDebugStringA("methodAny  | return value \n");
337 	printVariant( varRet);
338 
339 	OutputDebugStringA("methodXInterface | Params: \n");
340 	printVariant( varUnkArray);
341 	hr=	oletest.Invoke1(static_cast<LPCOLESTR>(L"methodXInterface"), &varUnkArray, &varRet);
342 	OutputDebugStringA("methodAny  | return value \n");
343 	printVariant( varRet);
344 
345 	// Out Parameter ###########################################################################
346 	OutputDebugString( _T("Out parameter ###########################################\n\n"));
347 
348 	OutputDebugString(_T("testout_methodByte  \n"));
349 	hr=	oletest.InvokeN(static_cast<LPCOLESTR>(L"testout_methodByte"), &varOutByte, 1, &varRet);
350 	OutputDebugString(_T("testout_methodByte  | out value: \n"));
351 	printVariant( varOutByte);
352 
353 	OutputDebugString(_T("testout_methodShort \n"));
354 	hr=	oletest.Invoke1(static_cast<LPCOLESTR>(L"testout_methodShort"), &varOutShort, &varRet);
355 	OutputDebugString(_T("testout_methodShort  | out value: \n"));
356 	printVariant( varOutShort);
357 
358 	OutputDebugString(_T("testout_methodLong \n"));
359 	hr=	oletest.Invoke1(static_cast<LPCOLESTR>(L"testout_methodLong"), &varOutLong, &varRet);
360 	OutputDebugString(_T("testout_methodLong  | out value: \n"));
361 	printVariant( varOutLong);
362 
363 	OutputDebugString(_T("testout_methodDouble \n"));
364 	hr=	oletest.Invoke1(static_cast<LPCOLESTR>(L"testout_methodDouble"), &varOutDouble, &varRet);
365 	OutputDebugString(_T("testout_methodDouble  | out value: \n"));
366 	printVariant( varOutDouble);
367 
368 	OutputDebugString(_T("testout_methodString \n"));
369 	hr=	oletest.Invoke1(static_cast<LPCOLESTR>(L"testout_methodString"), &varOutString, &varRet);
370 	OutputDebugString(_T("testout_methodString  | out value: \n"));
371 	printVariant( varOutString);
372 
373 	OutputDebugString(_T("testout_methodAny \n"));
374 	hr=	oletest.Invoke1(static_cast<LPCOLESTR>(L"testout_methodAny"), &varOutAny, &varRet);
375 	OutputDebugString(_T("methodAny  | out value: \n"));
376 	printVariant( varOutAny);
377 
378 	OutputDebugString(_T("testout_methodXInterface \n"));
379 	hr=	oletest.Invoke1(static_cast<LPCOLESTR>(L"testout_methodXInterface"), &varOutXInterface, &varRet);
380 	OutputDebugString(_T("methodAny  | out value: \n"));
381 	printVariant( varOutXInterface);
382 	CComDispatchDriver outDisp( *varOutXInterface.ppdispVal);
383 	CComVariant varAttr3;
384 	outDisp.GetPropertyByName(L"AttrAny2", &varAttr3);
385 	ATLTRACE("property OleTest.AttrAny2: %s", W2T(varAttr3.bstrVal));
386 
387 	OutputDebugString(_T("testout_methodMulParams1 ( 2 out Parameter) \n"));
388 	long longOut2=0;
389 	CComVariant _params[2];
390 	longOut=0;
391 	_params[0]= varOutLong;
392 	_params[1].vt= VT_BYREF | VT_I4;
393 	V_I4REF(& _params[1])= &longOut2;
394 	hr=	oletest.InvokeN( static_cast<LPCOLESTR>(L"testout_methodMulParams1"), (VARIANT*)&_params, 2);
395 	OutputDebugString(_T("testout_methodMulParams1  | out values: \n"));
396 	printVariant( _params[1]);
397 	printVariant( _params[0]);
398 
399 	OutputDebugString(_T("testout_methodMulParams2 ( 3 out Parameter) \n"));
400 	CComVariant _params2[3];
401 	_params2[2]= varOutLong;
402 	_params2[1].vt= VT_BYREF | VT_I4;
403 	V_I4REF(& _params2[1])= &longOut2;
404 	_params2[0]= varOutString;
405 	hr=	oletest.InvokeN( static_cast<LPCOLESTR>( L"testout_methodMulParams2"), (VARIANT*)&_params2, 3);
406 	OutputDebugString(_T("testout_methodMulParams2  | out values: \n"));
407 	printVariant( _params2[2]);
408 	printVariant( _params2[1]);
409 	printVariant( _params2[0]);
410 
411 	OutputDebugString(_T("testout_methodMulParams3 ( 1 in and 1 out Parameter) \n"));
412 	CComVariant _params3[2];
413 	_params3[1]= CComBSTR(L" In string");
414 	_params3[0]= varOutString;
415 	hr=	oletest.InvokeN( static_cast<LPCOLESTR>( L"testout_methodMulParams3"), (VARIANT*)&_params3, 2);
416 	OutputDebugString(_T("testout_methodMulParams3  | out values: \n"));
417 	printVariant( _params3[1]);
418 	printVariant( _params3[0]);
419 
420 	//In Out Parameter ###########################################################################
421 	OutputDebugString( _T("In Out parameter ###########################################\n\n"));
422 
423 	*V_I1REF(&varOutByte)= 5;
424 	ATLTRACE(_T("testinout_methodByte | in value: %d \n"), *V_I1REF(&varOutByte));
425 	hr=	oletest.InvokeN(static_cast<LPCOLESTR>(L"testinout_methodByte"), &varOutByte, 1, &varRet);
426 	OutputDebugString(_T("testinout_methodByte  | out value: \n"));
427 	printVariant( varOutByte);
428 
429 	OutputDebugString(_T("testinout_methodShort | in value= 1000 \n"));
430 	*V_UI2REF(&varOutShort)= 1000;
431 	hr=	oletest.Invoke1(static_cast<LPCOLESTR>(L"testinout_methodShort"), &varOutShort, &varRet);
432 	OutputDebugString(_T("testinout_methodShort  | out value: \n"));
433 	printVariant( varOutShort);
434 
435 	OutputDebugString(_T("testinout_methodLong | in value= 10000 \n"));
436 	*V_UI4REF(&varOutLong)= 10000;
437 	hr=	oletest.Invoke1(static_cast<LPCOLESTR>(L"testinout_methodLong"), &varOutLong, &varRet);
438 	OutputDebugString(_T("testinout_methodLong  | out value: \n"));
439 	printVariant( varOutLong);
440 
441 	*V_R8REF(&varOutDouble)= 3.14;
442 	ATLTRACE(_T("testinou_methodDouble in value: %f \n"),*V_R8REF(&varOutDouble));
443 	hr=	oletest.Invoke1(static_cast<LPCOLESTR>(L"testinout_methodDouble"), &varOutDouble, &varRet);
444 	OutputDebugString(_T("testinout_methodDouble  | out value: \n"));
445 	printVariant( varOutDouble);
446 
447 	SysFreeString( *V_BSTRREF(&varOutString));
448 	*V_BSTRREF(&varOutString)= SysAllocString( L"this is a in string");
449 	ATLTRACE(_T("testinout_methodString | value: %s \n"), W2T(*V_BSTRREF(&varOutString)));
450 	hr=	oletest.Invoke1(static_cast<LPCOLESTR>(L"testinout_methodString"), &varOutString, &varRet);
451 	OutputDebugString(_T("testinout_methodString  | out value: \n"));
452 	printVariant( varOutString);
453 
454 	CComVariant var1(CComBSTR(L" this is a string in a VARIANT"));
455 	CComVariant outVar1;
456 	outVar1.vt= VT_BYREF | VT_VARIANT;
457 	outVar1.pvarVal= &var1;
458 	ATLTRACE(_T("testinout_methodAny | parameter: %s\n"), W2T(var1.bstrVal));
459 	hr=	oletest.Invoke1(static_cast<LPCOLESTR>(L"testinout_methodAny"), &varOutAny, &varRet);
460 	OutputDebugString(_T("testinout_methodAny  | out value: \n"));
461 	printVariant( varOutAny);
462 
463 	CComPtr< IUnknown > objectIn = unk1;
464 	CComVariant varOutIFace;
465 	varOutIFace.vt= VT_BYREF | VT_UNKNOWN;
466 	varOutIFace.ppunkVal= &objectIn.p;
467 	(*varOutIFace.ppunkVal)->AddRef();
468 	OutputDebugString(_T("testinout_methodXInterface | in value: \n"));
469 	printVariant(varOutIFace);
470 	hr=	oletest.Invoke1(static_cast<LPCOLESTR>(L"testinout_methodXInterface"), &varOutIFace, &varRet);
471 	OutputDebugString(_T("testinout_methodXInterface  | out value: \n"));
472 	printVariant( varOutIFace);
473 
474 	// Properties ######################################################################
475 	OutputDebugString( _T(" Properties ###########################################\n\n"));
476 
477 	OutputDebugString(_T("set property \"AttrByte\" | value"));
478 	//CComVariant propArByte;
479 	//propArByte.vt= VT_ARRAY | VT_I1;
480   	varParam1.parray= (SAFEARRAY*)arByte;
481 	printVariant( varParam1);
482 	hr= oletest.PutPropertyByName( static_cast<LPCOLESTR>(L"AttrByte"), &varParam1);
483 	OutputDebugString(_T("get property \"AttrByte\" | value:"));
484 	varRet.Clear();
485 	hr= oletest.GetPropertyByName( static_cast<LPCOLESTR>(L"AttrByte"), &varRet);
486 	printVariant( varRet);
487 
488 
489 	return S_OK;
490 
491 
492 }
493 
494 
printVariant(VARIANT & _var)495 void printVariant( VARIANT & _var)
496 {
497 	HRESULT hr;
498 	USES_CONVERSION;
499 	CComVariant var;
500 	hr=	VariantCopyInd( &var, &_var);
501 	if( var.vt & VT_ARRAY)
502 	{
503 		VARTYPE type= var.vt ^ VT_ARRAY;
504 		SAFEARRAY * sarray= var.parray;
505 		long lbound;
506 		long ubound;
507 		hr= SafeArrayGetLBound( sarray, 1, &lbound);
508 		hr= SafeArrayGetUBound( sarray, 1, &ubound);
509 		long count= ubound - lbound + 1;
510 		char charValue;
511 		BYTE byteValue;
512 		short shortValue;
513 		long longValue;
514 		double doubleValue;
515 		IUnknown* unkValue;
516 		BSTR bstrValue;
517 		OutputDebugString( _T("# Array \n"));
518 		for( long i= 0; i < count; i++)
519 		{
520 //			CComVariant variantValue;
521 			TCHAR *buf[256];
522 			wsprintf( (TCHAR*)buf, _T("%d : "), i);
523 			OutputDebugString( (TCHAR*)buf);
524 			VARIANT varTemp;
525 			VariantInit( &varTemp);
526 			VARIANT variantValue;
527 			VariantInit( &variantValue);
528 			switch( type)
529 			{
530 			case VT_UI1:
531 				hr= SafeArrayGetElement( sarray, &i, &byteValue);
532 				varTemp.vt= VT_UI1;
533 				V_UI1( &varTemp)= byteValue;
534 				printVariant( varTemp);
535 				break;
536 			case VT_I1:
537 				hr= SafeArrayGetElement( sarray, &i, &charValue);
538 				varTemp.vt= VT_I1;
539 				V_I1( &varTemp)= charValue;
540 				printVariant( varTemp);
541 				break;
542 			case VT_I2:
543 				hr= SafeArrayGetElement( sarray, &i, &shortValue);
544 				varTemp.vt= VT_I2;
545 				V_I2( &varTemp)= shortValue;
546 				printVariant( varTemp);
547 				break;
548 
549 			case VT_UI2:
550 			case VT_I4:
551 				hr= SafeArrayGetElement( sarray, &i, &longValue);
552 				varTemp.vt= VT_I4;
553 				V_I4( &varTemp)= longValue;
554 				printVariant( varTemp);
555 				break;
556 			case VT_R8:
557 				hr= SafeArrayGetElement( sarray, &i, &doubleValue);
558 				varTemp.vt= VT_R8;
559 				V_R8( &varTemp)= doubleValue;
560 				printVariant( varTemp);
561 				break;
562 			case VT_BSTR:
563 				hr= SafeArrayGetElement( sarray, &i, &bstrValue);
564 				varTemp.vt= VT_BSTR;
565 				varTemp.bstrVal= bstrValue;
566 				printVariant( varTemp);
567 				break;
568 			case VT_VARIANT:
569 				hr= SafeArrayGetElement( sarray, &i, &varTemp);
570 				printVariant( varTemp);
571 				break;
572 
573 			case VT_UNKNOWN:
574 				hr= SafeArrayGetElement( sarray, &i, &unkValue);
575 				varTemp.vt= VT_UNKNOWN;
576 				varTemp.punkVal= unkValue;
577 				printVariant( varTemp);
578 				break;
579 			}
580 
581 			VariantClear( &varTemp);
582 			VariantClear( &variantValue);
583 		}
584 
585 	}
586 	else
587 	{
588 		TCHAR buf[256];
589 		switch (var.vt)
590 		{
591 		case VT_I1: wsprintf( (TCHAR*)buf, _T(" VT_I1: %d \n"), V_I1( &var) );
592 			break;
593 		case VT_UI1: wsprintf( (TCHAR*)buf, _T(" VT_UI1: %d \n"), V_I1( &var) );
594 			break;
595 
596 		case VT_I2: wsprintf( (TCHAR*)buf, _T(" VT_I2: %d \n"), V_I2( &var) );
597 			break;
598 		case VT_I4: wsprintf( (TCHAR*)buf, _T(" VT_I4: %d \n"), V_I4( &var) );
599 			break;
600 		case VT_R8:
601 			{
602 
603 //				int     decimal,   sign;
604 //				char    *buffer;
605 //				int     precision = 14;
606 //				double  source = 3.1415926535;
607 
608 //				buffer = _ecvt( V_R8(&var), precision, &decimal, &sign );
609 				sprintf( (TCHAR*)buf, _T(" VT_R8: %f \n"),V_R8( &var) );
610 			break;
611 			}
612 		case VT_UNKNOWN:
613 			// The object implement IFont
614 			{
615 				CComDispatchDriver disp( var.punkVal);
616 				CComVariant ret;
617 				hr= disp.GetPropertyByName( static_cast<LPCOLESTR>(L"Name"), &ret);
618 				wsprintf( (TCHAR*)buf, _T(" VT_UNKNOWN: property \"Name\": %s \n"), W2T(ret.bstrVal));
619 				break;
620 			}
621 		case VT_DISPATCH:
622 			// The object implement IFont
623 			{
624 				CComDispatchDriver disp( var.punkVal);
625 				CComVariant ret;
626 				if( SUCCEEDED( hr= disp.GetPropertyByName( static_cast<LPCOLESTR>(L"Name"), &ret)))
627 					wsprintf( (TCHAR*)buf, _T(" VT_DISPATCH: property \"Name\": %s \n"), W2T(ret.bstrVal));
628 				else
629 					wsprintf( (TCHAR*)buf, _T(" VT_DISPATCH \n"));
630 
631 				break;
632 			}
633 
634 
635 		case VT_BSTR:
636 			{
637 				TCHAR* str= W2T( var.bstrVal);
638 				wsprintf( (TCHAR*)buf, _T(" VT_BSTR: %s \n"), str);
639 			}
640 			break;
641 		default:
642 			wsprintf( (TCHAR*)buf, _T("\n"));
643 
644 		}
645 
646 		OutputDebugString( (TCHAR*) buf);
647 	}
648 
649 		return;
650 
651 }
652 
653