From: Václav Slavík Date: Sun, 3 Jan 2010 18:28:56 +0000 (+0000) Subject: Moved wxConvertVariantToOle and wxConvertOleToVariant to oleutils.cpp. X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/a2fd865b0dc2abc2ae04811cbd88c90a146c9e4f Moved wxConvertVariantToOle and wxConvertOleToVariant to oleutils.cpp. These are declared in oleutils.h, so that's where they should be. More importantly, they are used by wxActiveXContainer and so are required even if wxUSE_OLE_AUTOMATION is off. Also added "wx" prefix to (Clear|Release)Variant, because they cannot be static any longer. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@63043 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/src/msw/ole/automtn.cpp b/src/msw/ole/automtn.cpp index 774d15476f..04f367675d 100644 --- a/src/msw/ole/automtn.cpp +++ b/src/msw/ole/automtn.cpp @@ -22,8 +22,6 @@ #define wxUSE_OLE_AUTOMATION 0 #endif -#if wxUSE_OLE_AUTOMATION - #ifndef WX_PRECOMP #include "wx/log.h" #include "wx/math.h" @@ -56,10 +54,12 @@ #include "wx/datetime.h" #endif // wxUSE_DATETIME -static void ClearVariant(VARIANTARG *pvarg) ; -static void ReleaseVariant(VARIANTARG *pvarg) ; +extern void wxClearVariant(VARIANTARG *pvarg) ; +extern void wxReleaseVariant(VARIANTARG *pvarg) ; // static void ShowException(LPOLESTR szMember, HRESULT hr, EXCEPINFO *pexcep, unsigned int uiArgErr); +#if wxUSE_OLE_AUTOMATION + /* * wxAutomationObject */ @@ -103,7 +103,7 @@ bool wxAutomationObject::Invoke(const wxString& member, int action, } VARIANTARG vReturn; - ClearVariant(& vReturn); + wxClearVariant(& vReturn); VARIANTARG* vReturnPtr = & vReturn; @@ -194,7 +194,7 @@ bool wxAutomationObject::Invoke(const wxString& member, int action, delete[] dispIds; for (i = 0; i < noArgs; i++) - ReleaseVariant(& oleArgs[i]) ; + wxReleaseVariant(& oleArgs[i]) ; delete[] oleArgs; if (FAILED(hr)) @@ -208,7 +208,7 @@ bool wxAutomationObject::Invoke(const wxString& member, int action, SysFreeString(excep.bstrHelpFile); if (vReturnPtr) - ReleaseVariant(vReturnPtr); + wxReleaseVariant(vReturnPtr); return false; } else @@ -222,7 +222,7 @@ bool wxAutomationObject::Invoke(const wxString& member, int action, { vReturn.pdispVal = NULL; } - ReleaseVariant(& vReturn); + wxReleaseVariant(& vReturn); } } return true; @@ -553,364 +553,7 @@ bool wxAutomationObject::CreateInstance(const wxString& classId) const return true; } - -WXDLLEXPORT bool wxConvertVariantToOle(const wxVariant& variant, VARIANTARG& oleVariant) -{ - ClearVariant(&oleVariant); - if (variant.IsNull()) - { - oleVariant.vt = VT_NULL; - return true; - } - - wxString type(variant.GetType()); - - - if (type == wxT("long")) - { - oleVariant.vt = VT_I4; - oleVariant.lVal = variant.GetLong() ; - } - // cVal not always present -#ifndef __GNUWIN32__ - else if (type == wxT("char")) - { - oleVariant.vt=VT_I1; // Signed Char - oleVariant.cVal=variant.GetChar(); - } -#endif - else if (type == wxT("double")) - { - oleVariant.vt = VT_R8; - oleVariant.dblVal = variant.GetDouble(); - } - else if (type == wxT("bool")) - { - oleVariant.vt = VT_BOOL; - // 'bool' required for VC++ 4 apparently -#if (defined(__VISUALC__) && (__VISUALC__ <= 1000)) - oleVariant.bool = variant.GetBool(); -#else - oleVariant.boolVal = variant.GetBool(); -#endif - } - else if (type == wxT("string")) - { - wxString str( variant.GetString() ); - oleVariant.vt = VT_BSTR; - oleVariant.bstrVal = wxConvertStringToOle(str); - } -#if wxUSE_DATETIME - else if (type == wxT("datetime")) - { - wxDateTime date( variant.GetDateTime() ); - oleVariant.vt = VT_DATE; - - SYSTEMTIME st; - date.GetAsMSWSysTime(&st); - - SystemTimeToVariantTime(&st, &oleVariant.date); - } -#endif - else if (type == wxT("void*")) - { - oleVariant.vt = VT_DISPATCH; - oleVariant.pdispVal = (IDispatch*) variant.GetVoidPtr(); - } - else if (type == wxT("list") || type == wxT("stringlist")) - { - oleVariant.vt = VT_VARIANT | VT_ARRAY; - - SAFEARRAY *psa; - SAFEARRAYBOUND saBound; - VARIANTARG *pvargBase; - VARIANTARG *pvarg; - int i, j; - - int iCount = variant.GetCount(); - - saBound.lLbound = 0; - saBound.cElements = iCount; - - psa = SafeArrayCreate(VT_VARIANT, 1, &saBound); - if (psa == NULL) - return false; - - SafeArrayAccessData(psa, (void**)&pvargBase); - - pvarg = pvargBase; - for (i = 0; i < iCount; i++) - { - // copy each string in the list of strings - wxVariant eachVariant(variant[i]); - if (!wxConvertVariantToOle(eachVariant, * pvarg)) - { - // memory failure: back out and free strings alloc'ed up to - // now, and then the array itself. - pvarg = pvargBase; - for (j = 0; j < i; j++) - { - SysFreeString(pvarg->bstrVal); - pvarg++; - } - SafeArrayDestroy(psa); - return false; - } - pvarg++; - } - - SafeArrayUnaccessData(psa); - - oleVariant.parray = psa; - } - else - { - oleVariant.vt = VT_NULL; - return false; - } - return true; -} - -#ifndef VT_TYPEMASK -#define VT_TYPEMASK 0xfff -#endif - -WXDLLEXPORT bool -wxConvertOleToVariant(const VARIANTARG& oleVariant, wxVariant& variant) -{ - bool ok = true; - if ( oleVariant.vt & VT_ARRAY ) - { - - // 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; - - // Get a pointer to the data - void* pvdata; - HRESULT hr = SafeArrayAccessData(oleVariant.parray, &pvdata); - if ( FAILED(hr) ) - return false; - - switch (oleVariant.vt & VT_TYPEMASK) - { - case VT_VARIANT: - { - variant.ClearList(); - VARIANTARG *variant_data=(VARIANTARG*)pvdata; - for ( int i = 0; i < cElements; i++ ) - { - VARIANTARG& oleElement = variant_data[i]; - wxVariant vElement; - if ( !wxConvertOleToVariant(oleElement, vElement) ) - { - ok = false; - variant.ClearList(); - break; - } - - variant.Append(vElement); - } - } - break; - - case VT_BSTR: - { - wxArrayString strings; - BSTR *string_val=(BSTR*)pvdata; - for ( int i = 0; i < cElements; ++i ) - { - wxString str=wxConvertStringFromOle(*string_val); - strings.Add(str); - ++string_val; - } - variant=strings; - } - break; - - default: - wxLogDebug(wxT("unhandled VT_ARRAY type %x in wxConvertOleToVariant"), - oleVariant.vt & VT_TYPEMASK); - variant = wxVariant(); - ok = false; - break; - } - - 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 - { - SYSTEMTIME st; - VariantTimeToSystemTime(oleVariant.date, &st); - - wxDateTime date; - date.SetFromMSWSysTime(st); - variant = date; - } -#endif // wxUSE_DATETIME - break; - - case VT_I4: - variant = (long) oleVariant.lVal; - break; - - case VT_I2: - variant = (long) oleVariant.iVal; - break; - - case VT_BOOL: - variant = oleVariant.boolVal != 0; - 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 ok; -} - -/* - * ClearVariant - * - * Zeros a variant structure without regard to current contents - */ -static void ClearVariant(VARIANTARG *pvarg) -{ - pvarg->vt = VT_EMPTY; - pvarg->wReserved1 = 0; - pvarg->wReserved2 = 0; - pvarg->wReserved3 = 0; - pvarg->lVal = 0; -} - -/* - * ReleaseVariant - * - * Clears a particular variant structure and releases any external objects - * or memory contained in the variant. Supports the data types listed above. - */ -static void ReleaseVariant(VARIANTARG *pvarg) -{ - VARTYPE vt; - VARIANTARG _huge *pvargArray; - LONG lLBound, lUBound, l; - - vt = (VARTYPE)(pvarg->vt & 0xfff); // mask off flags - - // check if an array. If so, free its contents, then the array itself. - if (V_ISARRAY(pvarg)) - { - // variant arrays are all this routine currently knows about. Since a - // variant can contain anything (even other arrays), call ourselves - // recursively. - if (vt == VT_VARIANT) - { - SafeArrayGetLBound(pvarg->parray, 1, &lLBound); - SafeArrayGetUBound(pvarg->parray, 1, &lUBound); - - if (lUBound > lLBound) - { - lUBound -= lLBound; - - SafeArrayAccessData(pvarg->parray, (void**)&pvargArray); - - for (l = 0; l < lUBound; l++) - { - ReleaseVariant(pvargArray); - pvargArray++; - } - - SafeArrayUnaccessData(pvarg->parray); - } - } - else - { - wxLogWarning(wxT("ReleaseVariant: Array contains non-variant type")); - } - - // Free the array itself. - SafeArrayDestroy(pvarg->parray); - } - else - { - switch (vt) - { - case VT_DISPATCH: - if (pvarg->pdispVal) - pvarg->pdispVal->Release(); - break; - - case VT_BSTR: - SysFreeString(pvarg->bstrVal); - break; - - case VT_I2: - case VT_I4: - case VT_BOOL: - case VT_R8: - case VT_ERROR: // to avoid erroring on an error return from Excel - case VT_EMPTY: - case VT_DATE: - // no work for these types - break; - - default: - wxLogWarning(wxT("ReleaseVariant: Unknown type")); - break; - } - } - - ClearVariant(pvarg); -} +#endif // wxUSE_OLE_AUTOMATION #if 0 @@ -974,5 +617,3 @@ void ShowException(LPOLESTR szMember, HRESULT hr, EXCEPINFO *pexcep, unsigned in } #endif - -#endif // wxUSE_OLE_AUTOMATION diff --git a/src/msw/ole/oleutils.cpp b/src/msw/ole/oleutils.cpp index cd7dd75edc..8cf7899187 100644 --- a/src/msw/ole/oleutils.cpp +++ b/src/msw/ole/oleutils.cpp @@ -124,12 +124,380 @@ wxBasicString::~wxBasicString() SysFreeString(m_bstrBuf); } -#if wxUSE_DATAOBJ + +// ---------------------------------------------------------------------------- +// Convert variants +// ---------------------------------------------------------------------------- + +#if wxUSE_VARIANT + +/* + * wxClearVariant + * + * Zeros a variant structure without regard to current contents + */ +void wxClearVariant(VARIANTARG *pvarg) +{ + pvarg->vt = VT_EMPTY; + pvarg->wReserved1 = 0; + pvarg->wReserved2 = 0; + pvarg->wReserved3 = 0; + pvarg->lVal = 0; +} + +/* + * wxReleaseVariant + * + * Clears a particular variant structure and releases any external objects + * or memory contained in the variant. Supports the data types listed above. + */ +void wxReleaseVariant(VARIANTARG *pvarg) +{ + VARTYPE vt; + VARIANTARG _huge *pvargArray; + LONG lLBound, lUBound, l; + + vt = (VARTYPE)(pvarg->vt & 0xfff); // mask off flags + + // check if an array. If so, free its contents, then the array itself. + if (V_ISARRAY(pvarg)) + { + // variant arrays are all this routine currently knows about. Since a + // variant can contain anything (even other arrays), call ourselves + // recursively. + if (vt == VT_VARIANT) + { + SafeArrayGetLBound(pvarg->parray, 1, &lLBound); + SafeArrayGetUBound(pvarg->parray, 1, &lUBound); + + if (lUBound > lLBound) + { + lUBound -= lLBound; + + SafeArrayAccessData(pvarg->parray, (void**)&pvargArray); + + for (l = 0; l < lUBound; l++) + { + wxReleaseVariant(pvargArray); + pvargArray++; + } + + SafeArrayUnaccessData(pvarg->parray); + } + } + else + { + wxLogWarning(wxT("wxReleaseVariant: Array contains non-variant type")); + } + + // Free the array itself. + SafeArrayDestroy(pvarg->parray); + } + else + { + switch (vt) + { + case VT_DISPATCH: + if (pvarg->pdispVal) + pvarg->pdispVal->Release(); + break; + + case VT_BSTR: + SysFreeString(pvarg->bstrVal); + break; + + case VT_I2: + case VT_I4: + case VT_BOOL: + case VT_R8: + case VT_ERROR: // to avoid erroring on an error return from Excel + case VT_EMPTY: + case VT_DATE: + // no work for these types + break; + + default: + wxLogWarning(wxT("wxReleaseVariant: Unknown type")); + break; + } + } + + wxClearVariant(pvarg); +} + +WXDLLEXPORT bool wxConvertVariantToOle(const wxVariant& variant, VARIANTARG& oleVariant) +{ + wxClearVariant(&oleVariant); + if (variant.IsNull()) + { + oleVariant.vt = VT_NULL; + return true; + } + + wxString type(variant.GetType()); + + + if (type == wxT("long")) + { + oleVariant.vt = VT_I4; + oleVariant.lVal = variant.GetLong() ; + } + // cVal not always present +#ifndef __GNUWIN32__ + else if (type == wxT("char")) + { + oleVariant.vt=VT_I1; // Signed Char + oleVariant.cVal=variant.GetChar(); + } +#endif + else if (type == wxT("double")) + { + oleVariant.vt = VT_R8; + oleVariant.dblVal = variant.GetDouble(); + } + else if (type == wxT("bool")) + { + oleVariant.vt = VT_BOOL; + // 'bool' required for VC++ 4 apparently +#if (defined(__VISUALC__) && (__VISUALC__ <= 1000)) + oleVariant.bool = variant.GetBool(); +#else + oleVariant.boolVal = variant.GetBool(); +#endif + } + else if (type == wxT("string")) + { + wxString str( variant.GetString() ); + oleVariant.vt = VT_BSTR; + oleVariant.bstrVal = wxConvertStringToOle(str); + } +#if wxUSE_DATETIME + else if (type == wxT("datetime")) + { + wxDateTime date( variant.GetDateTime() ); + oleVariant.vt = VT_DATE; + + SYSTEMTIME st; + date.GetAsMSWSysTime(&st); + + SystemTimeToVariantTime(&st, &oleVariant.date); + } +#endif + else if (type == wxT("void*")) + { + oleVariant.vt = VT_DISPATCH; + oleVariant.pdispVal = (IDispatch*) variant.GetVoidPtr(); + } + else if (type == wxT("list") || type == wxT("stringlist")) + { + oleVariant.vt = VT_VARIANT | VT_ARRAY; + + SAFEARRAY *psa; + SAFEARRAYBOUND saBound; + VARIANTARG *pvargBase; + VARIANTARG *pvarg; + int i, j; + + int iCount = variant.GetCount(); + + saBound.lLbound = 0; + saBound.cElements = iCount; + + psa = SafeArrayCreate(VT_VARIANT, 1, &saBound); + if (psa == NULL) + return false; + + SafeArrayAccessData(psa, (void**)&pvargBase); + + pvarg = pvargBase; + for (i = 0; i < iCount; i++) + { + // copy each string in the list of strings + wxVariant eachVariant(variant[i]); + if (!wxConvertVariantToOle(eachVariant, * pvarg)) + { + // memory failure: back out and free strings alloc'ed up to + // now, and then the array itself. + pvarg = pvargBase; + for (j = 0; j < i; j++) + { + SysFreeString(pvarg->bstrVal); + pvarg++; + } + SafeArrayDestroy(psa); + return false; + } + pvarg++; + } + + SafeArrayUnaccessData(psa); + + oleVariant.parray = psa; + } + else + { + oleVariant.vt = VT_NULL; + return false; + } + return true; +} + +#ifndef VT_TYPEMASK +#define VT_TYPEMASK 0xfff +#endif + +WXDLLEXPORT bool +wxConvertOleToVariant(const VARIANTARG& oleVariant, wxVariant& variant) +{ + bool ok = true; + if ( oleVariant.vt & VT_ARRAY ) + { + + // 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; + + // Get a pointer to the data + void* pvdata; + HRESULT hr = SafeArrayAccessData(oleVariant.parray, &pvdata); + if ( FAILED(hr) ) + return false; + + switch (oleVariant.vt & VT_TYPEMASK) + { + case VT_VARIANT: + { + variant.ClearList(); + VARIANTARG *variant_data=(VARIANTARG*)pvdata; + for ( int i = 0; i < cElements; i++ ) + { + VARIANTARG& oleElement = variant_data[i]; + wxVariant vElement; + if ( !wxConvertOleToVariant(oleElement, vElement) ) + { + ok = false; + variant.ClearList(); + break; + } + + variant.Append(vElement); + } + } + break; + + case VT_BSTR: + { + wxArrayString strings; + BSTR *string_val=(BSTR*)pvdata; + for ( int i = 0; i < cElements; ++i ) + { + wxString str=wxConvertStringFromOle(*string_val); + strings.Add(str); + ++string_val; + } + variant=strings; + } + break; + + default: + wxLogDebug(wxT("unhandled VT_ARRAY type %x in wxConvertOleToVariant"), + oleVariant.vt & VT_TYPEMASK); + variant = wxVariant(); + ok = false; + break; + } + + 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 + { + SYSTEMTIME st; + VariantTimeToSystemTime(oleVariant.date, &st); + + wxDateTime date; + date.SetFromMSWSysTime(st); + variant = date; + } +#endif // wxUSE_DATETIME + break; + + case VT_I4: + variant = (long) oleVariant.lVal; + break; + + case VT_I2: + variant = (long) oleVariant.iVal; + break; + + case VT_BOOL: + variant = oleVariant.boolVal != 0; + 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 ok; +} + +#endif // wxUSE_VARIANT + // ---------------------------------------------------------------------------- // Debug support // ---------------------------------------------------------------------------- +#if wxUSE_DATAOBJ + #if wxDEBUG_LEVEL && ( ( defined(__VISUALC__) && (__VISUALC__ > 1000) ) || defined(__MWERKS__) ) static wxString GetIidName(REFIID riid) { @@ -260,7 +628,7 @@ void wxLogRelease(const wxChar *szInterface, ULONG cRef) #endif // wxDEBUG_LEVEL -#endif // wxUSE_DRAG_AND_DROP +#endif // wxUSE_DATAOBJ #endif // __CYGWIN10__