From 242019eef3fdcdb12b5310da67af3ef6d15e0f58 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 22 Dec 2007 15:22:16 +0000 Subject: [PATCH] handle VT_ARRAY/VT_BYREF VARIANTs in wxConvertOleToVariant() (patch 1845897) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@50899 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/msw/ole/automtn.cpp | 223 ++++++++++++++++++++++------------------ 1 file changed, 124 insertions(+), 99 deletions(-) diff --git a/src/msw/ole/automtn.cpp b/src/msw/ole/automtn.cpp index 0a80f775cb..c39b3b2e4c 100644 --- a/src/msw/ole/automtn.cpp +++ b/src/msw/ole/automtn.cpp @@ -671,112 +671,137 @@ WXDLLEXPORT bool wxConvertVariantToOle(const wxVariant& variant, VARIANTARG& ole #define VT_TYPEMASK 0xfff #endif -WXDLLEXPORT bool wxConvertOleToVariant(const VARIANTARG& oleVariant, wxVariant& variant) +WXDLLEXPORT bool +wxConvertOleToVariant(const VARIANTARG& oleVariant, wxVariant& variant) { - switch (oleVariant.vt & VT_TYPEMASK) + if ( oleVariant.vt & VT_ARRAY ) { - case VT_BSTR: - { - wxString str(wxConvertStringFromOle(oleVariant.bstrVal)); - variant = str; - break; - } - case VT_DATE: - { -#if wxUSE_DATETIME - unsigned short dosDate = 0; - unsigned short dosTime = 0; - VariantTimeToDosDateTime(oleVariant.date, & dosDate, & dosTime); + variant.ClearList(); - long dosDateTime = (dosDate << 16) | dosTime; - wxDateTime date; - date.SetFromDOS(dosDateTime); - variant = date; -#endif - break; - } - case VT_I4: - { - variant = (long) oleVariant.lVal; - break; - } - case VT_I2: - { - variant = (long) oleVariant.iVal; - break; - } + // Compute the total number of elements in all array dimensions + int cElements = 1; + for ( int cDims = 0; cDims < oleVariant.parray->cDims; cDims++ ) + cElements *= oleVariant.parray->rgsabound[cDims].cElements; - case VT_BOOL: - { -#if (defined(_MSC_VER) && (_MSC_VER <= 1000) && !defined(__MWERKS__) ) //GC -#ifndef HAVE_BOOL // Can't use bool operator if no native bool type - variant = (long) (oleVariant.bool != 0); -#else - variant = (bool) (oleVariant.bool != 0); -#endif -#else -#ifndef HAVE_BOOL // Can't use bool operator if no native bool type - variant = (long) (oleVariant.boolVal != 0); -#else - variant = (bool) (oleVariant.boolVal != 0); -#endif -#endif - break; - } - case VT_R8: - { - variant = oleVariant.dblVal; - break; - } - case VT_ARRAY: - { - variant.ClearList(); - - int cDims, cElements, i; - VARIANTARG* pvdata; - - // Iterate the dimensions: number of elements is x*y*z - for (cDims = 0, cElements = 1; - cDims < oleVariant.parray->cDims; cDims ++) - cElements *= oleVariant.parray->rgsabound[cDims].cElements; - - // Get a pointer to the data - HRESULT hr = SafeArrayAccessData(oleVariant.parray, (void HUGEP* FAR*) & pvdata); - if (hr != NOERROR) - return false; - // Iterate the data. - for (i = 0; i < cElements; i++) - { - VARIANTARG& oleElement = pvdata[i]; - wxVariant vElement; - if (!wxConvertOleToVariant(oleElement, vElement)) - return false; - - variant.Append(vElement); - } - SafeArrayUnaccessData(oleVariant.parray); - break; - } - case VT_DISPATCH: - { - variant = (void*) oleVariant.pdispVal; - break; - } - case VT_NULL: - { - variant.MakeNull(); - break; - } - case VT_EMPTY: - { - break; // Ignore Empty Variant, used only during destruction of objects - } - default: - { - wxLogError(wxT("wxAutomationObject::ConvertOleToVariant: Unknown variant value type")); + // Get a pointer to the data + VARIANTARG* pvdata; + HRESULT hr = SafeArrayAccessData(oleVariant.parray, (void **)&pvdata); + if ( FAILED(hr) ) return false; + + bool ok = true; + for ( int i = 0; i < cElements; i++ ) + { + VARIANTARG& oleElement = pvdata[i]; + wxVariant vElement; + if ( !wxConvertOleToVariant(oleElement, vElement) ) + { + ok = false; + variant.ClearList(); + break; + } + + variant.Append(vElement); + } + + SafeArrayUnaccessData(oleVariant.parray); + } + else if ( oleVariant.vt & VT_BYREF ) + { + switch ( oleVariant.vt & VT_TYPEMASK ) + { + case VT_VARIANT: + { + VARIANTARG& oleReference = *((LPVARIANT)oleVariant.byref); + if (!wxConvertOleToVariant(oleReference,variant)) + return false; + break; + } + + default: + wxLogError(wxT("wxAutomationObject::ConvertOleToVariant: [as yet] unhandled reference %X"),oleVariant.vt); + return false; } } + else // simply type (not array or reference) + { + switch (oleVariant.vt & VT_TYPEMASK) + { + case VT_BSTR: + { + wxString str(wxConvertStringFromOle(oleVariant.bstrVal)); + variant = str; + break; + } + case VT_DATE: + { +#if wxUSE_DATETIME + unsigned short dosDate = 0; + unsigned short dosTime = 0; + VariantTimeToDosDateTime(oleVariant.date, & dosDate, & dosTime); + + long dosDateTime = (dosDate << 16) | dosTime; + wxDateTime date; + date.SetFromDOS(dosDateTime); + variant = date; +#endif + break; + } + case VT_I4: + { + variant = (long) oleVariant.lVal; + break; + } + case VT_I2: + { + variant = (long) oleVariant.iVal; + break; + } + + case VT_BOOL: + { +#if (defined(_MSC_VER) && (_MSC_VER <= 1000) && !defined(__MWERKS__) ) //GC +#ifndef HAVE_BOOL // Can't use bool operator if no native bool type + variant = (long) (oleVariant.bool != 0); +#else + variant = (bool) (oleVariant.bool != 0); +#endif +#else +#ifndef HAVE_BOOL // Can't use bool operator if no native bool type + variant = (long) (oleVariant.boolVal != 0); +#else + variant = (bool) (oleVariant.boolVal != 0); +#endif +#endif + break; + } + case VT_R8: + { + variant = oleVariant.dblVal; + break; + } + case VT_DISPATCH: + { + variant = (void*) oleVariant.pdispVal; + break; + } + case VT_NULL: + { + variant.MakeNull(); + break; + } + case VT_EMPTY: + { + break; // Ignore Empty Variant, used only during destruction of objects + } + default: + { + wxLogError(wxT("wxAutomationObject::ConvertOleToVariant: Unknown variant value type %X -> %X"),oleVariant.vt,oleVariant.vt&VT_TYPEMASK); + return false; + } + } + } + return true; }