X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/25889d3c43f537fea00a2b7d6df7bd7e63e113f8..e4a8a172020d5e3ee08660420142e702799c7878:/src/msw/ole/automtn.cpp diff --git a/src/msw/ole/automtn.cpp b/src/msw/ole/automtn.cpp index 934efa6354..6b948f8baa 100644 --- a/src/msw/ole/automtn.cpp +++ b/src/msw/ole/automtn.cpp @@ -9,7 +9,7 @@ // Licence: wxWindows Licence ///////////////////////////////////////////////////////////////////////////// -#ifdef __GNUG__ +#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) #pragma implementation "automtn.h" #endif @@ -20,50 +20,37 @@ #pragma hdrstop #endif -#include "wx/log.h" +#include "wx/defs.h" -#include -#include - -#include "wx/msw/ole/automtn.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(__WATCOMC__) && !(defined(__BORLANDC__) && (__BORLANDC__ < 0x520)) && !defined(__CYGWIN10__) +#define _FORCENAMELESSUNION +#include "wx/log.h" #include "wx/msw/private.h" +#include "wx/msw/ole/oleutils.h" +#include "wx/msw/ole/automtn.h" -#include -#include - -// wrapper around BSTR type (by Vadim Zeitlin) - -class WXDLLEXPORT BasicString -{ -public: - // ctors & dtor - BasicString(const char *sz); - ~BasicString(); - - // accessors - // just get the string - operator BSTR() const { return m_wzBuf; } - // retrieve a copy of our string - caller must SysFreeString() it later! - BSTR Get() const { return SysAllocString(m_wzBuf); } +#include -private: - // @@@ not implemented (but should be) - BasicString(const BasicString&); - BasicString& operator=(const BasicString&); +#ifdef __WXWINCE__ +#include "wx/msw/wince/time.h" +#else +#include +#endif - OLECHAR *m_wzBuf; // actual string -}; +#include +#include -// Convert variants -static bool ConvertVariantToOle(const wxVariant& variant, VARIANTARG& oleVariant) ; -static bool ConvertOleToVariant(const VARIANTARG& oleVariant, wxVariant& variant) ; +#include +#define _huge -// Convert string to Unicode -static BSTR ConvertStringToOle(const wxString& str); +#ifndef __WXWINCE__ +#include +#endif -// Convert string from BSTR to wxString -static wxString ConvertStringFromOle(BSTR bStr); +#include // Verifies will fail if the needed buffer size is too large #define MAX_TIME_BUFFER_SIZE 128 // matches that in timecore.cpp @@ -77,12 +64,13 @@ static wxString ConvertStringFromOle(BSTR bStr); static int rgMonthDays[13] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365}; +#if wxUSE_DATETIME +#include "wx/datetime.h" + static BOOL OleDateFromTm(WORD wYear, WORD wMonth, WORD wDay, WORD wHour, WORD wMinute, WORD wSecond, DATE& dtDest); static BOOL TmFromOleDate(DATE dtSrc, struct tm& tmDest); -static void TmConvertToStandardFormat(struct tm& tmSrc); -static double DoubleFromDate(DATE dt); -static DATE DateFromDouble(double dbl); +#endif // wxUSE_TIMEDATE static void ClearVariant(VARIANTARG *pvarg) ; static void ReleaseVariant(VARIANTARG *pvarg) ; @@ -146,7 +134,7 @@ bool wxAutomationObject::Invoke(const wxString& member, int action, int namedArgStringCount = namedArgCount + 1; BSTR* argNames = new BSTR[namedArgStringCount]; - argNames[0] = ConvertStringToOle(member); + argNames[0] = wxConvertStringToOle(member); // Note that arguments are specified in reverse order // (all totally logical; hey, we're dealing with OLE here.) @@ -156,7 +144,7 @@ bool wxAutomationObject::Invoke(const wxString& member, int action, { if (!INVOKEARG(i).GetName().IsNull()) { - argNames[(namedArgCount-j)] = ConvertStringToOle(INVOKEARG(i).GetName()); + argNames[(namedArgCount-j)] = wxConvertStringToOle(INVOKEARG(i).GetName()); j ++; } } @@ -176,6 +164,8 @@ bool wxAutomationObject::Invoke(const wxString& member, int action, if (FAILED(hr)) { // ShowException(szMember, hr, NULL, 0); + delete[] argNames; + delete[] dispIds; return FALSE; } @@ -193,8 +183,13 @@ bool wxAutomationObject::Invoke(const wxString& member, int action, for (i = 0; i < noArgs; i++) { // Again, reverse args - if (!ConvertVariantToOle(INVOKEARG((noArgs-1) - i), oleArgs[i])) - return FALSE; // TODO: clean up memory at this point + if (!wxConvertVariantToOle(INVOKEARG((noArgs-1) - i), oleArgs[i])) + { + delete[] argNames; + delete[] dispIds; + delete[] oleArgs; + return FALSE; + } } dispparams.rgdispidNamedArgs = dispIds + 1; @@ -237,7 +232,7 @@ bool wxAutomationObject::Invoke(const wxString& member, int action, if (vReturnPtr) { // Convert result to wxVariant form - ConvertOleToVariant(vReturn, retValue); + wxConvertOleToVariant(vReturn, retValue); // Mustn't release the dispatch pointer if (vReturn.vt == VT_DISPATCH) { @@ -260,6 +255,16 @@ wxVariant wxAutomationObject::CallMethod(const wxString& member, int noArgs, wxV return retVariant; } +wxVariant wxAutomationObject::CallMethodArray(const wxString& member, int noArgs, const wxVariant **args) +{ + wxVariant retVariant; + if (!Invoke(member, DISPATCH_METHOD, retVariant, noArgs, NULL, args)) + { + retVariant.MakeNull(); + } + return retVariant; +} + wxVariant wxAutomationObject::CallMethod(const wxString& member, const wxVariant& arg1, const wxVariant& arg2, const wxVariant& arg3, const wxVariant& arg4, @@ -307,6 +312,15 @@ wxVariant wxAutomationObject::CallMethod(const wxString& member, } // Get/Set property +wxVariant wxAutomationObject::GetPropertyArray(const wxString& property, int noArgs, const wxVariant **args) const +{ + wxVariant retVariant; + if (!Invoke(property, DISPATCH_PROPERTYGET, retVariant, noArgs, NULL, args)) + { + retVariant.MakeNull(); + } + return retVariant; +} wxVariant wxAutomationObject::GetProperty(const wxString& property, int noArgs, wxVariant args[]) const { wxVariant retVariant; @@ -373,6 +387,16 @@ bool wxAutomationObject::PutProperty(const wxString& property, int noArgs, wxVar return TRUE; } +bool wxAutomationObject::PutPropertyArray(const wxString& property, int noArgs, const wxVariant **args) +{ + wxVariant retVariant; + if (!Invoke(property, DISPATCH_PROPERTYPUT, retVariant, noArgs, NULL, args)) + { + return FALSE; + } + return TRUE; +} + bool wxAutomationObject::PutProperty(const wxString& property, const wxVariant& arg1, const wxVariant& arg2, const wxVariant& arg3, const wxVariant& arg4, @@ -426,19 +450,34 @@ WXIDISPATCH* wxAutomationObject::GetDispatchProperty(const wxString& property, i wxVariant retVariant; if (Invoke(property, DISPATCH_PROPERTYGET, retVariant, noArgs, args)) { - if (retVariant.GetType() == "void*") + if (retVariant.GetType() == wxT("void*")) { return (WXIDISPATCH*) retVariant.GetVoidPtr(); } - else + } + + return (WXIDISPATCH*) NULL; +} + +// Uses DISPATCH_PROPERTYGET +// and returns a dispatch pointer. The calling code should call Release +// on the pointer, though this could be implicit by constructing an wxAutomationObject +// with it and letting the destructor call Release. +WXIDISPATCH* wxAutomationObject::GetDispatchProperty(const wxString& property, int noArgs, const wxVariant **args) const +{ + wxVariant retVariant; + if (Invoke(property, DISPATCH_PROPERTYGET, retVariant, noArgs, NULL, args)) + { + if (retVariant.GetType() == wxT("void*")) { - return (WXIDISPATCH*) NULL; + return (WXIDISPATCH*) retVariant.GetVoidPtr(); } } - else - return (WXIDISPATCH*) NULL; + + return (WXIDISPATCH*) NULL; } + // A way of initialising another wxAutomationObject with a dispatch object bool wxAutomationObject::GetObject(wxAutomationObject& obj, const wxString& property, int noArgs, wxVariant args[]) const { @@ -452,6 +491,19 @@ bool wxAutomationObject::GetObject(wxAutomationObject& obj, const wxString& prop return FALSE; } +// A way of initialising another wxAutomationObject with a dispatch object +bool wxAutomationObject::GetObject(wxAutomationObject& obj, const wxString& property, int noArgs, const wxVariant **args) const +{ + WXIDISPATCH* dispatch = GetDispatchProperty(property, noArgs, args); + if (dispatch) + { + obj.SetDispatchPtr(dispatch); + return TRUE; + } + else + return FALSE; +} + // Get a dispatch pointer from the current object associated // with a class id bool wxAutomationObject::GetInstance(const wxString& classId) const @@ -462,23 +514,23 @@ bool wxAutomationObject::GetInstance(const wxString& classId) const CLSID clsId; IUnknown * pUnk = NULL; - BasicString unicodeName((const char*) classId); + wxBasicString unicodeName(classId.mb_str()); if (FAILED(CLSIDFromProgID((BSTR) unicodeName, &clsId))) { - wxLogWarning("Cannot obtain CLSID from ProgID"); + wxLogWarning(wxT("Cannot obtain CLSID from ProgID")); return FALSE; } if (FAILED(GetActiveObject(clsId, NULL, &pUnk))) { - wxLogWarning("Cannot find an active object"); + wxLogWarning(wxT("Cannot find an active object")); return FALSE; } if (pUnk->QueryInterface(IID_IDispatch, (LPVOID*) &m_dispatchPtr) != S_OK) { - wxLogWarning("Cannot find IDispatch interface"); + wxLogWarning(wxT("Cannot find IDispatch interface")); return FALSE; } @@ -493,20 +545,19 @@ bool wxAutomationObject::CreateInstance(const wxString& classId) const return FALSE; CLSID clsId; - IUnknown * pUnk = NULL; - BasicString unicodeName((const char*) classId); + wxBasicString unicodeName(classId.mb_str()); if (FAILED(CLSIDFromProgID((BSTR) unicodeName, &clsId))) { - wxLogWarning("Cannot obtain CLSID from ProgID"); + wxLogWarning(wxT("Cannot obtain CLSID from ProgID")); 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))) { - wxLogWarning("Cannot start an instance of this class."); + wxLogWarning(wxT("Cannot start an instance of this class.")); return FALSE; } @@ -514,7 +565,7 @@ bool wxAutomationObject::CreateInstance(const wxString& classId) const } -bool ConvertVariantToOle(const wxVariant& variant, VARIANTARG& oleVariant) +bool wxConvertVariantToOle(const wxVariant& variant, VARIANTARG& oleVariant) { ClearVariant(&oleVariant); if (variant.IsNull()) @@ -525,17 +576,26 @@ bool ConvertVariantToOle(const wxVariant& variant, VARIANTARG& oleVariant) wxString type(variant.GetType()); - if (type == "long") + + if (type == wxT("long")) { oleVariant.vt = VT_I4; oleVariant.lVal = variant.GetLong() ; } - else if (type == "double") + // 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 == "bool") + else if (type == wxT("bool")) { oleVariant.vt = VT_BOOL; // 'bool' required for VC++ 4 apparently @@ -545,13 +605,16 @@ bool ConvertVariantToOle(const wxVariant& variant, VARIANTARG& oleVariant) oleVariant.boolVal = variant.GetBool(); #endif } - else if (type == "string") + else if (type == wxT("string")) { wxString str( variant.GetString() ); oleVariant.vt = VT_BSTR; - oleVariant.bstrVal = ConvertStringToOle(str); + oleVariant.bstrVal = wxConvertStringToOle(str); } - else if (type == "date") +// For some reason, Watcom C++ can't link variant.cpp with time/date classes compiled +// Now obsolete +#if 0 // wxUSE_TIMEDATE && !defined(__WATCOMC__) + else if (type == wxT("date")) { wxDate date( variant.GetDate() ); oleVariant.vt = VT_DATE; @@ -560,7 +623,7 @@ bool ConvertVariantToOle(const wxVariant& variant, VARIANTARG& oleVariant) 0, 0, 0, oleVariant.date)) return FALSE; } - else if (type == "time") + else if (type == wxT("time")) { wxTime time( variant.GetTime() ); oleVariant.vt = VT_DATE; @@ -569,12 +632,24 @@ bool ConvertVariantToOle(const wxVariant& variant, VARIANTARG& oleVariant) time.GetHour(), time.GetMinute(), time.GetSecond(), oleVariant.date)) return FALSE; } - else if (type == "void*") +#endif +#if wxUSE_DATETIME + else if (type == wxT("datetime")) + { + wxDateTime date( variant.GetDateTime() ); + oleVariant.vt = VT_DATE; + + if (!OleDateFromTm(date.GetYear(), date.GetMonth(), date.GetDay(), + date.GetHour(), date.GetMinute(), date.GetSecond(), oleVariant.date)) + return FALSE; + } +#endif + else if (type == wxT("void*")) { oleVariant.vt = VT_DISPATCH; oleVariant.pdispVal = (IDispatch*) variant.GetVoidPtr(); } - else if (type == "list" || type == "stringlist") + else if (type == wxT("list") || type == wxT("stringlist")) { oleVariant.vt = VT_VARIANT | VT_ARRAY; @@ -600,7 +675,7 @@ bool ConvertVariantToOle(const wxVariant& variant, VARIANTARG& oleVariant) { // copy each string in the list of strings wxVariant eachVariant(variant[i]); - if (!ConvertVariantToOle(eachVariant, * pvarg)) + if (!wxConvertVariantToOle(eachVariant, * pvarg)) { // memory failure: back out and free strings alloc'ed up to // now, and then the array itself. @@ -632,27 +707,29 @@ bool ConvertVariantToOle(const wxVariant& variant, VARIANTARG& oleVariant) #define VT_TYPEMASK 0xfff #endif -bool ConvertOleToVariant(const VARIANTARG& oleVariant, wxVariant& variant) +bool wxConvertOleToVariant(const VARIANTARG& oleVariant, wxVariant& variant) { switch (oleVariant.vt & VT_TYPEMASK) { case VT_BSTR: { - wxString str(ConvertStringFromOle(oleVariant.bstrVal)); + wxString str(wxConvertStringFromOle(oleVariant.bstrVal)); variant = str; break; } case VT_DATE: { - struct tm tmTemp; +#if wxUSE_DATETIME + struct tm tmTemp; if (!TmFromOleDate(oleVariant.date, tmTemp)) return FALSE; - wxDate date(tmTemp.tm_yday, tmTemp.tm_mon, tmTemp.tm_year); - wxTime time(date, tmTemp.tm_hour, tmTemp.tm_min, tmTemp.tm_sec); + wxDateTime date(tmTemp.tm_yday, (wxDateTime::Month) tmTemp.tm_mon, tmTemp.tm_year, tmTemp.tm_hour, tmTemp.tm_min, tmTemp.tm_sec); - variant = time; - break; + variant = date; +#endif + + break; } case VT_I4: { @@ -667,14 +744,18 @@ bool ConvertOleToVariant(const VARIANTARG& oleVariant, wxVariant& variant) case VT_BOOL: { -#if defined(__WATCOMC__) || (defined(_MSC_VER) && (_MSC_VER <= 1000)) //GC +#if defined(__WATCOMC__) || (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; } @@ -704,7 +785,7 @@ bool ConvertOleToVariant(const VARIANTARG& oleVariant, wxVariant& variant) { VARIANTARG& oleElement = pvdata[i]; wxVariant vElement; - if (!ConvertOleToVariant(oleElement, vElement)) + if (!wxConvertOleToVariant(oleElement, vElement)) return FALSE; variant.Append(vElement); @@ -728,14 +809,14 @@ bool ConvertOleToVariant(const VARIANTARG& oleVariant, wxVariant& variant) } default: { - wxLogError("wxAutomationObject::ConvertOleToVariant: Unknown variant value type"); + wxLogError(wxT("wxAutomationObject::ConvertOleToVariant: Unknown variant value type")); return FALSE; } } return TRUE; } -static BSTR ConvertStringToOle(const wxString& str) +BSTR wxConvertStringToOle(const wxString& str) { /* unsigned int len = strlen((const char*) str); @@ -745,48 +826,69 @@ static BSTR ConvertStringToOle(const wxString& str) for (i=0; i < len; i++) s[i*2] = str[i]; */ - BasicString bstr((const char*) str); + wxBasicString bstr(str.mb_str()); return bstr.Get(); } -static wxString ConvertStringFromOle(BSTR bStr) +wxString wxConvertStringFromOle(BSTR bStr) { +#if wxUSE_UNICODE + wxString str(bStr); +#else int len = SysStringLen(bStr) + 1; char *buf = new char[len]; - int i = wcstombs( buf, bStr, len); - - wxString str(buf); + (void)wcstombs( buf, bStr, len); + wxString str(buf); delete[] buf; +#endif return str; } // ---------------------------------------------------------------------------- -// BasicString +// wxBasicString // ---------------------------------------------------------------------------- // ctor takes an ANSI string and transforms it to Unicode -BasicString::BasicString(const char *sz) +wxBasicString::wxBasicString(const char *sz) { - // get the size of required buffer - UINT lenAnsi = strlen(sz); - #ifdef __MWERKS__ - UINT lenWide = lenAnsi * 2 ; - #else - UINT lenWide = mbstowcs(NULL, sz, lenAnsi); - #endif - - if ( lenWide > 0 ) { - m_wzBuf = new OLECHAR[lenWide + 1]; - mbstowcs(m_wzBuf, sz, lenAnsi); - m_wzBuf[lenWide] = L'\0'; - } - else { - m_wzBuf = NULL; - } + Init(sz); +} + +// ctor takes an ANSI or Unicode string and transforms it to Unicode +wxBasicString::wxBasicString(const wxString& str) +{ +#if wxUSE_UNICODE + m_wzBuf = new OLECHAR[str.Length() + 1]; + memcpy(m_wzBuf, str.c_str(), str.Length()*2); + m_wzBuf[str.Length()] = L'\0'; +#else + Init(str.c_str()); +#endif +} + +// Takes an ANSI string and transforms it to Unicode +void wxBasicString::Init(const char *sz) +{ + // get the size of required buffer + UINT lenAnsi = strlen(sz); +#ifdef __MWERKS__ + UINT lenWide = lenAnsi * 2 ; +#else + UINT lenWide = mbstowcs(NULL, sz, lenAnsi); +#endif + + if ( lenWide > 0 ) { + m_wzBuf = new OLECHAR[lenWide + 1]; + mbstowcs(m_wzBuf, sz, lenAnsi); + m_wzBuf[lenWide] = L'\0'; + } + else { + m_wzBuf = NULL; + } } // dtor frees memory -BasicString::~BasicString() +wxBasicString::~wxBasicString() { delete [] m_wzBuf; } @@ -847,7 +949,6 @@ BOOL TmFromOleDate(DATE dtSrc, struct tm& tmDest) if (dtSrc > MAX_DATE || dtSrc < MIN_DATE) // about year 100 to about 9999 return FALSE; - long nDays; // Number of days since Dec. 30, 1899 long nDaysAbsolute; // Number of days since 1/1/0 long nSecsInDay; // Time in seconds since midnight long nMinutesInDay; // Minutes in day @@ -862,9 +963,6 @@ BOOL TmFromOleDate(DATE dtSrc, struct tm& tmDest) double dblDate = dtSrc; // tempory serial date - // If a valid date, then this conversion should not overflow - nDays = (long)dblDate; - // Round to the second dblDate += ((dtSrc > 0.0) ? HALF_SECOND : -HALF_SECOND); @@ -969,6 +1067,8 @@ DoTime: return TRUE; } +// this function is not used +#if 0 void TmConvertToStandardFormat(struct tm& tmSrc) { // Convert afx internal tm to format expected by runtimes (_tcsftime, etc) @@ -1001,6 +1101,7 @@ DATE DateFromDouble(double dbl) double temp = floor(dbl); // dbl is now whole part return temp + (temp - dbl); } +#endif // 0 /* * ClearVariant @@ -1058,7 +1159,7 @@ static void ReleaseVariant(VARIANTARG *pvarg) } else { - wxLogWarning("ReleaseVariant: Array contains non-variant type"); + wxLogWarning(wxT("ReleaseVariant: Array contains non-variant type")); } // Free the array itself. @@ -1085,7 +1186,7 @@ static void ReleaseVariant(VARIANTARG *pvarg) break; default: - wxLogWarning("ReleaseVariant: Unknown type"); + wxLogWarning(wxT("ReleaseVariant: Unknown type")); break; } } @@ -1156,3 +1257,5 @@ void ShowException(LPOLESTR szMember, HRESULT hr, EXCEPINFO *pexcep, unsigned in #endif +#endif // __WATCOMC__ +