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 #include "stdafx.h"
28 //#include "AxTestComponents.h"
29 #include "Basic.h"
30 
31 
32 
33 /////////////////////////////////////////////////////////////////////////////
34 // CBasic
35 CBasic::CBasic():	m_cPrpByte(0),m_nPrpShort(0),m_lPrpLong(0),m_fPrpFloat(0), m_dPrpDouble(0),m_PrpArray(0),
36 m_safearray(NULL), m_bool(VARIANT_FALSE),
37 m_arByte(0), m_arShort(0), m_arLong(0), m_arString(0), m_arVariant(0), m_arFloat(0),
38 m_arDouble(0), m_arObject(0), m_arByteDim2(0), m_date(0.), m_scode(0)
39 
40 {
41 	memset(&m_cy, 0, sizeof(CY));
42 	memset(&m_decimal, 0, sizeof(DECIMAL));
43 }
44 
45 CBasic::~CBasic()
46 {
47 	SafeArrayDestroy(m_safearray);
48 	SafeArrayDestroy(m_arByte);
49 	SafeArrayDestroy(m_arShort);
50 	SafeArrayDestroy(m_arLong);
51 	SafeArrayDestroy(m_arString);
52 	SafeArrayDestroy(m_arVariant);
53 	SafeArrayDestroy(m_arFloat);
54 	SafeArrayDestroy(m_arDouble);
55 	SafeArrayDestroy(m_arObject);
56 	SafeArrayDestroy(m_arByteDim2);
57 
58 }
59 STDMETHODIMP CBasic::inBool(VARIANT_BOOL val)
60 {
61 	m_bool = val;
62 	return S_OK;
63 }
64 STDMETHODIMP CBasic::inByte(unsigned char val)
65 {
66 	m_byte = val;
67 	return S_OK;
68 }
69 
70 STDMETHODIMP CBasic::inShort(short val)
71 {
72 	m_short = val;
73 	return S_OK;
74 }
75 
76 STDMETHODIMP CBasic::inLong(long val)
77 {
78 	m_long = val;
79 	return S_OK;
80 }
81 
82 STDMETHODIMP CBasic::inString(BSTR val)
83 {
84 	m_bstr = val;
85 	return S_OK;
86 }
87 
88 STDMETHODIMP CBasic::inFloat(float val)
89 {
90 	m_float = val;
91 	return S_OK;
92 }
93 
94 STDMETHODIMP CBasic::inDouble(double val)
95 {
96 	m_double = val;
97 
98 	CComVariant varDest;
99 	CComVariant varSource(val);
100 	HRESULT hr = VariantChangeType(&varDest, &varSource, 0, VT_BSTR);
101 	return S_OK;
102 }
103 
104 STDMETHODIMP CBasic::inVariant(VARIANT val)
105 {
106 	m_var1 = val;
107 	return S_OK;
108 }
109 
110 STDMETHODIMP CBasic::inArray(LPSAFEARRAY val)
111 {
112 	HRESULT hr = S_OK;
113 	if (FAILED(hr = SafeArrayDestroy(m_safearray)))
114 		return hr;
115 	if (FAILED(hr = SafeArrayCopy(val, &m_safearray)))
116 		return hr;
117 	return S_OK;
118 }
119 
120 STDMETHODIMP CBasic::inObject(IDispatch *val)
121 {
122 	m_obj = val;
123 	return S_OK;
124 }
125 
126 STDMETHODIMP CBasic::inoutBool(VARIANT_BOOL* val)
127 {
128 	VARIANT_BOOL aBool = *val;
129 	*val = m_bool;
130 	m_bool = aBool;
131 	return S_OK;
132 }
133 
134 
135 STDMETHODIMP CBasic::inoutByte(unsigned char* val)
136 {
137 	unsigned char aByte = *val;
138 	*val = m_byte;
139 	m_byte = aByte;
140 	return S_OK;
141 }
142 
143 STDMETHODIMP CBasic::inoutShort(short *val)
144 {
145 	short aShort = *val;
146 	*val = m_short;
147 	m_short = aShort;
148 	return S_OK;
149 }
150 
151 STDMETHODIMP CBasic::inoutLong(long *val)
152 {
153 	long aLong = *val;
154 	*val = m_long;
155 	m_long = aLong;
156 	return S_OK;
157 }
158 
159 STDMETHODIMP CBasic::inoutString(BSTR *val)
160 {
161 	CComBSTR aStr = *val;
162 	HRESULT hr = S_OK;
163 	if (FAILED( hr = m_bstr.CopyTo(val)))
164 		return hr;
165 	m_bstr = aStr;
166 	return S_OK;
167 }
168 
169 STDMETHODIMP CBasic::inoutFloat(float *val)
170 {
171 	float aFloat = *val;
172 	*val = m_float;
173 	m_float = aFloat;
174 	return S_OK;
175 }
176 
177 STDMETHODIMP CBasic::inoutDouble(double *val)
178 {
179 	double aDouble = *val;
180 	*val = m_double;
181 	m_double  = aDouble;
182 	return S_OK;
183 }
184 
185 STDMETHODIMP CBasic::inoutVariant(VARIANT *val)
186 {
187 	CComVariant aVar = *val;
188 	HRESULT hr = S_OK;
189 	if (FAILED(hr = VariantCopy(val, &m_var1)))
190 		return hr;
191 	m_var1 = aVar;
192 	return S_OK;
193 }
194 
195 /* The array contains VARIANT according to IDL.
196 	If the VARIANTs contain strings then we append "out" to each string.
197 */
198 STDMETHODIMP CBasic::inoutArray(LPSAFEARRAY *val)
199 {
200 	SAFEARRAY* aAr = NULL;
201 	HRESULT hr = S_OK;
202 	if (FAILED(hr = SafeArrayCopy(*val, &aAr)))
203 		return hr;
204 	if (FAILED(hr = SafeArrayCopy(m_safearray, val)))
205 		return hr;
206 	if (FAILED(hr = SafeArrayCopy(aAr, & m_safearray)))
207 		return hr;
208 	return S_OK;
209 }
210 
211 STDMETHODIMP CBasic::inoutObject(IDispatch **val)
212 {
213 	CComPtr<IDispatch> disp = *val;
214 	if (*val)
215 		(*val)->Release();
216 	*val = m_obj;
217 	if (*val)
218 		(*val)->AddRef();
219 	m_obj = disp;
220 	return S_OK;
221 }
222 
223 
224 STDMETHODIMP CBasic::outBool(VARIANT_BOOL* val)
225 {
226 	*val = m_bool;
227 	return S_OK;
228 }
229 
230 STDMETHODIMP CBasic::outByte(unsigned char *val)
231 {
232 	*val= m_byte;
233 	return S_OK;
234 }
235 
236 STDMETHODIMP CBasic::outShort(short *val)
237 {
238 	*val= m_short;
239 	return S_OK;
240 }
241 
242 STDMETHODIMP CBasic::outLong(long *val)
243 {
244 	*val= m_long;
245 	return S_OK;
246 }
247 
248 STDMETHODIMP CBasic::outString(BSTR *val)
249 {
250 	*val= SysAllocString(m_bstr);
251 	return S_OK;
252 }
253 
254 STDMETHODIMP CBasic::outFloat(float *val)
255 {
256 	*val= m_float;
257 	return S_OK;
258 }
259 
260 STDMETHODIMP CBasic::outDouble(double *val)
261 {
262 	*val= m_double;
263 	return S_OK;
264 }
265 
266 STDMETHODIMP CBasic::outVariant(VARIANT *val)
267 {
268 	HRESULT hr = S_OK;
269 	if (FAILED(hr = VariantCopy(val, &m_var1)))
270 		return hr;
271 	return S_OK;
272 }
273 
274 STDMETHODIMP CBasic::outArray(LPSAFEARRAY *val)
275 {
276 	HRESULT hr = S_OK;
277 	if (FAILED(hr = SafeArrayCopy(m_safearray, val)))
278 		return false;
279 	return S_OK;
280 }
281 
282 STDMETHODIMP CBasic::outObject(IDispatch* *val)
283 {
284 	*val = m_obj;
285 	if (m_obj)
286 		(*val)->AddRef();
287 
288 	return S_OK;
289 }
290 
291 
292 STDMETHODIMP CBasic::get_prpBool(VARIANT_BOOL* pVal)
293 {
294 	if (!pVal) return E_POINTER;
295 	*pVal = m_bool;
296 	return S_OK;
297 }
298 
299 STDMETHODIMP CBasic::put_prpBool(VARIANT_BOOL val)
300 {
301 	m_bool = val;
302 	return S_OK;
303 }
304 
305 
306 STDMETHODIMP CBasic::get_prpByte(unsigned char *pVal)
307 {
308 	if( !pVal)
309 		return E_POINTER;
310 	*pVal= m_cPrpByte;
311 	return S_OK;
312 }
313 
314 STDMETHODIMP CBasic::put_prpByte(unsigned char newVal)
315 {
316 	m_cPrpByte= newVal;
317 	return S_OK;
318 }
319 
320 STDMETHODIMP CBasic::get_prpShort(short *pVal)
321 {
322 	if( !pVal)
323 		return E_POINTER;
324 	*pVal= m_nPrpShort;
325 	return S_OK;
326 }
327 
328 STDMETHODIMP CBasic::put_prpShort(short newVal)
329 {
330 	m_nPrpShort= newVal;
331 	return S_OK;
332 }
333 
334 STDMETHODIMP CBasic::get_prpLong(long *pVal)
335 {
336 	if( !pVal)
337 		return E_POINTER;
338 	*pVal= m_lPrpLong;
339 	return S_OK;
340 }
341 
342 STDMETHODIMP CBasic::put_prpLong(long newVal)
343 {
344 	m_lPrpLong= newVal;
345 	return S_OK;
346 }
347 
348 STDMETHODIMP CBasic::get_prpString(BSTR *pVal)
349 {
350 	if( !pVal)
351 		return E_POINTER;
352 	m_bstrPrpString.CopyTo( pVal );
353 	return S_OK;
354 }
355 
356 STDMETHODIMP CBasic::put_prpString(BSTR newVal)
357 {
358 	m_bstrPrpString= newVal;
359 	return S_OK;
360 }
361 
362 STDMETHODIMP CBasic::get_prpFloat(float *pVal)
363 {
364 	if( !pVal)
365 		return E_POINTER;
366 	*pVal= m_fPrpFloat;
367 	return S_OK;
368 }
369 
370 STDMETHODIMP CBasic::put_prpFloat(float newVal)
371 {
372 	m_fPrpFloat= newVal;
373 	return S_OK;
374 }
375 
376 STDMETHODIMP CBasic::get_prpDouble(double *pVal)
377 {
378 	if( !pVal)
379 		return E_POINTER;
380 	*pVal= m_dPrpDouble;
381 	return S_OK;
382 }
383 
384 STDMETHODIMP CBasic::put_prpDouble(double newVal)
385 {
386 	m_dPrpDouble= newVal;
387 	return S_OK;
388 }
389 
390 STDMETHODIMP CBasic::get_prpVariant(VARIANT *pVal)
391 {
392 	if( !pVal)
393 		return E_POINTER;
394 	HRESULT hr = S_OK;
395 	if (FAILED(hr = VariantCopy( pVal, &m_PropVariant)))
396 		return hr;
397 	return hr;
398 }
399 
400 STDMETHODIMP CBasic::put_prpVariant(VARIANT newVal)
401 {
402 	m_PropVariant= newVal;
403 	return S_OK;
404 }
405 
406 STDMETHODIMP CBasic::get_prpArray(LPSAFEARRAY *pVal)
407 {
408 	if( !pVal)
409 		return E_POINTER;
410 	HRESULT hr = S_OK;
411 	if (FAILED(hr = SafeArrayCopy( m_PrpArray, pVal)))
412 		return hr;
413 	return hr;
414 }
415 
416 STDMETHODIMP CBasic::put_prpArray(LPSAFEARRAY newVal)
417 {
418 	HRESULT hr = S_OK;
419 	if (FAILED(hr = SafeArrayDestroy( m_PrpArray)))
420 		return hr;
421 	if (FAILED(hr = SafeArrayCopy( newVal, &m_PrpArray)))
422 		return hr;
423 	return hr;
424 }
425 
426 STDMETHODIMP CBasic::get_prpObject(IDispatch **pVal)
427 {
428 	if( !pVal)
429 		return E_POINTER;
430 	*pVal= m_PrpObject;
431 	if( *pVal != NULL)
432 		(*pVal)->AddRef();
433 	return S_OK;
434 }
435 
436 STDMETHODIMP CBasic::put_prpObject(IDispatch *newVal)
437 {
438 	m_PrpObject= newVal;
439 	return S_OK;
440 }
441 
442 STDMETHODIMP CBasic::mixed1(
443             /* [out][in] */ unsigned char *aChar,
444 			/* [out][in] */ float *aFloat,
445             /* [out][in] */ VARIANT *aVar)
446 
447 {
448 	HRESULT hr= S_OK;
449 	inoutByte(aChar);
450 	inoutFloat(aFloat);
451 	inoutVariant(aVar);
452 	return hr;
453 }
454 
455 
456 
457 
458 // VT_UI1
459 
460 STDMETHODIMP CBasic::inSequenceLong(LPSAFEARRAY val)
461 {
462 	HRESULT hr = S_OK;
463 	if (FAILED(hr = SafeArrayDestroy(m_arLong)))
464 		return hr;
465 	if (FAILED(hr = SafeArrayCopy(val, & m_arLong)))
466 		return hr;
467 	return hr;
468 }
469 
470 STDMETHODIMP CBasic::inSequenceByte( LPSAFEARRAY val)
471 {
472 	HRESULT hr = S_OK;
473 	if (FAILED(hr = SafeArrayDestroy(m_arByte)))
474 		return hr;
475 	if (FAILED(hr = SafeArrayCopy(val, & m_arByte)))
476 		return hr;
477 	return hr;
478 }
479 
480 STDMETHODIMP CBasic::inSequenceShort(LPSAFEARRAY val)
481 {
482 	HRESULT hr = S_OK;
483 	if (FAILED(hr = SafeArrayDestroy(m_arShort)))
484 		return hr;
485 	if (FAILED(hr = SafeArrayCopy(val, & m_arShort)))
486 		return hr;
487 	return hr;
488 }
489 
490 STDMETHODIMP CBasic::inSequenceString(LPSAFEARRAY val)
491 {
492 	HRESULT hr = S_OK;
493 	if (FAILED(hr = SafeArrayDestroy(m_arString)))
494 		return hr;
495 	if (FAILED(hr = SafeArrayCopy(val, & m_arString)))
496 		return hr;
497 	return hr;
498 }
499 
500 STDMETHODIMP CBasic::inSequenceFloat(LPSAFEARRAY val)
501 {
502 	HRESULT hr = S_OK;
503 	if (FAILED(hr = SafeArrayDestroy(m_arFloat)))
504 		return hr;
505 	if (FAILED(hr = SafeArrayCopy(val, & m_arFloat)))
506 		return hr;
507 	return hr;
508 }
509 
510 STDMETHODIMP CBasic::inSequenceDouble(LPSAFEARRAY val)
511 {
512 	HRESULT hr = S_OK;
513 	if (FAILED(hr = SafeArrayDestroy(m_arDouble)))
514 		return hr;
515 	if (FAILED(hr = SafeArrayCopy(val, & m_arDouble)))
516 		return hr;
517 	return hr;
518 }
519 
520 STDMETHODIMP CBasic::inSequenceObject(LPSAFEARRAY val)
521 {
522 	HRESULT hr = S_OK;
523 	if (FAILED(hr = SafeArrayDestroy(m_arObject)))
524 		return hr;
525 	if (FAILED(hr = SafeArrayCopy(val, & m_arObject)))
526 		return hr;
527 	return hr;
528 }
529 
530 void CBasic::printArray( LPSAFEARRAY val, BSTR message, VARTYPE type)
531 {
532 
533 	HRESULT hr= S_OK;
534 	USES_CONVERSION;
535 	long lbound=0;
536 	long ubound= 0;
537 	hr= SafeArrayGetLBound( val, 1, &lbound);
538 	hr= SafeArrayGetUBound( val, 1, &ubound);
539 	long length= ubound - lbound +1;
540 
541 	CComVariant varElement;
542 	char buf[1024];
543 	sprintf( buf,"%s", W2A(message));
544 
545 	for( long i= 0; i < length ; i++)
546 	{
547 		char tmp[1024];
548 		long data=0;
549 		CComVariant var;
550 		switch( type)
551 		{
552 		case VT_UI1:
553 		case VT_I2:
554 		case VT_I4:
555 		case VT_ERROR:
556 			hr= SafeArrayGetElement( val, &i, (void*)&data);
557 			sprintf( tmp, "%d \n", *(long*)&data);
558 			break;
559 		case VT_BSTR:
560 			hr= SafeArrayGetElement( val, &i, (void*)&data);
561 			sprintf( tmp, "%S \n", (BSTR)data);
562 			break;
563 		case VT_VARIANT:
564 			hr= SafeArrayGetElement( val, &i, &var);
565 			sprintf( tmp, "%x \n", var.byref);
566 			break;
567 		case VT_R4:
568 			hr= SafeArrayGetElement( val, &i, (void*)&data);
569 			sprintf( tmp, "%f \n", *(float*) &data);
570 			break;
571 		case VT_R8: ;
572 			hr= SafeArrayGetElement( val, &i, (void*)&data);
573 			sprintf( tmp, "%f \n", *(double*) &data);
574 			break;
575 		case VT_DISPATCH:
576 			// we assume the objects are instances of this component and have the
577 			// property prpString set.
578 			hr= SafeArrayGetElement( val, &i, (void*)&data);
579 			IDispatch* pdisp= ( IDispatch*) data;
580 			CComDispatchDriver driver( pdisp);
581 			CComVariant var;
582 			if( pdisp)
583 			{
584 				driver.GetPropertyByName(L"prpString", &var);
585 				sprintf( tmp, "%x : %S \n", *(long*)&data, var.bstrVal);
586 			}
587 			else
588 				sprintf( tmp, "%x\n", *(long*)&data);
589 		}
590 
591 		strcat( buf, tmp);
592 	}
593 	MessageBox( NULL, _T(A2T(buf)), _T("AxTestComponents.Basic"), MB_OK);
594 
595 }
596 // V_ERROR OLECHAR VARIANT VT_UI1
597 
598 STDMETHODIMP CBasic::outSequenceByte(LPSAFEARRAY* val)
599 {
600 	HRESULT hr= S_OK;
601 	hr = SafeArrayCopy(m_arByte, val);
602 	return hr;
603 }
604 
605 STDMETHODIMP CBasic::outSequenceShort(LPSAFEARRAY* val)
606 {
607 	HRESULT hr= S_OK;
608 	hr = SafeArrayCopy(m_arShort, val);
609 	return hr;
610 }
611 
612 STDMETHODIMP CBasic::outSequenceLong(LPSAFEARRAY* val)
613 {
614 	HRESULT hr= S_OK;
615 	hr = SafeArrayCopy(m_arLong, val);
616 	return hr;
617 }
618 
619 STDMETHODIMP CBasic::outSequenceString(LPSAFEARRAY* val)
620 {
621 	HRESULT hr= S_OK;
622 	hr = SafeArrayCopy(m_arString, val);
623 	return hr;
624 }
625 
626 STDMETHODIMP CBasic::outSequenceFloat(LPSAFEARRAY* val)
627 {
628 	HRESULT hr= S_OK;
629 	hr = SafeArrayCopy(m_arFloat, val);
630 	return hr;
631 }
632 
633 STDMETHODIMP CBasic::outSequenceDouble(LPSAFEARRAY* val)
634 {
635 	HRESULT hr= S_OK;
636 	hr = SafeArrayCopy(m_arDouble, val);
637 	return hr;
638 }
639 
640 STDMETHODIMP CBasic::outSequenceObject(LPSAFEARRAY* val)
641 {
642 	HRESULT hr = S_OK;
643 	hr = SafeArrayCopy(m_arObject, val);
644 	return S_OK;
645 }
646 
647 STDMETHODIMP CBasic::inoutSequenceByte(LPSAFEARRAY* val)
648 {
649 	HRESULT hr = S_OK;
650 	SAFEARRAY *arTemp = NULL;
651 	if (FAILED(hr = SafeArrayCopy(*val, &arTemp)))
652 		return hr;
653 	if (FAILED(hr = SafeArrayCopy(m_arByte, val)))
654 		return hr;
655 	m_arByte = arTemp;
656 	return hr;
657 }
658 
659 STDMETHODIMP CBasic::inoutSequenceShort(LPSAFEARRAY* val)
660 {
661 	HRESULT hr = S_OK;
662 	SAFEARRAY *arTemp = NULL;
663 	if (FAILED(hr = SafeArrayCopy(*val, &arTemp)))
664 		return hr;
665 	if (FAILED(hr = SafeArrayCopy(m_arShort, val)))
666 		return hr;
667 	m_arShort = arTemp;
668 	return hr;
669 }
670 
671 STDMETHODIMP CBasic::inoutSequenceLong(LPSAFEARRAY* val)
672 {
673 	HRESULT hr = S_OK;
674 	SAFEARRAY *arTemp = NULL;
675 	if (FAILED(hr = SafeArrayCopy(*val, &arTemp)))
676 		return hr;
677 	if (FAILED(hr = SafeArrayCopy(m_arLong, val)))
678 		return hr;
679 	m_arLong = arTemp;
680 	return hr;
681 }
682 
683 STDMETHODIMP CBasic::inoutSequenceString(LPSAFEARRAY* val)
684 {
685 	HRESULT hr = S_OK;
686 	SAFEARRAY *arTemp = NULL;
687 	if (FAILED(hr = SafeArrayCopy(*val, &arTemp)))
688 		return hr;
689 	if (FAILED(hr = SafeArrayCopy(m_arString, val)))
690 		return hr;
691 	m_arString = arTemp;
692 	return hr;
693 }
694 
695 STDMETHODIMP CBasic::inoutSequenceFloat(LPSAFEARRAY* val)
696 {
697 	HRESULT hr = S_OK;
698 	SAFEARRAY *arTemp = NULL;
699 	if (FAILED(hr = SafeArrayCopy(*val, &arTemp)))
700 		return hr;
701 	if (FAILED(hr = SafeArrayCopy(m_arFloat, val)))
702 		return hr;
703 	m_arFloat = arTemp;
704 	return hr;
705 }
706 
707 STDMETHODIMP CBasic::inoutSequenceDouble(LPSAFEARRAY* val)
708 {
709 	HRESULT hr = S_OK;
710 	SAFEARRAY *arTemp = NULL;
711 	if (FAILED(hr = SafeArrayCopy(*val, &arTemp)))
712 		return hr;
713 	if (FAILED(hr = SafeArrayCopy(m_arDouble, val)))
714 		return hr;
715 	m_arDouble = arTemp;
716 	return hr;
717 }
718 
719 STDMETHODIMP CBasic::inoutSequenceObject(LPSAFEARRAY* val)
720 {
721 	HRESULT hr = S_OK;
722 	SAFEARRAY *arTemp = NULL;
723 	if (FAILED(hr = SafeArrayCopy(*val, &arTemp)))
724 		return hr;
725 	if (FAILED(hr = SafeArrayCopy(m_arObject, val)))
726 		return hr;
727 	m_arObject = arTemp;
728 	return hr;
729 }
730 
731 // 2-dimensional Array
732 STDMETHODIMP CBasic::inMulDimArrayLong(LPSAFEARRAY val)
733 {
734 	printMulArray( val, VT_I4);
735 	return S_OK;
736 }
737 // 2-dimensional Array
738 STDMETHODIMP CBasic::inMulDimArrayVariant(LPSAFEARRAY val)
739 {
740 	printMulArray( val, VT_VARIANT);
741 	return S_OK;
742 }
743 // 3-dimensional Array
744 STDMETHODIMP CBasic::inMulDimArrayLong2(LPSAFEARRAY val)
745 {
746 	printMulArray( val, VT_I4);
747 	return S_OK;
748 }
749 // 3-dimensional Array
750 STDMETHODIMP CBasic::inMulDimArrayVariant2(LPSAFEARRAY val)
751 {
752 	return S_OK;
753 }
754 
755 
756 STDMETHODIMP CBasic::inMulDimArrayByte(LPSAFEARRAY val)
757 {
758 	HRESULT hr = S_OK;
759 	if (FAILED(hr = SafeArrayDestroy(m_arByteDim2)))
760 		return hr;
761 	if (FAILED(hr = SafeArrayCopy(val, & m_arByteDim2)))
762 		return hr;
763 	return hr;
764 }
765 // 3-dimensionales array
766 STDMETHODIMP CBasic::inMulDimArrayByte2(LPSAFEARRAY val)
767 {
768 
769 	// TODO: Add your implementation code here
770 	//printMulArray( val, VT_UI1);
771 	return S_OK;
772 }
773 
774 // supports 2 and 3 dimensionals SAFEARRAY with elements of long or VARIANT
775 void CBasic::printMulArray( SAFEARRAY* val, VARTYPE type)
776 {
777 	HRESULT hr= S_OK;
778 	UINT dims= SafeArrayGetDim( val);
779 	long lbound1;
780 	long ubound1;
781 	long lbound2;
782 	long ubound2;
783 	long lbound3;
784 	long ubound3;
785 	long length1;
786 	long length2;
787 	long length3;
788 
789 	char buff[4096];
790 	buff[0]=0;
791 
792 	if( dims == 2)
793 	{
794 		hr= SafeArrayGetLBound( val, 1, &lbound1);
795 		hr= SafeArrayGetUBound( val, 1, &ubound1);
796 		length1= ubound1 - lbound1 +1;
797 
798 		hr= SafeArrayGetLBound( val, 2, &lbound2);
799 		hr= SafeArrayGetUBound( val, 2, &ubound2);
800 		length2= ubound2 - lbound2 + 1;
801 		char tmpBuf[1024];
802 		tmpBuf[0]=0;
803 		long index[2];
804 		for( long i= 0; i< length2; i++)
805 		{
806 			for( long j= 0; j<length1; j++)
807 			{
808 				index[0]= j;
809 				index[1]= i;
810 				long longVal;
811 				CComVariant var;
812 				switch( type)
813 				{
814 				case VT_I4:
815 					hr= SafeArrayGetElement( val, index, &longVal);
816 					sprintf( tmpBuf, "(%d,%d): %d\n", index[1], index[0], longVal);
817 					break;
818 				case VT_UI1:
819 					hr= SafeArrayGetElement( val, index, &longVal);
820 					sprintf( tmpBuf, "(%d,%d): %d\n", index[1], index[0], (unsigned char)longVal);
821 					break;
822 				case VT_VARIANT:
823 					hr= SafeArrayGetElement( val, index, &var );
824 					sprintf( tmpBuf, "(%d,%d):  %d (vartype %d)\n",  index[1], index[0], var.byref, var.vt);
825 					break;
826 				}
827 				strcat( buff,tmpBuf);
828 			}
829 
830 		}
831 
832 
833 	}
834 	else if( dims == 3 )
835 	{
836 		hr= SafeArrayGetLBound( val, 1, &lbound1);
837 		hr= SafeArrayGetUBound( val, 1, &ubound1);
838 		length1= ubound1 - lbound1 +1;
839 
840 		hr= SafeArrayGetLBound( val, 2, &lbound2);
841 		hr= SafeArrayGetUBound( val, 2, &ubound2);
842 		length2= ubound2 - lbound2 + 1;
843 
844 		hr= SafeArrayGetLBound( val, 3, &lbound3);
845 		hr= SafeArrayGetUBound( val, 3, &ubound3);
846 		length3= ubound3 - lbound3 +1;
847 		char tmpBuf[1024];
848 		tmpBuf[0]=0;
849 		long index[3];
850 		for( long i= 0; i< length3; i++)
851 		{
852 			for( long j= 0; j<length2; j++)
853 			{
854 				for( long k= 0; k<length1; k++)
855 				{
856 					index[0]= k;
857 					index[1]= j;
858 					index[2]= i;
859 					long longVal;
860 					CComVariant var;
861 					switch( type)
862 					{
863 					case VT_I4:
864 						hr= SafeArrayGetElement( val, index, &longVal);
865 						sprintf( tmpBuf, "(%d,%d,%d): %d\n", index[2], index[1], index[0], longVal);
866 						break;
867 					case VT_UI1:
868 						hr= SafeArrayGetElement( val, index, &longVal);
869 						sprintf( tmpBuf, "(%d,%d,%d): %d\n", index[2], index[1], index[0], (unsigned char)longVal);
870 						break;
871 
872 					case VT_VARIANT:
873 						hr= SafeArrayGetElement( val, index, &var );
874 						sprintf( tmpBuf, "(%d,%d,%d):  %d (vartype %d)\n", index[2],  index[1], index[0], var.byref, var.vt);
875 						break;
876 					}
877 					strcat( buff,tmpBuf);
878 				}
879 			}
880 
881 		}
882 
883 	}
884 
885 	MessageBox( NULL, A2T( buff), _T("AxTestControl.Basic"), MB_OK);
886 
887 
888 }
889 
890 
891 
892 
893 STDMETHODIMP CBasic::outMore(long* val1, long* val2)
894 {
895 	// TODO: Add your implementation code here
896 	*val1= 111;
897 	*val2= 112;
898 	return S_OK;
899 }
900 // If an optional parameter was not provided then the respective member will
901 // not be set
902 STDMETHODIMP CBasic::optional1(/*[in]*/ long val1, /*[in, optional]*/ VARIANT* val2)
903 {
904 	m_long = val1;
905 	if (val2->vt != VT_ERROR)
906 		m_var1 = *val2;
907 	return S_OK;
908 }
909 
910 STDMETHODIMP CBasic::optional2(/*[out]*/ long* val1,/*[out, optional]*/ VARIANT* val2)
911 {
912 	HRESULT hr = S_OK;
913 	*val1 = m_long;
914 
915 	if (val2->vt != VT_ERROR)
916 		hr = VariantCopy(val2, & m_var1);
917 	return hr;
918 }
919 
920 STDMETHODIMP CBasic::optional3(/*[in, optional]*/ VARIANT* val1,/*[in, optional]*/ VARIANT* val2)
921 {
922 	//if (val1->vt != VT_ERROR)
923 		m_var1 = *val1;
924 
925 	//if (val2->vt != VT_ERROR)
926 		m_var2 = *val2;
927 	return S_OK;
928 }
929 
930 STDMETHODIMP CBasic::optional4(/*[in, out, optional]*/ VARIANT* val1,
931 							   /*[in, out, optional]*/ VARIANT* val2)
932 {
933 	HRESULT hr = S_OK;
934 	//return the previously set in values
935 	if (val1->vt != VT_ERROR)
936 	{
937 		CComVariant var1(*val1);
938 		if (FAILED(hr = VariantCopy(val1, & m_var1)))
939 			return hr;
940 		m_var1 = var1;
941 	}
942 	if (val2->vt != VT_ERROR)
943 	{
944 		CComVariant var2(*val2);
945 		if (FAILED(hr = VariantCopy(val2, & m_var2)))
946 			return hr;
947 		m_var2 = var2;
948 	}
949 	return hr;
950 }
951 
952 STDMETHODIMP CBasic::optional5(/*[out, optional]*/ VARIANT* val1,
953 							   /*[out, optional]*/ VARIANT* val2)
954 {
955 	HRESULT hr = S_OK;
956 	if (FAILED(hr = VariantCopy(val1, &m_var1)))
957 		return hr;
958 	if (FAILED(hr = VariantCopy(val2, &m_var2)))
959 		return hr;
960 	return hr;
961 }
962 
963 STDMETHODIMP CBasic::defaultvalue1(/*[in, defaultvalue(10)]*/ long val1,
964 								   /*[in, defaultvalue(3.14)]*/ double* val2,
965 								//   /*[in, defaultvalue(10)]*/ VARIANT val3,
966 							       /*[in, defaultvalue(100)]*/ VARIANT* val4)
967 {
968 	m_long = val1;
969 	m_double = *val2;
970 //	m_var1 = val3;
971 	m_var2 = *val4;
972 	return S_OK;
973 }
974 STDMETHODIMP CBasic::defaultvalue2(/*[in, out, defaultvalue(10)]*/ long* val1,
975 								   /*[in, out, defaultvalue(3.14)]*/ double* val2,
976 								//   /*[in, out, defaultvalue(10)]*/ VARIANT* val3,
977 							       /*[in, out, defaultvalue(100)]*/ VARIANT* val4)
978 {
979 	HRESULT hr = S_OK;
980 	long aLong = *val1;
981 	double aDouble = *val2;
982 //	CComVariant var1(*val3);
983 	CComVariant var2(*val4);
984 	*val1 = m_long;
985 	*val2 = m_double;
986 	//if (FAILED(hr = VariantCopy(val3, &m_var1)))
987 	//	return hr;
988 	if (FAILED(hr = VariantCopy(val4, &m_var2)))
989 		return hr;
990 	m_long = aLong;
991 	m_double = aDouble;
992 //	m_var1 = var1;
993 	m_var2 = var2;
994 	return hr;
995 }
996 /* val2 contains the variable argument list. If no such arguments are supplied
997 	then the safearray is invalid. SafeArrayCopy then returns E_INVALIDARG
998 */
999 STDMETHODIMP CBasic::varargfunc1(/*[in]*/ long val1,/*[in]*/ LPSAFEARRAY val2)
1000 {
1001 	m_long = val1;
1002 
1003 	HRESULT hr = S_OK;
1004 	if (FAILED(hr = SafeArrayDestroy(m_safearray)))
1005 		return hr;
1006 	if (FAILED(hr = SafeArrayCopy(val2, & m_safearray)))
1007 	{
1008 		if (hr != E_INVALIDARG)
1009 			return hr;
1010 	}
1011 	return S_OK;
1012 }
1013 
1014 STDMETHODIMP CBasic::varargfunc2(/*[out]*/ long* val1, /*[out]*/ SAFEARRAY ** val2)
1015 {
1016 	*val1 = m_long;
1017 	HRESULT hr = SafeArrayCopy(m_safearray, val2);
1018 	return hr;
1019 }
1020 
1021 STDMETHODIMP CBasic::inSequenceByteDim2(LPSAFEARRAY val)
1022 {
1023 	HRESULT hr = S_OK;
1024 	if (FAILED(hr = SafeArrayDestroy(m_arByteDim2)))
1025 		return hr;
1026 	if (FAILED(hr = SafeArrayCopy(val, & m_arByteDim2)))
1027 		return hr;
1028 	return hr;
1029 }
1030 
1031 
1032 STDMETHODIMP CBasic::inCurrency(CY val)
1033 {
1034 	m_cy = val;
1035 	return S_OK;
1036 }
1037 
1038 STDMETHODIMP CBasic::outCurrency(CY* val)
1039 {
1040 	*val = m_cy;
1041 	return S_OK;
1042 }
1043 
1044 STDMETHODIMP CBasic::inoutCurrency(CY* val)
1045 {
1046 	CY tmp = *val;
1047 	*val = m_cy;
1048 	m_cy = tmp;
1049 	return S_OK;
1050 }
1051 
1052 STDMETHODIMP CBasic::inDate(DATE val)
1053 {
1054 	m_date = val;
1055 	return S_OK;
1056 }
1057 
1058 STDMETHODIMP CBasic::outDate(DATE* val)
1059 {
1060 	*val = m_date;
1061 	return S_OK;
1062 }
1063 
1064 STDMETHODIMP CBasic::inoutDate(DATE* val)
1065 {
1066 	DATE tmp = *val;
1067 	*val = m_date;
1068 	m_date = tmp;
1069 	return S_OK;
1070 }
1071 
1072 STDMETHODIMP CBasic::get_prpCurrency(CY* pVal)
1073 {
1074 	*pVal = m_cy;
1075 	return S_OK;
1076 }
1077 
1078 STDMETHODIMP CBasic::put_prpCurrency(CY newVal)
1079 {
1080 	m_cy = newVal;
1081 	return S_OK;
1082 }
1083 
1084 STDMETHODIMP CBasic::get_prpDate(DATE* pVal)
1085 {
1086 	*pVal = m_date;
1087 	return S_OK;
1088 }
1089 
1090 STDMETHODIMP CBasic::put_prpDate(DATE newVal)
1091 {
1092 	m_date = newVal;
1093 	return S_OK;
1094 }
1095 
1096 //VT_I4 DECIMAL_NEG //tagVARIANT DISPATCH_PROPERTYPUT
1097 STDMETHODIMP CBasic::inDecimal(DECIMAL val)
1098 {
1099 	m_decimal = val;
1100 	return S_OK;
1101 }
1102 
1103 STDMETHODIMP CBasic::outDecimal(DECIMAL* val)
1104 {
1105 	* val = m_decimal;
1106 	return S_OK;
1107 }
1108 
1109 STDMETHODIMP CBasic::inoutDecimal(DECIMAL* val)
1110 {
1111 	DECIMAL tmp;
1112 	tmp = * val;
1113 	* val = m_decimal;
1114 	m_decimal = tmp;
1115 	return S_OK;
1116 }
1117 
1118 STDMETHODIMP CBasic::get_prpDecimal(DECIMAL* pVal)
1119 {
1120 	* pVal = m_decimal;
1121 	return S_OK;
1122 }
1123 
1124 STDMETHODIMP CBasic::put_prpDecimal(DECIMAL newVal)
1125 {
1126 	m_decimal = newVal;
1127 	return S_OK;
1128 }
1129 
1130 STDMETHODIMP CBasic::inSCode(SCODE val)
1131 {
1132 	m_scode = val;
1133 	return S_OK;
1134 }
1135 
1136 STDMETHODIMP CBasic::outScode(SCODE* val)
1137 {
1138 	* val = m_scode;
1139 	return S_OK;
1140 }
1141 
1142 STDMETHODIMP CBasic::inoutSCode(SCODE* val)
1143 {
1144 	SCODE tmp = *val;
1145 	* val = m_scode;
1146 	m_scode = tmp;
1147 	return S_OK;
1148 }
1149 
1150 STDMETHODIMP CBasic::get_prpSCode(SCODE* pVal)
1151 {
1152 	* pVal = m_scode;
1153 	return S_OK;
1154 }
1155 
1156 STDMETHODIMP CBasic::put_prpSCode(SCODE newVal)
1157 {
1158 	m_scode = newVal;
1159 	return S_OK;
1160 }
1161 
1162 STDMETHODIMP CBasic::inrefLong(LONG* val)
1163 {
1164 	m_long = * val;
1165 	return S_OK;
1166 }
1167 
1168 STDMETHODIMP CBasic::inrefVariant(VARIANT* val)
1169 {
1170 	HRESULT hr = S_OK;
1171 	if (FAILED(hr = VariantCopy( & m_var1, val)))
1172 		return hr;
1173 	return S_OK;
1174 }
1175 
1176 STDMETHODIMP CBasic::inrefDecimal(DECIMAL* val)
1177 {
1178 	m_decimal = * val;
1179 	return S_OK;
1180 }
1181 
1182 STDMETHODIMP CBasic::get_prpRefLong(long* pVal)
1183 {
1184 	*pVal = m_long;
1185 	return S_OK;
1186 }
1187 
1188 STDMETHODIMP CBasic::putref_prpRefLong(long* newVal)
1189 {
1190 	m_long = * newVal;
1191 	return S_OK;
1192 }
1193 
1194 STDMETHODIMP CBasic::get_prprefVariant(VARIANT* pVal)
1195 {
1196 	HRESULT hr = S_OK;
1197 	hr = VariantCopy(pVal, & m_var1);
1198 	return hr;
1199 }
1200 
1201 STDMETHODIMP CBasic::putref_prprefVariant(VARIANT* newVal)
1202 {
1203 	m_var1 = * newVal;
1204 	return S_OK;
1205 }
1206 
1207 STDMETHODIMP CBasic::get_prprefDecimal(DECIMAL* pVal)
1208 {
1209 	* pVal = m_decimal;
1210 	return S_OK;
1211 }
1212 
1213 STDMETHODIMP CBasic::putref_prprefDecimal(DECIMAL* newVal)
1214 {
1215 	m_decimal = *newVal;
1216 	return S_OK;
1217 }
1218 
1219 
1220 STDMETHODIMP CBasic::optional6(VARIANT* val1, VARIANT* val2, VARIANT* val3, VARIANT* val4)
1221 {
1222 	HRESULT hr = S_OK;
1223 	if (FAILED(hr = m_var1.Copy(val1)))
1224 		return hr;
1225 	if (FAILED(hr = m_var2.Copy(val2)))
1226 		return hr;
1227 	if (FAILED(hr = m_var3.Copy(val3)))
1228 		return hr;
1229 	if (FAILED(hr = m_var4.Copy(val4)))
1230 		return hr;
1231 	return S_OK;
1232 }
1233 
1234 STDMETHODIMP CBasic::optional7(VARIANT* val1, VARIANT* val2, VARIANT* val3, VARIANT* val4)
1235 {
1236 	HRESULT hr = S_OK;
1237 	if (FAILED(hr = VariantCopy(val1, & m_var1)))
1238 		return hr;
1239 	if (FAILED(hr = VariantCopy(val2, & m_var2)))
1240 		return hr;
1241 	if (FAILED(hr = VariantCopy(val3, & m_var3)))
1242 		return hr;
1243 	if (FAILED(hr = VariantCopy(val4, & m_var4)))
1244 		return hr;
1245 
1246 	return S_OK;
1247 }
1248 
1249 STDMETHODIMP CBasic::get_prpMultiArg1(VARIANT* val1, VARIANT* val2, VARIANT* pVal)
1250 {
1251 	HRESULT hr = S_OK;
1252 	CComVariant tmp1(*val1);
1253 	CComVariant tmp2(*val2);
1254 
1255 	if (FAILED(hr = VariantCopy(val1, & m_var1)))
1256 		return hr;
1257 	if (FAILED(hr = VariantCopy(val2, & m_var2)))
1258 		return hr;
1259 	m_var1 = tmp1;
1260 	m_var2 = tmp2;
1261 	if  (FAILED(hr = VariantCopy(pVal, & m_var3)))
1262 		return hr;
1263 	return S_OK;
1264 }
1265 
1266 STDMETHODIMP CBasic::put_prpMultiArg1(VARIANT* val1, VARIANT* val2, VARIANT* newVal)
1267 {
1268 	HRESULT hr = S_OK;
1269 	CComVariant tmp1( * val1);
1270 	CComVariant tmp2( * val2);
1271 
1272 	if (FAILED(hr = VariantCopy(val1, & m_var1)))
1273 		return hr;
1274 	if (FAILED(hr = VariantCopy(val2, & m_var2)))
1275 		return hr;
1276 	m_var1 = tmp1;
1277 	m_var2 = tmp2;
1278 
1279 	m_var3 = *newVal;
1280 	return S_OK;
1281 }
1282 
1283 // tagVARIANT DISPATCH_PROPERTYPUT DISPID_PROPERTYPUT VARIANTARG LOCALE_USER_DEFAULT
1284 
1285 STDMETHODIMP CBasic::get_prpMultiArg2(VARIANT val1, VARIANT* pVal)
1286 {
1287 	HRESULT hr = S_OK;
1288 	m_var1 =  val1;
1289 
1290 	if (FAILED(hr = VariantCopy(pVal, & m_var2)))
1291 		return hr;
1292 	return S_OK;
1293 }
1294 
1295 STDMETHODIMP CBasic::put_prpMultiArg2(VARIANT val1, VARIANT newVal)
1296 {
1297 	m_var1 = val1;
1298 	m_var2 = newVal;
1299 	return S_OK;
1300 }
1301 
1302 // returns the values set by prpMultiArg2
1303 STDMETHODIMP CBasic::prpMultiArg2GetValues(VARIANT* val1, VARIANT* valProperty)
1304 {
1305 	HRESULT hr = S_OK;
1306 	if (FAILED(VariantCopy(val1, & m_var1)))
1307 		return hr;
1308 	if (FAILED(VariantCopy(valProperty, & m_var2)))
1309 		return hr;
1310 	return S_OK;
1311 }
1312 
1313 STDMETHODIMP CBasic::get_prpMultiArg3(LONG* val1, LONG* pVal)
1314 {
1315 	long aLong = *val1;
1316 	*val1 = m_long;
1317 	m_long = aLong;
1318 
1319 	* pVal = m_long2;
1320 	return S_OK;
1321 }
1322 
1323 STDMETHODIMP CBasic::put_prpMultiArg3(LONG* val1, LONG newVal)
1324 {
1325 	long aLong = *val1;
1326 	*val1 = m_long;
1327 	m_long = aLong;
1328 
1329 	m_long2 = newVal;
1330 	return S_OK;
1331 }
1332 
1333 STDMETHODIMP CBasic::inUnknown(IUnknown* val)
1334 {
1335 	m_unknown = val;
1336 
1337 	return S_OK;
1338 }
1339 
1340 STDMETHODIMP CBasic::outUnknown(IUnknown** val)
1341 {
1342 	m_unknown.CopyTo(val);
1343 	return S_OK;
1344 }
1345 
1346 STDMETHODIMP CBasic::inoutUnknown(IUnknown** val)
1347 {
1348 	CComPtr<IUnknown> tmp = *val;
1349 	m_unknown.CopyTo(val);
1350 	m_unknown = tmp;
1351 	return S_OK;
1352 }
1353 
1354 STDMETHODIMP CBasic::get_prpUnknown(IUnknown** pVal)
1355 {
1356 	m_prpUnknown.CopyTo(pVal);
1357 	return S_OK;
1358 }
1359 
1360 STDMETHODIMP CBasic::put_prpUnknown(IUnknown* newVal)
1361 {
1362 	m_prpUnknown = newVal;
1363 	return S_OK;
1364 }
1365