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