/************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * only, as published by the Free Software Foundation. * * OpenOffice.org is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License version 3 for more details * (a copy is included in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenOffice.org. If not, see * * for a copy of the LGPLv3 License. * ************************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_extensions.hxx" #pragma warning (disable: 4917) #include #include #include #include extern CComModule _Module; #include #include #include #include #include #include #include #include #include #include #include #include #include CComModule _Module; BEGIN_OBJECT_MAP(ObjectMap) END_OBJECT_MAP() #include "smartarray.h" using namespace com::sun::star::bridge; using namespace com::sun::star::bridge::ModelDependent; using namespace com::sun::star::lang; using namespace com::sun::star::uno; using namespace oletest; using namespace cppu; using namespace rtl; HRESULT doTest(); HRESULT InitializeParameter(); void printResultVariantArray( VARIANT & var); void printVariant( VARIANT & var); int __cdecl _tmain( int argc, _TCHAR * argv[] ) { HRESULT hr; if( FAILED( hr=CoInitialize(NULL))) { _tprintf(_T("CoInitialize failed \n")); return -1; } _Module.Init( ObjectMap, GetModuleHandle( NULL)); if( FAILED(hr=doTest())) { _com_error err( hr); const TCHAR * errMsg= err.ErrorMessage(); MessageBox( NULL, errMsg, "Test failed", MB_ICONERROR); } _Module.Term(); CoUninitialize(); return 0; } char _c[]={ 1,2,3,4,5}; short _short[]={0xffff, 1, 11 ,111, 1111 }; unsigned short _ushort[]={0xffff, 1, 11 ,111, 1111 }; long _long[]= { 0xffffffff, 11, 111 ,1111, 1111 }; unsigned long _ulong[]= { 0xffffffff, 11, 111 ,1111, 1111 }; float _float[]= { 12345.f, 1234.5f, 123.45f, 12.345f, 1.2345f}; double _double[]= {12345, 1234.5, 123.45, 12.345, 1.2345}; CComVariant _variant[]= {L"variant 1", L"variant2", L"variant3"}; wchar_t _wchar[]= {L'1', L'2', L'3', L'A', L' '}; BSTR _bstr[]={L"Ich", L"bin", L"ein", L"Hamburger", L"Jung"}; SmartArray arByte( _c, 5, VT_I1); SmartArray< short> arShort( _short, 5, VT_I2); //SmartArray< unsigned short> arUShort( _ushort, 5, VT_UI2); SmartArray< long> arLong( _long, 5, VT_I4); //SmartArray< unsigned long> arULong( _ulong, 5, VT_UI4); //SmartArray< float> arFloat( _float, 5, VT_R4 ); SmartArray< double> arDouble( _double, 5, VT_R8 ); //SmartArray< unsigned short> arWChar( _wchar, 5, VT_UI2 ); SmartArray< wchar_t* > arString( _bstr, 5, VT_BSTR); SmartArray< VARIANT > arVariant( _variant, 3, VT_VARIANT); HRESULT doTest() { HRESULT hr; USES_CONVERSION; CComPtr spUnkMgr; putenv("UNO_TYPES=types.rdb"); putenv("UNO_SERVICES=services.rdb"); Reference xContext = defaultBootstrap_InitialComponentContext(); Reference< XMultiComponentFactory > mgr = xContext->getServiceManager();//createRegistryServiceFactory( OUString(L"services.rdb")); Reference< XInterface > xIntSupplier= mgr->createInstanceWithContext( OUString(L"com.sun.star.bridge.OleBridgeSupplierVar1"), xContext); Reference< XBridgeSupplier2 > xSuppl( xIntSupplier, UNO_QUERY); Reference xOletest= mgr->createInstanceWithContext( OUString(L"oletest.OleTest"), xContext); Any any; any <<= xOletest; sal_uInt8 arId[16]; rtl_getGlobalProcessId( arId); Any target= xSuppl->createBridge( any, Sequence( (sal_Int8*)arId, 16), UNO, OLE); CComDispatchDriver oletest; if (target.getValueTypeClass() == getCppuType((sal_uInt32*) 0).getTypeClass()) { VARIANT* pVariant = *(VARIANT**)target.getValue(); oletest= pVariant->pdispVal; VariantClear(pVariant); CoTaskMemFree(pVariant); } CComVariant varRet; CComVariant varParam1; CComVariant varParam2; CComVariant varParam3; CComVariant varParam4; long value= 100; varParam1.vt= VT_I1 | VT_BYREF; varParam1.plVal= &value; // Testing the caching of DISPIDs and the process of aquiring member information // on demand in IDispatch::Invoke // Step through the corresponding IDispatch implementation of the ole bridge hr= oletest.Invoke1(static_cast(L"testinout_methodByte"), &varParam1, &varRet); hr= oletest.Invoke1(static_cast(L"testinout_methodByte"), &varParam1, &varRet); // Name ok but different case hr= oletest.Invoke1(static_cast(L"Testinout_methodByte"), &varParam1, &varRet); hr= oletest.Invoke1(static_cast(L"Testinout_methodByte"), &varParam1, &varRet); // not existing member hr= oletest.Invoke1(static_cast(L"Testinout"), &varParam1, &varRet); hr= oletest.Invoke1(static_cast(L"Testinout"), &varParam1, &varRet); // Property varParam1.vt= VT_ARRAY | VT_I1; varParam1.parray= (SAFEARRAY*)arByte; hr= oletest.PutPropertyByName( static_cast(L"AttrByte"), &varParam1); hr= oletest.PutPropertyByName( static_cast(L"AttrByte"), &varParam1); // Name ok but different case hr= oletest.PutPropertyByName( static_cast(L"attrByte"), &varParam1); hr= oletest.PutPropertyByName( static_cast(L"attrByte"), &varParam1); // not existing member hr= oletest.PutPropertyByName( static_cast(L"attr"), &varParam1); hr= oletest.PutPropertyByName( static_cast(L"attr"), &varParam1); // PropertyGet hr= oletest.GetPropertyByName( static_cast(L"AttrByte"), &varRet); hr= oletest.GetPropertyByName( static_cast(L"attrByte"), &varRet); hr= oletest.GetPropertyByName( static_cast(L"attrByte"), &varRet); //not existing member hr= oletest.GetPropertyByName( static_cast(L"attrBy"), &varRet); hr= oletest.GetPropertyByName( static_cast(L"attrBy"), &varRet); DISPID dispid; LPOLESTR method= L"methodByte"; hr = oletest.p->GetIDsOfNames(IID_NULL, &method, 1, LOCALE_USER_DEFAULT, &dispid); CComVariant arg[1]; arg[0].vt= VT_ARRAY | VT_I1; arg[0].parray= (SAFEARRAY*)arByte; DISPPARAMS params={ arg,0,1,0}; hr = oletest.p->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD | DISPATCH_PROPERTYPUT, ¶ms, &varRet, NULL, NULL); hr = oletest.p->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD | DISPATCH_PROPERTYPUT, ¶ms, &varRet, NULL, NULL); // different case LPOLESTR method2= L"MEthodByte"; hr = oletest.p->GetIDsOfNames(IID_NULL, &method2, 1, LOCALE_USER_DEFAULT, &dispid); hr = oletest.p->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD | DISPATCH_PROPERTYPUT, ¶ms, &varRet, NULL, NULL); hr = oletest.p->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD | DISPATCH_PROPERTYPUT, ¶ms, &varRet, NULL, NULL); LPOLESTR attrib= L"AttrByte"; hr = oletest.p->GetIDsOfNames(IID_NULL, &attrib, 1, LOCALE_USER_DEFAULT, &dispid); hr = oletest.p->Invoke( dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD | DISPATCH_PROPERTYPUTREF, ¶ms, &varRet, NULL, NULL); hr = oletest.p->Invoke( dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD | DISPATCH_PROPERTYGET, ¶ms, &varRet, NULL, NULL); CComVariant varByteArray; varByteArray.vt= VT_ARRAY | VT_I1; varByteArray.parray= (SAFEARRAY*)arByte; CComVariant varShortArray; varShortArray.vt= VT_ARRAY | VT_I2; varShortArray.parray= (SAFEARRAY*)arShort; CComVariant varLongArray; varLongArray.vt= VT_ARRAY | VT_I4; varLongArray.parray= (SAFEARRAY*)arLong; CComVariant varDoubleArray; varDoubleArray.vt= VT_ARRAY | VT_R8; varDoubleArray.parray= (SAFEARRAY*)arDouble; CComVariant varStringArray; varStringArray.vt= VT_ARRAY | VT_BSTR; varStringArray.parray= (SAFEARRAY*)arString; CComVariant varArray; varArray.vt= VT_ARRAY | VT_VARIANT; varArray.parray= (SAFEARRAY*)arVariant; FONTDESC fd={ sizeof( fd), L"ARIAL", 10, FW_NORMAL, 0, 0, 0, 0}; CComPtr< IUnknown > unk1; CComPtr< IUnknown > unk2; CComPtr< IUnknown > unk3; IUnknown* _unknown[3]; hr= OleCreateFontIndirect( &fd, __uuidof( IUnknown), (void**)&unk1.p); hr= OleCreateFontIndirect( &fd, __uuidof( IUnknown), (void**)&unk2.p); hr= OleCreateFontIndirect( &fd, __uuidof( IUnknown), (void**)&unk3.p); _unknown[0]= unk1; _unknown[1]= unk2; _unknown[2]= unk3; SmartArray arUnknown( _unknown, 3, VT_UNKNOWN); CComVariant varUnkArray; varUnkArray.vt= VT_ARRAY | VT_UNKNOWN; varUnkArray.parray= (SAFEARRAY*)arUnknown; // preparing out parameter; char byteOut; CComVariant varOutByte; //### varOutByte.vt= VT_BYREF | VT_UI1; V_I1REF(&varOutByte)= &byteOut; short shortOut; CComVariant varOutShort; //### varOutShort.vt= VT_BYREF | VT_I2; V_I2REF( &varOutShort)= &shortOut; long longOut; CComVariant varOutLong; //### varOutLong.vt= VT_BYREF | VT_I4; V_I4REF( &varOutLong)= &longOut; double doubleOut; CComVariant varOutDouble; //### varOutDouble.vt= VT_BYREF | VT_R8; V_R8REF( &varOutDouble)= &doubleOut; BSTR bstrOut= NULL; CComVariant varOutString; //### varOutString.vt= VT_BYREF | VT_BSTR; V_BSTRREF(&varOutString)= &bstrOut; CComVariant variantOut; CComVariant varOutAny; //### varOutAny.vt= VT_BYREF | VT_VARIANT; V_VARIANTREF(&varOutAny)= &variantOut; CComPtr dispOut; CComVariant varOutXInterface; //### varOutXInterface.vt= VT_BYREF |VT_DISPATCH; V_DISPATCHREF(&varOutXInterface)= &dispOut.p; // In Parameter ( all of type Sequence ########################################################### OutputDebugString( _T("In parameter of type Sequence ###########################################\n" "The functions return the Sequence parameter \n\n")); OutputDebugStringA("methodByte | Params: \n"); printVariant( varByteArray); hr= oletest.Invoke1(static_cast(L"methodByte"), &varByteArray, &varRet); OutputDebugStringA("methodByte | return value \n"); printVariant( varRet); OutputDebugStringA("methodShort | Params: \n"); printVariant( varShortArray); hr= oletest.Invoke1(static_cast(L"methodShort"), &varShortArray, &varRet); OutputDebugStringA("methodShort | return value \n"); printVariant( varRet); OutputDebugStringA("methodLong | Params: \n"); printVariant( varLongArray); hr= oletest.Invoke1(static_cast(L"methodLong"), &varLongArray, &varRet); OutputDebugStringA("methodLong | return value \n"); printVariant( varRet); OutputDebugStringA("methodDouble | Params: \n"); printVariant( varDoubleArray); hr= oletest.Invoke1(static_cast(L"methodDouble"), &varDoubleArray, &varRet); OutputDebugStringA("methodDouble | return value \n"); printVariant( varRet); OutputDebugStringA("methodString | Params: \n"); printVariant( varStringArray); hr= oletest.Invoke1(static_cast(L"methodString"), &varStringArray, &varRet); OutputDebugStringA("methodString | return value \n"); printVariant( varRet); OutputDebugStringA("methodAny | Params: \n"); printVariant( varArray); hr= oletest.Invoke1(static_cast(L"methodAny"), &varArray, &varRet); OutputDebugStringA("methodAny | return value \n"); printVariant( varRet); OutputDebugStringA("methodXInterface | Params: \n"); printVariant( varUnkArray); hr= oletest.Invoke1(static_cast(L"methodXInterface"), &varUnkArray, &varRet); OutputDebugStringA("methodAny | return value \n"); printVariant( varRet); // Out Parameter ########################################################################### OutputDebugString( _T("Out parameter ###########################################\n\n")); OutputDebugString(_T("testout_methodByte \n")); hr= oletest.InvokeN(static_cast(L"testout_methodByte"), &varOutByte, 1, &varRet); OutputDebugString(_T("testout_methodByte | out value: \n")); printVariant( varOutByte); OutputDebugString(_T("testout_methodShort \n")); hr= oletest.Invoke1(static_cast(L"testout_methodShort"), &varOutShort, &varRet); OutputDebugString(_T("testout_methodShort | out value: \n")); printVariant( varOutShort); OutputDebugString(_T("testout_methodLong \n")); hr= oletest.Invoke1(static_cast(L"testout_methodLong"), &varOutLong, &varRet); OutputDebugString(_T("testout_methodLong | out value: \n")); printVariant( varOutLong); OutputDebugString(_T("testout_methodDouble \n")); hr= oletest.Invoke1(static_cast(L"testout_methodDouble"), &varOutDouble, &varRet); OutputDebugString(_T("testout_methodDouble | out value: \n")); printVariant( varOutDouble); OutputDebugString(_T("testout_methodString \n")); hr= oletest.Invoke1(static_cast(L"testout_methodString"), &varOutString, &varRet); OutputDebugString(_T("testout_methodString | out value: \n")); printVariant( varOutString); OutputDebugString(_T("testout_methodAny \n")); hr= oletest.Invoke1(static_cast(L"testout_methodAny"), &varOutAny, &varRet); OutputDebugString(_T("methodAny | out value: \n")); printVariant( varOutAny); OutputDebugString(_T("testout_methodXInterface \n")); hr= oletest.Invoke1(static_cast(L"testout_methodXInterface"), &varOutXInterface, &varRet); OutputDebugString(_T("methodAny | out value: \n")); printVariant( varOutXInterface); CComDispatchDriver outDisp( *varOutXInterface.ppdispVal); CComVariant varAttr3; outDisp.GetPropertyByName(L"AttrAny2", &varAttr3); ATLTRACE("property OleTest.AttrAny2: %s", W2T(varAttr3.bstrVal)); OutputDebugString(_T("testout_methodMulParams1 ( 2 out Parameter) \n")); long longOut2=0; CComVariant _params[2]; longOut=0; _params[0]= varOutLong; _params[1].vt= VT_BYREF | VT_I4; V_I4REF(& _params[1])= &longOut2; hr= oletest.InvokeN( static_cast(L"testout_methodMulParams1"), (VARIANT*)&_params, 2); OutputDebugString(_T("testout_methodMulParams1 | out values: \n")); printVariant( _params[1]); printVariant( _params[0]); OutputDebugString(_T("testout_methodMulParams2 ( 3 out Parameter) \n")); CComVariant _params2[3]; _params2[2]= varOutLong; _params2[1].vt= VT_BYREF | VT_I4; V_I4REF(& _params2[1])= &longOut2; _params2[0]= varOutString; hr= oletest.InvokeN( static_cast( L"testout_methodMulParams2"), (VARIANT*)&_params2, 3); OutputDebugString(_T("testout_methodMulParams2 | out values: \n")); printVariant( _params2[2]); printVariant( _params2[1]); printVariant( _params2[0]); OutputDebugString(_T("testout_methodMulParams3 ( 1 in and 1 out Parameter) \n")); CComVariant _params3[2]; _params3[1]= CComBSTR(L" In string"); _params3[0]= varOutString; hr= oletest.InvokeN( static_cast( L"testout_methodMulParams3"), (VARIANT*)&_params3, 2); OutputDebugString(_T("testout_methodMulParams3 | out values: \n")); printVariant( _params3[1]); printVariant( _params3[0]); //In Out Parameter ########################################################################### OutputDebugString( _T("In Out parameter ###########################################\n\n")); *V_I1REF(&varOutByte)= 5; ATLTRACE(_T("testinout_methodByte | in value: %d \n"), *V_I1REF(&varOutByte)); hr= oletest.InvokeN(static_cast(L"testinout_methodByte"), &varOutByte, 1, &varRet); OutputDebugString(_T("testinout_methodByte | out value: \n")); printVariant( varOutByte); OutputDebugString(_T("testinout_methodShort | in value= 1000 \n")); *V_UI2REF(&varOutShort)= 1000; hr= oletest.Invoke1(static_cast(L"testinout_methodShort"), &varOutShort, &varRet); OutputDebugString(_T("testinout_methodShort | out value: \n")); printVariant( varOutShort); OutputDebugString(_T("testinout_methodLong | in value= 10000 \n")); *V_UI4REF(&varOutLong)= 10000; hr= oletest.Invoke1(static_cast(L"testinout_methodLong"), &varOutLong, &varRet); OutputDebugString(_T("testinout_methodLong | out value: \n")); printVariant( varOutLong); *V_R8REF(&varOutDouble)= 3.14; ATLTRACE(_T("testinou_methodDouble in value: %f \n"),*V_R8REF(&varOutDouble)); hr= oletest.Invoke1(static_cast(L"testinout_methodDouble"), &varOutDouble, &varRet); OutputDebugString(_T("testinout_methodDouble | out value: \n")); printVariant( varOutDouble); SysFreeString( *V_BSTRREF(&varOutString)); *V_BSTRREF(&varOutString)= SysAllocString( L"this is a in string"); ATLTRACE(_T("testinout_methodString | value: %s \n"), W2T(*V_BSTRREF(&varOutString))); hr= oletest.Invoke1(static_cast(L"testinout_methodString"), &varOutString, &varRet); OutputDebugString(_T("testinout_methodString | out value: \n")); printVariant( varOutString); CComVariant var1(CComBSTR(L" this is a string in a VARIANT")); CComVariant outVar1; outVar1.vt= VT_BYREF | VT_VARIANT; outVar1.pvarVal= &var1; ATLTRACE(_T("testinout_methodAny | parameter: %s\n"), W2T(var1.bstrVal)); hr= oletest.Invoke1(static_cast(L"testinout_methodAny"), &varOutAny, &varRet); OutputDebugString(_T("testinout_methodAny | out value: \n")); printVariant( varOutAny); CComPtr< IUnknown > objectIn = unk1; CComVariant varOutIFace; varOutIFace.vt= VT_BYREF | VT_UNKNOWN; varOutIFace.ppunkVal= &objectIn.p; (*varOutIFace.ppunkVal)->AddRef(); OutputDebugString(_T("testinout_methodXInterface | in value: \n")); printVariant(varOutIFace); hr= oletest.Invoke1(static_cast(L"testinout_methodXInterface"), &varOutIFace, &varRet); OutputDebugString(_T("testinout_methodXInterface | out value: \n")); printVariant( varOutIFace); // Properties ###################################################################### OutputDebugString( _T(" Properties ###########################################\n\n")); OutputDebugString(_T("set property \"AttrByte\" | value")); //CComVariant propArByte; //propArByte.vt= VT_ARRAY | VT_I1; varParam1.parray= (SAFEARRAY*)arByte; printVariant( varParam1); hr= oletest.PutPropertyByName( static_cast(L"AttrByte"), &varParam1); OutputDebugString(_T("get property \"AttrByte\" | value:")); varRet.Clear(); hr= oletest.GetPropertyByName( static_cast(L"AttrByte"), &varRet); printVariant( varRet); return S_OK; } void printVariant( VARIANT & _var) { HRESULT hr; USES_CONVERSION; CComVariant var; hr= VariantCopyInd( &var, &_var); if( var.vt & VT_ARRAY) { VARTYPE type= var.vt ^ VT_ARRAY; SAFEARRAY * sarray= var.parray; long lbound; long ubound; hr= SafeArrayGetLBound( sarray, 1, &lbound); hr= SafeArrayGetUBound( sarray, 1, &ubound); long count= ubound - lbound + 1; char charValue; BYTE byteValue; short shortValue; long longValue; double doubleValue; IUnknown* unkValue; BSTR bstrValue; OutputDebugString( _T("# Array \n")); for( long i= 0; i < count; i++) { // CComVariant variantValue; TCHAR *buf[256]; wsprintf( (TCHAR*)buf, _T("%d : "), i); OutputDebugString( (TCHAR*)buf); VARIANT varTemp; VariantInit( &varTemp); VARIANT variantValue; VariantInit( &variantValue); switch( type) { case VT_UI1: hr= SafeArrayGetElement( sarray, &i, &byteValue); varTemp.vt= VT_UI1; V_UI1( &varTemp)= byteValue; printVariant( varTemp); break; case VT_I1: hr= SafeArrayGetElement( sarray, &i, &charValue); varTemp.vt= VT_I1; V_I1( &varTemp)= charValue; printVariant( varTemp); break; case VT_I2: hr= SafeArrayGetElement( sarray, &i, &shortValue); varTemp.vt= VT_I2; V_I2( &varTemp)= shortValue; printVariant( varTemp); break; case VT_UI2: case VT_I4: hr= SafeArrayGetElement( sarray, &i, &longValue); varTemp.vt= VT_I4; V_I4( &varTemp)= longValue; printVariant( varTemp); break; case VT_R8: hr= SafeArrayGetElement( sarray, &i, &doubleValue); varTemp.vt= VT_R8; V_R8( &varTemp)= doubleValue; printVariant( varTemp); break; case VT_BSTR: hr= SafeArrayGetElement( sarray, &i, &bstrValue); varTemp.vt= VT_BSTR; varTemp.bstrVal= bstrValue; printVariant( varTemp); break; case VT_VARIANT: hr= SafeArrayGetElement( sarray, &i, &varTemp); printVariant( varTemp); break; case VT_UNKNOWN: hr= SafeArrayGetElement( sarray, &i, &unkValue); varTemp.vt= VT_UNKNOWN; varTemp.punkVal= unkValue; printVariant( varTemp); break; } VariantClear( &varTemp); VariantClear( &variantValue); } } else { TCHAR buf[256]; switch (var.vt) { case VT_I1: wsprintf( (TCHAR*)buf, _T(" VT_I1: %d \n"), V_I1( &var) ); break; case VT_UI1: wsprintf( (TCHAR*)buf, _T(" VT_UI1: %d \n"), V_I1( &var) ); break; case VT_I2: wsprintf( (TCHAR*)buf, _T(" VT_I2: %d \n"), V_I2( &var) ); break; case VT_I4: wsprintf( (TCHAR*)buf, _T(" VT_I4: %d \n"), V_I4( &var) ); break; case VT_R8: { // int decimal, sign; // char *buffer; // int precision = 14; // double source = 3.1415926535; // buffer = _ecvt( V_R8(&var), precision, &decimal, &sign ); sprintf( (TCHAR*)buf, _T(" VT_R8: %f \n"),V_R8( &var) ); break; } case VT_UNKNOWN: // The object implement IFont { CComDispatchDriver disp( var.punkVal); CComVariant ret; hr= disp.GetPropertyByName( static_cast(L"Name"), &ret); wsprintf( (TCHAR*)buf, _T(" VT_UNKNOWN: property \"Name\": %s \n"), W2T(ret.bstrVal)); break; } case VT_DISPATCH: // The object implement IFont { CComDispatchDriver disp( var.punkVal); CComVariant ret; if( SUCCEEDED( hr= disp.GetPropertyByName( static_cast(L"Name"), &ret))) wsprintf( (TCHAR*)buf, _T(" VT_DISPATCH: property \"Name\": %s \n"), W2T(ret.bstrVal)); else wsprintf( (TCHAR*)buf, _T(" VT_DISPATCH \n")); break; } case VT_BSTR: { TCHAR* str= W2T( var.bstrVal); wsprintf( (TCHAR*)buf, _T(" VT_BSTR: %s \n"), str); } break; default: wsprintf( (TCHAR*)buf, _T("\n")); } OutputDebugString( (TCHAR*) buf); } return; }