X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/afd23c224adf19f62353d8ec309db91747cbf237..ce7208d49d5ce2ca1dc0b3b83f14f1d04f29c4bf:/src/msw/ole/automtn.cpp diff --git a/src/msw/ole/automtn.cpp b/src/msw/ole/automtn.cpp index e4114afd26..ac86d8782e 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: @@ -9,31 +9,31 @@ // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) -#pragma implementation "automtn.h" -#endif - // For compilers that support precompilation, includes "wx.h". #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 + +#if wxUSE_OLE_AUTOMATION + +#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 - #ifdef __WXWINCE__ #include "wx/msw/wince/time.h" #else @@ -52,24 +52,8 @@ #include -// Verifies will fail if the needed buffer size is too large -#define MAX_TIME_BUFFER_SIZE 128 // matches that in timecore.cpp -#define MIN_DATE (-657434L) // about year 100 -#define MAX_DATE 2958465L // about year 9999 - -// Half a second, expressed in days -#define HALF_SECOND (1.0/172800.0) - -// One-based array of days in year at month start -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); #endif // wxUSE_TIMEDATE static void ClearVariant(VARIANTARG *pvarg) ; @@ -111,7 +95,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; @@ -200,7 +184,7 @@ bool wxAutomationObject::Invoke(const wxString& member, int action, excep.pfnDeferredFillIn = NULL; hr = ((IDispatch*)m_dispatchPtr)->Invoke(dispIds[0], IID_NULL, LOCALE_SYSTEM_DEFAULT, - action, &dispparams, vReturnPtr, &excep, &uiArgErr); + (WORD)action, &dispparams, vReturnPtr, &excep, &uiArgErr); for (i = 0; i < namedArgStringCount; i++) { @@ -565,7 +549,7 @@ bool wxAutomationObject::CreateInstance(const wxString& classId) const } -bool wxConvertVariantToOle(const wxVariant& variant, VARIANTARG& oleVariant) +WXDLLEXPORT bool wxConvertVariantToOle(const wxVariant& variant, VARIANTARG& oleVariant) { ClearVariant(&oleVariant); if (variant.IsNull()) @@ -617,9 +601,11 @@ bool wxConvertVariantToOle(const wxVariant& variant, VARIANTARG& oleVariant) 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; + long dosDateTime = date.GetAsDOS(); + short dosDate = short((dosDateTime & 0xFFFF0000) >> 16); + short dosTime = short(dosDateTime & 0xFFFF); + + DosDateTimeToVariantTime(dosDate, dosTime, & oleVariant.date); } #endif else if (type == wxT("void*")) @@ -685,7 +671,7 @@ bool wxConvertVariantToOle(const wxVariant& variant, VARIANTARG& oleVariant) #define VT_TYPEMASK 0xfff #endif -bool wxConvertOleToVariant(const VARIANTARG& oleVariant, wxVariant& variant) +WXDLLEXPORT bool wxConvertOleToVariant(const VARIANTARG& oleVariant, wxVariant& variant) { switch (oleVariant.vt & VT_TYPEMASK) { @@ -698,15 +684,15 @@ bool wxConvertOleToVariant(const VARIANTARG& oleVariant, wxVariant& variant) case VT_DATE: { #if wxUSE_DATETIME - struct tm tmTemp; - if (!TmFromOleDate(oleVariant.date, tmTemp)) - return false; - - wxDateTime date(tmTemp.tm_yday, (wxDateTime::Month) tmTemp.tm_mon, tmTemp.tm_year, tmTemp.tm_hour, tmTemp.tm_min, tmTemp.tm_sec); + 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: @@ -794,294 +780,6 @@ bool wxConvertOleToVariant(const VARIANTARG& oleVariant, wxVariant& variant) return true; } -BSTR wxConvertStringToOle(const wxString& str) -{ -/* - unsigned int len = strlen((const char*) str); - unsigned short* s = new unsigned short[len*2+2]; - unsigned int i; - memset(s, 0, len*2+2); - for (i=0; i < len; i++) - s[i*2] = str[i]; -*/ - wxBasicString bstr(str.mb_str()); - return bstr.Get(); -} - -wxString wxConvertStringFromOle(BSTR bStr) -{ -#if wxUSE_UNICODE - wxString str(bStr); -#else - int len = SysStringLen(bStr) + 1; - char *buf = new char[len]; - (void)wcstombs( buf, bStr, len); - wxString str(buf); - delete[] buf; -#endif - return str; -} - -// ---------------------------------------------------------------------------- -// wxBasicString -// ---------------------------------------------------------------------------- - -// ctor takes an ANSI string and transforms it to Unicode -wxBasicString::wxBasicString(const char *sz) -{ - 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 -wxBasicString::~wxBasicString() -{ - delete [] m_wzBuf; -} - -///////////////////////////////////////////////////////////////////////////// -// COleDateTime class HELPERS - implementation - -BOOL OleDateFromTm(WORD wYear, WORD wMonth, WORD wDay, - WORD wHour, WORD wMinute, WORD wSecond, DATE& dtDest) -{ - // Validate year and month (ignore day of week and milliseconds) - if (wYear > 9999 || wMonth < 1 || wMonth > 12) - return FALSE; - - // Check for leap year and set the number of days in the month - BOOL bLeapYear = ((wYear & 3) == 0) && - ((wYear % 100) != 0 || (wYear % 400) == 0); - - int nDaysInMonth = - rgMonthDays[wMonth] - rgMonthDays[wMonth-1] + - ((bLeapYear && wDay == 29 && wMonth == 2) ? 1 : 0); - - // Finish validating the date - if (wDay < 1 || wDay > nDaysInMonth || - wHour > 23 || wMinute > 59 || - wSecond > 59) - { - return FALSE; - } - - // Cache the date in days and time in fractional days - long nDate; - double dblTime; - - //It is a valid date; make Jan 1, 1AD be 1 - nDate = wYear*365L + wYear/4 - wYear/100 + wYear/400 + - rgMonthDays[wMonth-1] + wDay; - - // If leap year and it's before March, subtract 1: - if (wMonth <= 2 && bLeapYear) - --nDate; - - // Offset so that 12/30/1899 is 0 - nDate -= 693959L; - - dblTime = (((long)wHour * 3600L) + // hrs in seconds - ((long)wMinute * 60L) + // mins in seconds - ((long)wSecond)) / 86400.; - - dtDest = (double) nDate + ((nDate >= 0) ? dblTime : -dblTime); - - return TRUE; -} - -BOOL TmFromOleDate(DATE dtSrc, struct tm& tmDest) -{ - // The legal range does not actually span year 0 to 9999. - if (dtSrc > MAX_DATE || dtSrc < MIN_DATE) // about year 100 to about 9999 - return FALSE; - - long nDaysAbsolute; // Number of days since 1/1/0 - long nSecsInDay; // Time in seconds since midnight - long nMinutesInDay; // Minutes in day - - long n400Years; // Number of 400 year increments since 1/1/0 - long n400Century; // Century within 400 year block (0,1,2 or 3) - long n4Years; // Number of 4 year increments since 1/1/0 - long n4Day; // Day within 4 year block - // (0 is 1/1/yr1, 1460 is 12/31/yr4) - long n4Yr; // Year within 4 year block (0,1,2 or 3) - BOOL bLeap4 = TRUE; // TRUE if 4 year block includes leap year - - double dblDate = dtSrc; // tempory serial date - - // Round to the second - dblDate += ((dtSrc > 0.0) ? HALF_SECOND : -HALF_SECOND); - - nDaysAbsolute = (long)dblDate + 693959L; // Add days from 1/1/0 to 12/30/1899 - - dblDate = fabs(dblDate); - nSecsInDay = (long)((dblDate - floor(dblDate)) * 86400.); - - // Calculate the day of week (sun=1, mon=2...) - // -1 because 1/1/0 is Sat. +1 because we want 1-based - tmDest.tm_wday = (int)((nDaysAbsolute - 1) % 7L) + 1; - - // Leap years every 4 yrs except centuries not multiples of 400. - n400Years = (long)(nDaysAbsolute / 146097L); - - // Set nDaysAbsolute to day within 400-year block - nDaysAbsolute %= 146097L; - - // -1 because first century has extra day - n400Century = (long)((nDaysAbsolute - 1) / 36524L); - - // Non-leap century - if (n400Century != 0) - { - // Set nDaysAbsolute to day within century - nDaysAbsolute = (nDaysAbsolute - 1) % 36524L; - - // +1 because 1st 4 year increment has 1460 days - n4Years = (long)((nDaysAbsolute + 1) / 1461L); - - if (n4Years != 0) - n4Day = (long)((nDaysAbsolute + 1) % 1461L); - else - { - bLeap4 = FALSE; - n4Day = (long)nDaysAbsolute; - } - } - else - { - // Leap century - not special case! - n4Years = (long)(nDaysAbsolute / 1461L); - n4Day = (long)(nDaysAbsolute % 1461L); - } - - if (bLeap4) - { - // -1 because first year has 366 days - n4Yr = (n4Day - 1) / 365; - - if (n4Yr != 0) - n4Day = (n4Day - 1) % 365; - } - else - { - n4Yr = n4Day / 365; - n4Day %= 365; - } - - // n4Day is now 0-based day of year. Save 1-based day of year, year number - tmDest.tm_yday = (int)n4Day + 1; - tmDest.tm_year = n400Years * 400 + n400Century * 100 + n4Years * 4 + n4Yr; - - // Handle leap year: before, on, and after Feb. 29. - if (n4Yr == 0 && bLeap4) - { - // Leap Year - if (n4Day == 59) - { - /* Feb. 29 */ - tmDest.tm_mon = 2; - tmDest.tm_mday = 29; - goto DoTime; - } - - // Pretend it's not a leap year for month/day comp. - if (n4Day >= 60) - --n4Day; - } - - // Make n4DaY a 1-based day of non-leap year and compute - // month/day for everything but Feb. 29. - ++n4Day; - - // Month number always >= n/32, so save some loop time */ - for (tmDest.tm_mon = (n4Day >> 5) + 1; - n4Day > rgMonthDays[tmDest.tm_mon]; tmDest.tm_mon++) - ; - - tmDest.tm_mday = (int)(n4Day - rgMonthDays[tmDest.tm_mon-1]); - -DoTime: - if (nSecsInDay == 0) - tmDest.tm_hour = tmDest.tm_min = tmDest.tm_sec = 0; - else - { - tmDest.tm_sec = (int)nSecsInDay % 60L; - nMinutesInDay = nSecsInDay / 60L; - tmDest.tm_min = (int)nMinutesInDay % 60; - tmDest.tm_hour = (int)nMinutesInDay / 60; - } - - 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) - tmSrc.tm_year -= 1900; // year is based on 1900 - tmSrc.tm_mon -= 1; // month of year is 0-based - tmSrc.tm_wday -= 1; // day of week is 0-based - tmSrc.tm_yday -= 1; // day of year is 0-based -} - -double DoubleFromDate(DATE dt) -{ - // No problem if positive - if (dt >= 0) - return dt; - - // If negative, must convert since negative dates not continuous - // (examples: -1.25 to -.75, -1.50 to -.50, -1.75 to -.25) - double temp = ceil(dt); - return temp - (dt - temp); -} - -DATE DateFromDouble(double dbl) -{ - // No problem if positive - if (dbl >= 0) - return dbl; - - // If negative, must convert since negative dates not continuous - // (examples: -.75 to -1.25, -.50 to -1.50, -.25 to -1.75) - double temp = floor(dbl); // dbl is now whole part - return temp + (temp - dbl); -} -#endif // 0 - /* * ClearVariant * @@ -1108,7 +806,7 @@ static void ReleaseVariant(VARIANTARG *pvarg) VARIANTARG _huge *pvargArray; long lLBound, lUBound, l; - vt = pvarg->vt & 0xfff; // mask off flags + 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)) @@ -1158,9 +856,11 @@ static void ReleaseVariant(VARIANTARG *pvarg) 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: // no work for these types break; @@ -1227,7 +927,7 @@ void ShowException(LPOLESTR szMember, HRESULT hr, EXCEPINFO *pexcep, unsigned in break; default: - wsprintf(szBuf, L"%s: Unknown error occured.", szMember); + wsprintf(szBuf, L"%s: Unknown error occurred.", szMember); break; } @@ -1236,5 +936,4 @@ void ShowException(LPOLESTR szMember, HRESULT hr, EXCEPINFO *pexcep, unsigned in #endif -#endif // wxUSE_OLE && !(defined(__BORLANDC__) && (__BORLANDC__ < 0x520)) && !defined(__CYGWIN10__) - +#endif // wxUSE_OLE_AUTOMATION