X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/94113cc55572d23b2c86b9140543d32858c1eee6..d6d857b12404a9e50bebdd8d143a547b72332f2d:/src/msw/ole/automtn.cpp diff --git a/src/msw/ole/automtn.cpp b/src/msw/ole/automtn.cpp index 2a64cb87c1..cf05e1e910 100644 --- a/src/msw/ole/automtn.cpp +++ b/src/msw/ole/automtn.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: automtn.cpp +// Name: src/msw/ole/automtn.cpp // Purpose: OLE automation utilities // Author: Julian Smart // Modified by: @@ -13,21 +13,24 @@ #include "wx/wxprec.h" #if defined(__BORLANDC__) -#pragma hdrstop + #pragma hdrstop #endif -#include "wx/defs.h" - -// Watcom C++ gives a linker error if this is compiled in. // With Borland C++, all samples crash if this is compiled in. -#if wxUSE_OLE && !(defined(__BORLANDC__) && (__BORLANDC__ < 0x520)) && !defined(__CYGWIN10__) +#if (defined(__BORLANDC__) && (__BORLANDC__ < 0x520)) || defined(__CYGWIN10__) + #undef wxUSE_OLE_AUTOMATION + #define wxUSE_OLE_AUTOMATION 0 +#endif + +#ifndef WX_PRECOMP + #include "wx/log.h" + #include "wx/math.h" +#endif #define _FORCENAMELESSUNION -#include "wx/log.h" #include "wx/msw/private.h" #include "wx/msw/ole/oleutils.h" #include "wx/msw/ole/automtn.h" -#include "wx/math.h" #ifdef __WXWINCE__ #include "wx/msw/wince/time.h" @@ -49,12 +52,12 @@ #if wxUSE_DATETIME #include "wx/datetime.h" -#endif // wxUSE_TIMEDATE +#endif // wxUSE_DATETIME -static void ClearVariant(VARIANTARG *pvarg) ; -static void ReleaseVariant(VARIANTARG *pvarg) ; // static void ShowException(LPOLESTR szMember, HRESULT hr, EXCEPINFO *pexcep, unsigned int uiArgErr); +#if wxUSE_OLE_AUTOMATION + /* * wxAutomationObject */ @@ -90,7 +93,7 @@ bool wxAutomationObject::Invoke(const wxString& member, int action, { // Use dot notation to get the next object wxString member2(nonConstMember.Left((size_t) ch)); - wxString rest(nonConstMember.Right(nonConstMember.Length() - ch - 1)); + wxString rest(nonConstMember.Right(nonConstMember.length() - ch - 1)); wxAutomationObject obj; if (!GetObject(obj, member2)) return false; @@ -98,7 +101,7 @@ bool wxAutomationObject::Invoke(const wxString& member, int action, } VARIANTARG vReturn; - ClearVariant(& vReturn); + VariantInit(& vReturn); VARIANTARG* vReturnPtr = & vReturn; @@ -134,7 +137,6 @@ bool wxAutomationObject::Invoke(const wxString& member, int action, HRESULT hr; DISPPARAMS dispparams; unsigned int uiArgErr; - EXCEPINFO excep; // Get the IDs for the member and its arguments. GetIDsOfNames expects the // member name as the first name, followed by argument names (if any). @@ -154,7 +156,7 @@ bool wxAutomationObject::Invoke(const wxString& member, int action, { namedArgCount = 1; dispIds[1] = DISPID_PROPERTYPUT; - vReturnPtr = (VARIANTARG*) NULL; + vReturnPtr = NULL; } // Convert the wxVariants to VARIANTARGs @@ -176,7 +178,8 @@ bool wxAutomationObject::Invoke(const wxString& member, int action, dispparams.cArgs = noArgs; dispparams.cNamedArgs = namedArgCount; - excep.pfnDeferredFillIn = NULL; + EXCEPINFO excep; + wxZeroMemory(excep); hr = ((IDispatch*)m_dispatchPtr)->Invoke(dispIds[0], IID_NULL, LOCALE_SYSTEM_DEFAULT, (WORD)action, &dispparams, vReturnPtr, &excep, &uiArgErr); @@ -189,7 +192,7 @@ bool wxAutomationObject::Invoke(const wxString& member, int action, delete[] dispIds; for (i = 0; i < noArgs; i++) - ReleaseVariant(& oleArgs[i]) ; + VariantClear(& oleArgs[i]) ; delete[] oleArgs; if (FAILED(hr)) @@ -203,7 +206,7 @@ bool wxAutomationObject::Invoke(const wxString& member, int action, SysFreeString(excep.bstrHelpFile); if (vReturnPtr) - ReleaseVariant(vReturnPtr); + VariantClear(vReturnPtr); return false; } else @@ -215,9 +218,9 @@ bool wxAutomationObject::Invoke(const wxString& member, int action, // Mustn't release the dispatch pointer if (vReturn.vt == VT_DISPATCH) { - vReturn.pdispVal = (IDispatch*) NULL; + vReturn.pdispVal = NULL; } - ReleaseVariant(& vReturn); + VariantClear(& vReturn); } } return true; @@ -435,7 +438,7 @@ WXIDISPATCH* wxAutomationObject::GetDispatchProperty(const wxString& property, i } } - return (WXIDISPATCH*) NULL; + return NULL; } // Uses DISPATCH_PROPERTYGET @@ -453,7 +456,7 @@ WXIDISPATCH* wxAutomationObject::GetDispatchProperty(const wxString& property, i } } - return (WXIDISPATCH*) NULL; + return NULL; } @@ -493,7 +496,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))) { @@ -525,7 +528,7 @@ bool wxAutomationObject::CreateInstance(const wxString& classId) const CLSID clsId; - wxBasicString unicodeName(classId.mb_str()); + wxBasicString unicodeName(classId); if (FAILED(CLSIDFromProgID((BSTR) unicodeName, &clsId))) { @@ -533,8 +536,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; @@ -543,328 +551,7 @@ bool wxAutomationObject::CreateInstance(const wxString& classId) const return true; } - -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; - - long dosDateTime = date.GetAsDOS(); - short dosDate = (dosDateTime & 0xFFFF0000) >> 16; - short dosTime = dosDateTime & 0xFFFF; - - DosDateTimeToVariantTime(dosDate, dosTime, & 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 - -bool wxConvertOleToVariant(const VARIANTARG& oleVariant, wxVariant& variant) -{ - 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_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")); - return false; - } - } - return true; -} - -/* - * 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_BOOL: - case VT_R8: - case VT_ERROR: // to avoid erroring on an error return from Excel - // no work for these types - break; - - default: - wxLogWarning(wxT("ReleaseVariant: Unknown type")); - break; - } - } - - ClearVariant(pvarg); -} +#endif // wxUSE_OLE_AUTOMATION #if 0 @@ -928,6 +615,3 @@ void ShowException(LPOLESTR szMember, HRESULT hr, EXCEPINFO *pexcep, unsigned in } #endif - -#endif // wxUSE_OLE && !(defined(__BORLANDC__) && (__BORLANDC__ < 0x520)) && !defined(__CYGWIN10__) -