X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/d536aafb147e14e0c0d33766139e26c30fc9b33c..e2bfe6731edfca732418012b03438db85b4aa0dd:/src/msw/ole/automtn.cpp diff --git a/src/msw/ole/automtn.cpp b/src/msw/ole/automtn.cpp index a0937bdfdb..d10484a938 100644 --- a/src/msw/ole/automtn.cpp +++ b/src/msw/ole/automtn.cpp @@ -54,7 +54,7 @@ #if wxUSE_DATETIME #include "wx/datetime.h" -#endif // wxUSE_TIMEDATE +#endif // wxUSE_DATETIME static void ClearVariant(VARIANTARG *pvarg) ; static void ReleaseVariant(VARIANTARG *pvarg) ; @@ -498,7 +498,7 @@ bool wxAutomationObject::GetInstance(const wxString& classId) const CLSID clsId; IUnknown * pUnk = NULL; - wxBasicString unicodeName(classId.mb_str()); + wxBasicString unicodeName(classId); if (FAILED(CLSIDFromProgID((BSTR) unicodeName, &clsId))) { @@ -530,7 +530,7 @@ bool wxAutomationObject::CreateInstance(const wxString& classId) const CLSID clsId; - wxBasicString unicodeName(classId.mb_str()); + wxBasicString unicodeName(classId); if (FAILED(CLSIDFromProgID((BSTR) unicodeName, &clsId))) { @@ -538,8 +538,13 @@ bool wxAutomationObject::CreateInstance(const wxString& classId) const return false; } - // start a new copy of Excel, grab the IDispatch interface - if (FAILED(CoCreateInstance(clsId, NULL, CLSCTX_LOCAL_SERVER, IID_IDispatch, (void**)&m_dispatchPtr))) + // get the server IDispatch interface + // + // NB: using CLSCTX_INPROC_HANDLER results in failure when getting + // Automation interface for Microsoft Office applications so don't use + // CLSCTX_ALL which includes it + if (FAILED(CoCreateInstance(clsId, NULL, CLSCTX_SERVER, IID_IDispatch, + (void**)&m_dispatchPtr))) { wxLogWarning(wxT("Cannot start an instance of this class.")); return false; @@ -671,113 +676,149 @@ 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) + bool ok = true; + 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); - - 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: + // 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) { -#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_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(_T("unhandled VT_ARRAY type %x in wxConvertOleToVariant"), + oleVariant.vt & VT_TYPEMASK); + variant = wxVariant(); + ok = false; + break; } - case VT_R8: + + SafeArrayUnaccessData(oleVariant.parray); + } + else if ( oleVariant.vt & VT_BYREF ) + { + switch ( oleVariant.vt & VT_TYPEMASK ) { - variant = oleVariant.dblVal; - break; + 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; } - case VT_ARRAY: + } + else // simply type (not array or reference) + { + switch ( oleVariant.vt & VT_TYPEMASK ) { - variant.ClearList(); + case VT_BSTR: + { + wxString str(wxConvertStringFromOle(oleVariant.bstrVal)); + variant = str; + } + break; - int cDims, cElements, i; - VARIANTARG* pvdata; + 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 // wxUSE_DATETIME + break; - // 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; + case VT_I4: + variant = (long) oleVariant.lVal; + break; - // 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; + case VT_I2: + variant = (long) oleVariant.iVal; + break; - 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")); - return false; + 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 true; + + return ok; } /* @@ -861,6 +902,7 @@ static void ReleaseVariant(VARIANTARG *pvarg) 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;