/** * @file XTPCalendarUtils.cpp * * @copyright * (c) 1998-2025 Codejock Software, All Rights Reserved. * * This source file is the property of Codejock Software and must not be * redistributed by any means without the explicit written permission of * Codejock Software. * * The use of this source code is governed by the terms and conditions specified * in the Toolkit Pro license agreement. Codejock Software grants you, as a * single software developer, the limited right to use this software on one * computer only. * * Contact Information: * support@codejock.com * http://www.codejock.com * */ #include "stdafx.h" #include "Common/Base/Diagnostic/XTPDisableAdvancedWarnings.h" #include #include "Common/Base/Diagnostic/XTPEnableAdvancedWarnings.h" #include "Calendar/Resource.h" #include "Common/XTPTypeId.h" #include "Common/XTPCasting.h" #include "Common/XTPFramework.h" #include "Common/XTPSystemHelpers.h" #include "Common/XTPSynchro.h" #include "Common/XTPApplication.h" #include "Common/XTPSingleton.h" #include "Common/XTPGdiObjects.h" #include "Common/XTPResourceManager.h" #include "Common/XTPSmartPtrInternalT.h" #include "Common/XTPDrawHelpers.h" #include "Calendar/XTPCalendarDefines.h" #include "Calendar/XTPCalendarUtils.h" #include "Calendar/XTPCalendarEvent.h" #include "Common/Base/Diagnostic/XTPDisableNoisyWarnings.h" #ifdef _DEBUG # undef THIS_FILE static char THIS_FILE[] = __FILE__; # define new DEBUG_NEW #endif #ifndef LOCALE_SSHORTESTDAYNAME1 # define LOCALE_SSHORTESTDAYNAME1 0x00000060 // Shortest day name for Monday # define LOCALE_SSHORTESTDAYNAME2 0x00000061 // Shortest day name for Tuesday # define LOCALE_SSHORTESTDAYNAME3 0x00000062 // Shortest day name for Wednesday # define LOCALE_SSHORTESTDAYNAME4 0x00000063 // Shortest day name for Thursday # define LOCALE_SSHORTESTDAYNAME5 0x00000064 // Shortest day name for Friday # define LOCALE_SSHORTESTDAYNAME6 0x00000065 // Shortest day name for Saturday # define LOCALE_SSHORTESTDAYNAME7 0x00000066 // Shortest day name for Sunday #endif //////////////////////////////////////////////////////////////////////////// LCID CXTPCalendarUtils::GetActiveLCID() { return XTPResourceManager()->GetActiveLCID(); } //////////////////////////////////////////////////////////////////////////// CXTPCalendarUtils::CXTPCalendarUtils() { } int CXTPCalendarUtils::GetLocaleLong(LCTYPE LCType) { TCHAR szResult[5]; int nResult = ::GetLocaleInfo(GetActiveLCID(), LCType, szResult, 4); _ASSERTE(nResult == 2); UNUSED(nResult); return _ttoi(szResult); } CString CXTPCalendarUtils::GetLocaleString(LCTYPE LCType, int nMaxLength) { CString strResult; int nResult = ::GetLocaleInfo(GetActiveLCID(), LCType, strResult.GetBufferSetLength(nMaxLength), nMaxLength); strResult.ReleaseBuffer(); _ASSERTE(strResult.GetLength() == nResult - 1); UNUSED(nResult); return strResult; } CString CXTPCalendarUtils::GetDateFormat(CONST SYSTEMTIME* lpDate, LPCTSTR lpFormat) { CString strResult; int nResult = ::GetDateFormat(GetActiveLCID(), 0, lpDate, lpFormat, strResult.GetBufferSetLength(255), 255); strResult.ReleaseBuffer(); _ASSERTE(strResult.GetLength() == nResult - 1 || strResult.GetLength() == 0); UNUSED(nResult); return strResult; } CString CXTPCalendarUtils::GetTimeFormat(CONST SYSTEMTIME* lpTime, LPCTSTR lpFormat) { CString strResult; int nResult = ::GetTimeFormat(GetActiveLCID(), 0, lpTime, lpFormat, strResult.GetBufferSetLength(255), 255); strResult.ReleaseBuffer(); _ASSERTE(strResult.GetLength() == nResult - 1); UNUSED(nResult); if (strResult.IsEmpty()) { SYSTEMTIME MySystemTime; MySystemTime = *lpTime; CString s, t; s.Format(_T("%d"), MySystemTime.wYear); MySystemTime.wYear += 2000; t.Format(_T("%d"), MySystemTime.wYear); nResult = ::GetTimeFormat(GetActiveLCID(), 0, &MySystemTime, lpFormat, strResult.GetBufferSetLength(255), 255); strResult.ReleaseBuffer(); _ASSERTE(strResult.GetLength() == nResult - 1); UNUSED(nResult); strResult.Replace(t, s); } return strResult; } CString CXTPCalendarUtils::GetDateFormat(CONST COleDateTime& dtDate, LPCTSTR lpFormat) { SYSTEMTIME stDate; if (dtDate.GetYear() <= 1601 || (dtDate.GetYear() == 1601 && dtDate.GetMonth() <= 4)) { COleDateTime dtFutureDay(dtDate); dtFutureDay.SetDate(dtFutureDay.GetYear() + 2000, dtFutureDay.GetMonth(), dtFutureDay.GetDay()); CXTPCalendarUtils::GetAsSystemTime(dtFutureDay, stDate); CString sResult = GetDateFormat(&stDate, lpFormat); LCID nLocale = GetActiveLCID(); if (nLocale == LOCALE_USER_DEFAULT) nLocale = GetUserDefaultLCID(); // Special Thailand calendar Offset int nYearOffset = PRIMARYLANGID(LANGIDFROMLCID(nLocale)) == LANG_THAI ? 543 : 0; CString s, t; s.Format(_T("%d"), dtDate.GetYear() + nYearOffset); t.Format(_T("%d"), dtFutureDay.GetYear() + nYearOffset); sResult.Replace(t, s); return sResult; } else { CXTPCalendarUtils::GetAsSystemTime(dtDate, stDate); return GetDateFormat(&stDate, lpFormat); } } CString CXTPCalendarUtils::GetTimeFormat(CONST COleDateTime& dtTime, LPCTSTR lpFormat) { SYSTEMTIME stTime; CXTPCalendarUtils::GetAsSystemTime(dtTime, stTime); return GetTimeFormat(&stTime, lpFormat); } CString CXTPCalendarUtils::GetTimeFormat(int nHour, int nMinutes, LPCTSTR lpFormat) { SYSTEMTIME stTime; ::ZeroMemory(&stTime, sizeof(stTime)); stTime.wHour = (WORD)nHour; stTime.wMinute = (WORD)nMinutes; return GetTimeFormat(&stTime, lpFormat); } ///*** COleDateTime CXTPCalendarUtils::RetriveEventEndDate(const CXTPCalendarEvent* pEvent) { if (!pEvent) { _ASSERTE(FALSE); return COleDateTime((DATE)0); } COleDateTime dtStartDay = ResetTime(pEvent->GetStartTime()); COleDateTime dtEndDay = ResetTime(pEvent->GetEndTime()); if (IsZeroTime(pEvent->GetEndTime()) && dtStartDay < dtEndDay) { dtEndDay -= COleDateTimeSpan(1, 0, 0, 0); } return dtEndDay; } BOOL CXTPCalendarUtils::CalcDayOfMonth(COleDateTime& rdtDate, int nWhichDay, int nWhichDayMask) { _ASSERTE(nWhichDay >= xtpCalendarWeekFirst && nWhichDay <= xtpCalendarWeekLast); _ASSERTE((nWhichDayMask & (~xtpCalendarDayAllWeek)) == 0); COleDateTime dtYMD; dtYMD.SetDate(rdtDate.GetYear(), rdtDate.GetMonth(), 1); COleDateTimeSpan spStep(nWhichDay == xtpCalendarWeekLast ? -1 : 1, 0, 0, 0); if (nWhichDay == xtpCalendarWeekLast) { CXTPCalendarUtils::ShiftDate_Month(dtYMD, 1); COleDateTimeSpan spInitStep(-1, 0, 0, 0); dtYMD += spInitStep; } int nFCount = nWhichDay == xtpCalendarWeekLast ? xtpCalendarWeekLast - 1 : xtpCalendarWeekFirst - 1; for (int i = 0; i < 31; i++) { int nWD = dtYMD.GetDayOfWeek(); int nWDMask = CXTPCalendarUtils::GetDayOfWeekMask(nWD); if (nWhichDayMask & nWDMask) { nFCount++; if (nFCount == nWhichDay) { rdtDate = dtYMD; return TRUE; } } dtYMD += spStep; } _ASSERTE(FALSE); return FALSE; } int CXTPCalendarUtils::GetWeekOfYear(COleDateTime dtDate, int nFirstDayOfWeekIndex) { COleDateTime dtFirst(dtDate.GetYear(), 1, 1, 0, 0, 0); COleDateTime dtFirstWeekDate = ShiftDateToWeekBegin(dtFirst, nFirstDayOfWeekIndex); COleDateTimeSpan spDiff = dtDate - dtFirstWeekDate; int nDayOfYear = (int)spDiff.GetTotalDays(); int nWeek = nDayOfYear / 7 + 1; return nWeek; } BOOL CXTPCalendarUtils::IsWin9x() { return XTPSystemVersion()->IsWin9x(); } BOOL CXTPCalendarUtils::SystemTimeToTzSpecificLocalTime(const TIME_ZONE_INFORMATION* pTZI, const SYSTEMTIME* pUTime, SYSTEMTIME* pTzTime) { if (!pTZI || !pUTime || !pTzTime) { _ASSERTE(FALSE); return FALSE; } if (!CXTPCalendarUtils::IsWin9x()) { return ::SystemTimeToTzSpecificLocalTime((TIME_ZONE_INFORMATION*)pTZI, (SYSTEMTIME*)pUTime, pTzTime); } //--------------------------------------------------------------------------- COleDateTime dtUTime(*pUTime); COleDateTime dtTzTime = dtUTime; int nBias_min = pTZI->Bias; if (pTZI->StandardDate.wMonth) { nBias_min += pTZI->StandardBias; } BOOL bDayLight = FALSE; int nDLBias_min = 0; if (pTZI->DaylightDate.wMonth != 0 && pTZI->DaylightBias != 0) { bDayLight = TRUE; nDLBias_min = (pTZI->DaylightBias - pTZI->StandardBias); } dtTzTime = dtUTime - Minutes2Span(nBias_min); if (bDayLight && IsInDst(pTZI, dtTzTime)) { dtTzTime -= Minutes2Span(nDLBias_min); } return CXTPCalendarUtils::GetAsSystemTime(dtTzTime, *pTzTime); } BOOL CXTPCalendarUtils::IsInDst(const TIME_ZONE_INFORMATION* pTZI, COleDateTime dtTime) { if (pTZI->StandardDate.wMonth == 0 || pTZI->DaylightDate.wMonth == 0 || pTZI->DaylightBias == 0) { return FALSE; } COleDateTime dtStandard(dtTime.GetYear(), pTZI->StandardDate.wMonth, 1, pTZI->StandardDate.wHour, pTZI->StandardDate.wMinute, pTZI->StandardDate.wSecond); COleDateTime dtDaylight(dtTime.GetYear(), pTZI->DaylightDate.wMonth, 1, pTZI->DaylightDate.wHour, pTZI->DaylightDate.wMinute, pTZI->DaylightDate.wSecond); BOOL bRes1 = CalcDayOfMonth(dtStandard, pTZI->StandardDate.wDay, GetDayOfWeekMask(pTZI->StandardDate.wDayOfWeek + 1)); BOOL bRes2 = CalcDayOfMonth(dtDaylight, pTZI->DaylightDate.wDay, GetDayOfWeekMask(pTZI->DaylightDate.wDayOfWeek + 1)); if (!bRes1 || !bRes2) { _ASSERTE(FALSE); return FALSE; } if (dtStandard < dtDaylight) { if (dtTime >= dtDaylight || dtTime < dtStandard) { return TRUE; } } else { if (dtTime >= dtDaylight && dtTime < dtStandard) { return TRUE; } } return FALSE; } class DefaultTimeProvider : ITimeProvider { public: virtual COleDateTime GetCurrentTime() { SYSTEMTIME st; ::ZeroMemory(&st, sizeof(st)); ::GetLocalTime(&st); COleDateTime dtNow(st); return dtNow; } }; ITimeProvider* CXTPCalendarUtils::g_TimeProviderOverride = NULL; COleDateTime CXTPCalendarUtils::GetCurrentTime() { static DefaultTimeProvider g_defaultTimeProvider; if (g_TimeProviderOverride != NULL) return g_TimeProviderOverride->GetCurrentTime(); else return g_defaultTimeProvider.GetCurrentTime(); } void CXTPCalendarUtils::OverrideTimeProvider(ITimeProvider* pTimeProvider) { g_TimeProviderOverride = pTimeProvider; } void CXTPCalendarUtils::ResetTimeProvider() { g_TimeProviderOverride = NULL; } CString CXTPCalendarUtils::GetTimeFormatString_HrMin() { //////////////////////////////////////////////////////////////////////////// // LOCALE_STIME // time separator // // LOCALE_ITLZERO //leading zeros in time field // 0 No leading zeros for hours. // 1 Leading zeros for hours. // // LOCALE_ITIME // time format specifier // 0 AM / PM 12-hour format. // 1 24-hour format. // // LOCALE_ITIMEMARKPOSN // time marker position // 0 Use as suffix. // 1 Use as prefix. // // LOCALE_S1159 // AM designator // LOCALE_S2359 // PM designator //////////////////////////////////////////////////////////////////////////// CString strTmp; CString strTimeSeparator = CXTPCalendarUtils::GetLocaleString(LOCALE_STIME, 16); strTmp = CXTPCalendarUtils::GetLocaleString(LOCALE_ITIME, 16); BOOL b24_HFormat = _ttoi(strTmp) == 1; strTmp = CXTPCalendarUtils::GetLocaleString(LOCALE_ITLZERO, 16); BOOL bH_LZero = _ttoi(strTmp) == 1; strTmp = CXTPCalendarUtils::GetLocaleString(LOCALE_ITIMEMARKPOSN, 16); BOOL bAM_PM_Prefix = _ttoi(strTmp) == 1; //--------------------------------------------------------------------------- CString strTimeFormat; strTimeFormat += strTimeSeparator; strTimeFormat += _T("mm"); if (b24_HFormat) { strTmp = bH_LZero ? _T("HH") : _T("H"); strTimeFormat = strTmp + strTimeFormat; } else // 12 AM/PM Format { strTmp = bH_LZero ? _T("hh") : _T("h"); strTimeFormat = strTmp + strTimeFormat; if (bAM_PM_Prefix) { strTimeFormat = _T("tt ") + strTimeFormat; } else { strTimeFormat = strTimeFormat + _T(" tt"); } } //--------------------------------------------------------------------------- return strTimeFormat; } int CXTPCalendarUtils::ParceTimeString_min(LPCTSTR pcszTime_HrMin) { CString strTime = pcszTime_HrMin; strTime.TrimLeft(); strTime.TrimRight(); CString strPM = CXTPCalendarUtils::GetLocaleString(LOCALE_S2359, 20); strPM.MakeUpper(); strTime.MakeUpper(); // By default Am, or 24 hr format. BOOL bPM = !strPM.IsEmpty() && strTime.Find(strPM) >= 0; // remove prefixed AmPm and other non-digits in the beginning CString strTmp; strTmp = strTime.SpanExcluding(_T("0123456789")); int nTmpLen = strTmp.GetLength(); if (nTmpLen) { strTime.Delete(0, nTmpLen); } //------------------------------------------------- CString strHr, strMin; strHr = strTime.SpanIncluding(_T("0123456789")); int nHrLen = strHr.GetLength(); if (!nHrLen) { return -1; } strTime.Delete(0, nHrLen); CString strTimeSeparator = CXTPCalendarUtils::GetLocaleString(LOCALE_STIME, 16); TCHAR ctTimeSep = strTimeSeparator.GetLength() ? (TCHAR)strTimeSeparator[0] : (TCHAR)0; if (strTime.IsEmpty() || (strTime[0] != ctTimeSep && strTime[0] != _T(':'))) { return -1; } strTime.Delete(0); strMin = strTime.SpanIncluding(_T("0123456789")); TCHAR *pChar1 = NULL, *pChar2 = NULL; int nHr = _tcstol(strHr, &pChar1, 10); int nMin = _tcstol(strMin, &pChar2, 10); int nResult_min = nHr * 60 + nMin; if (bPM && nResult_min <= 12 * 60) nResult_min += 12 * 60; if (nResult_min > 24 * 60) nResult_min = nResult_min % (24 * 60); return nResult_min; } CFont* CXTPCalendarUtils::GetMaxHeightFont(CArray& arFonts, CDC* pDC, int* pnMaxHeight) { CFont* pFontMax = NULL; int nMaxHeight = 0; int nCount = (int)arFonts.GetSize(); for (int i = 0; i < nCount; i++) { CFont* pFont = arFonts[i]; if (pFont && pFont->m_hObject) { if (pDC) { CXTPFontDC autoFont(pDC, pFont); CSize szFi = pDC->GetTextExtent(_T("Aq"), 2); if (szFi.cy > nMaxHeight) { pFontMax = pFont; nMaxHeight = szFi.cy; } } else { LOGFONT lf; int nRes = pFont->GetLogFont(&lf); _ASSERTE(nRes); if (nRes) { int nHeight = abs(lf.lfHeight) + (lf.lfWeight < FW_BOLD ? 0 : 1); if (nHeight > nMaxHeight) { pFontMax = pFont; nMaxHeight = nHeight; } } } } } if (pnMaxHeight) { *pnMaxHeight = nMaxHeight; } return pFontMax; } CXTPCalendarUtils::CXTPTimesResourceIDs::CXTPTimesResourceIDs() { s_mapMinutes.SetAt(0, XTP_IDS_CALENDAR_MINUTES_0); s_mapMinutes.SetAt(1, XTP_IDS_CALENDAR_MINUTES_1); s_mapMinutes.SetAt(5, XTP_IDS_CALENDAR_MINUTES_5); s_mapMinutes.SetAt(10, XTP_IDS_CALENDAR_MINUTES_10); s_mapMinutes.SetAt(15, XTP_IDS_CALENDAR_MINUTES_15); s_mapMinutes.SetAt(30, XTP_IDS_CALENDAR_MINUTES_30); s_mapHours.SetAt(1, XTP_IDS_CALENDAR_HOURS_1); s_mapHours.SetAt(2, XTP_IDS_CALENDAR_HOURS_2); s_mapHours.SetAt(3, XTP_IDS_CALENDAR_HOURS_3); s_mapHours.SetAt(4, XTP_IDS_CALENDAR_HOURS_4); s_mapHours.SetAt(5, XTP_IDS_CALENDAR_HOURS_5); s_mapHours.SetAt(6, XTP_IDS_CALENDAR_HOURS_6); s_mapHours.SetAt(7, XTP_IDS_CALENDAR_HOURS_7); s_mapHours.SetAt(8, XTP_IDS_CALENDAR_HOURS_8); s_mapHours.SetAt(9, XTP_IDS_CALENDAR_HOURS_9); s_mapHours.SetAt(10, XTP_IDS_CALENDAR_HOURS_10); s_mapHours.SetAt(11, XTP_IDS_CALENDAR_HOURS_11); s_mapHours.SetAt(12, XTP_IDS_CALENDAR_DAYS_0_5); s_mapHours.SetAt(18, XTP_IDS_CALENDAR_HOURS_18); s_mapDays.SetAt(1, XTP_IDS_CALENDAR_DAYS_1); s_mapDays.SetAt(2, XTP_IDS_CALENDAR_DAYS_2); s_mapDays.SetAt(3, XTP_IDS_CALENDAR_DAYS_3); s_mapWeeks.SetAt(1, XTP_IDS_CALENDAR_WEEKS_1); s_mapWeeks.SetAt(2, XTP_IDS_CALENDAR_WEEKS_2); } CString CXTPCalendarUtils::LoadString(UINT nIDResource) { CString str; CXTPResourceManager::AssertValid(XTPResourceManager()->LoadString(&str, nIDResource)); return str; } BOOL CXTPCalendarUtils::LoadString2(CString& rstrString, UINT nIDResource) { CString str; BOOL bFind = XTPResourceManager()->LoadString(&str, nIDResource); if (bFind) { rstrString = str; } return bFind; } void CXTPCalendarUtils::TextPrepareSingleline(CString& rstrString) { rstrString.Replace('\n', ' '); } CString CXTPCalendarUtils::FormatTimeDuration(int nMinutes, BOOL bRoundly) { static CXTPTimesResourceIDs s_RCData; int nWeeks = nMinutes / (7 * 24 * 60); int nWeeks_r = nMinutes % (7 * 24 * 60); int nDays = nMinutes / (24 * 60); int nDays_r = nMinutes % (24 * 60); int nHours = nMinutes / 60; int nHours_r = nMinutes % 60; CString strDuration; UINT nStrID = 0; if ((bRoundly || nWeeks_r == 0) && nWeeks) { if (s_RCData.s_mapWeeks.Lookup(nWeeks, nStrID) && nStrID) strDuration = LoadString(nStrID); else strDuration.Format(_T("%d %s"), nWeeks, (LPCTSTR)LoadString(XTP_IDS_CALENDAR_WEEKS)); } else if ((bRoundly || nDays_r == 0) && nDays) { if (s_RCData.s_mapDays.Lookup(nDays, nStrID) && nStrID) strDuration = LoadString(nStrID); else strDuration.Format(_T("%d %s"), nDays, (LPCTSTR)LoadString(XTP_IDS_CALENDAR_DAYS)); } else if ((bRoundly || nHours_r == 0) && nHours) { if (s_RCData.s_mapHours.Lookup(nHours, nStrID) && nStrID) strDuration = LoadString(nStrID); else strDuration.Format(_T("%d %s"), nHours, (LPCTSTR)LoadString(XTP_IDS_CALENDAR_HOURS)); } else { if (s_RCData.s_mapMinutes.Lookup(nMinutes, nStrID) && nStrID) strDuration = LoadString(nStrID); else strDuration.Format(_T("%d %s"), nMinutes, (LPCTSTR)LoadString(XTP_IDS_CALENDAR_MINUTES)); } return strDuration; } int CXTPCalendarUtils::ParceTimeDuration_min(LPCTSTR pcszTime) { CString strTime = pcszTime; strTime.TrimLeft(); strTime.TrimRight(); CString strValue, strScale; strValue = strTime.SpanIncluding(_T("-+0123456789,.")); int nValueLen = strValue.GetLength(); if (!nValueLen) { return INT_MIN; } strTime.Delete(0, nValueLen); strScale = strTime; strScale.TrimLeft(); TCHAR* pChar = NULL; strValue.Replace(_T(","), _T(".")); double dValue = _tcstod(strValue, &pChar); CStringArray arSIname; CStringArray arSIname2; CUIntArray arSIvalue; arSIname.Add(LoadString(XTP_IDS_CALENDAR_TIME_PREFIX_MINUTES)); arSIname2.Add(_T("min")); arSIvalue.Add(1); arSIname.Add(LoadString(XTP_IDS_CALENDAR_TIME_PREFIX_HOURS)); arSIname2.Add(_T("h")); arSIvalue.Add(60); arSIname.Add(LoadString(XTP_IDS_CALENDAR_TIME_PREFIX_DAYS)); arSIname2.Add(_T("d")); arSIvalue.Add(24 * 60); arSIname.Add(LoadString(XTP_IDS_CALENDAR_TIME_PREFIX_WEEKS)); arSIname2.Add(_T("w")); arSIvalue.Add(7 * 24 * 60); int nCount = (int)arSIname.GetSize(); for (int i = 0; i < nCount; i++) { if (_tcsnicmp(strScale, arSIname[i], XTPToSizeTChecked(arSIname[i].GetLength())) == 0 || _tcsnicmp(strScale, arSIname2[i], XTPToSizeTChecked(arSIname2[i].GetLength())) == 0) { return (int)(dValue * arSIvalue[i]); } } return (int)dValue; // minutes } BOOL CXTPCalendarUtils::TrackMouseEvent(DWORD dwFlags, HWND hwndTrack, DWORD dwHoverTime) { TRACKMOUSEEVENT tme; tme.cbSize = sizeof(tme); tme.dwFlags = dwFlags; tme.hwndTrack = hwndTrack; tme.dwHoverTime = dwHoverTime; return _TrackMouseEvent(&tme); } BOOL CXTPCalendarUtils::IsFormatChar(TCHAR t) { return t == 'm' || t == 'M' || t == 'y' || t == 'Y' || t == 'd' || t == 'D' || t == 'g'; } void AFX_CDECL CXTPCalendarUtils::StripFormat(CString& strFormat, int nIndex, int nRemove) { if (nIndex + nRemove == strFormat.GetLength()) strFormat.ReleaseBuffer(nIndex); else strFormat.Delete(nIndex, nRemove); int nLast = nIndex; nIndex--; while (nIndex >= 0 && !IsFormatChar(strFormat[nIndex])) { if (strFormat[nIndex] == '\'') { nIndex--; while (nIndex > 0 && strFormat[nIndex] != '\'') nIndex--; } nIndex--; } nIndex++; strFormat.Delete(nIndex, nLast - nIndex); int nFirst = nIndex; while (nIndex < strFormat.GetLength() && !IsFormatChar(strFormat[nIndex])) { if (strFormat[nIndex] == '\'') { nIndex++; while (nIndex < strFormat.GetLength() && strFormat[nIndex] != '\'') nIndex++; } nIndex++; } if (nFirst == 0 || nIndex == strFormat.GetLength()) strFormat.Delete(nFirst, nIndex - nFirst); } CString CXTPCalendarUtils::RemoveFormatPart(CString strFormat, LPCTSTR lpszRemove) { int nRemove = (int)_tcslen(lpszRemove); int nIndex = strFormat.Find(lpszRemove, 0); while (nIndex >= 0) { if (nIndex + nRemove == strFormat.GetLength()) { StripFormat(strFormat, nIndex, nRemove); return strFormat; } else { if (!IsFormatChar(strFormat[nIndex + nRemove])) { StripFormat(strFormat, nIndex, nRemove); return strFormat; } else { nIndex += nRemove; while (nIndex < strFormat.GetLength() && IsFormatChar(strFormat[nIndex])) { nIndex++; } } } nIndex = strFormat.Find(lpszRemove, nIndex + 1); } return strFormat; } CString CXTPCalendarUtils::RemoveFormatPart(CString strFormat, TCHAR cRemove) { int nIndex = strFormat.Find(cRemove, 0); if (nIndex < 0) return strFormat; int nRemove = 1; while (nIndex + nRemove < strFormat.GetLength() && strFormat[nIndex + nRemove] == cRemove) { nRemove++; } StripFormat(strFormat, nIndex, nRemove); return strFormat; } BOOL CXTPCalendarUtils::IsZeroTime(const COleDateTime& dtDateTime) { double dTime = _ResetDate_dbl((double)dtDateTime); return fabs(dTime) < XTP_HALF_SECOND; } BOOL CXTPCalendarUtils::IsEqual(const COleDateTime& dt1, const COleDateTime& dt2, BOOL bOneSecTimeDiff) { if (dt1.GetStatus() == COleDateTime::null || dt2.GetStatus() == COleDateTime::null) return FALSE; double dTimeDiff = bOneSecTimeDiff ? XTP_HALF_SECOND * 2 : XTP_HALF_SECOND; return dTimeDiff >= fabs(dt1 - dt2); } int AFX_CDECL CXTPCalendarUtils::GetDayOfWeekLocaleStringId(int nWeekDay) { _ASSERTE(1 <= nWeekDay && nWeekDay <= 7); int nFirstID = XTPSystemVersion()->IsWinVistaOrGreater() ? LOCALE_SSHORTESTDAYNAME1 : LOCALE_SABBREVDAYNAME1; return nFirstID + (nWeekDay - 1); } int CXTPCalendarUtils::GetFirstWeekOfYearDays() { int iFirstWeekOfYearDays = 1; int fwy = GetLocaleLong(LOCALE_IFIRSTWEEKOFYEAR); if (fwy == 2) iFirstWeekOfYearDays = 4; else iFirstWeekOfYearDays = 1; return iFirstWeekOfYearDays; } ////////////////////////////////////////////////////////////////////////// // XTP_CALENDAR_HITTESTINFO BOOL XTP_CALENDAR_HITTESTINFO::operator==(const XTP_CALENDAR_HITTESTINFO& hitInfo2) { return (dt.GetStatus() == hitInfo2.dt.GetStatus()) && ((dt.GetStatus() == COleDateTime::valid) && (CXTPCalendarUtils::IsEqual(dt, hitInfo2.dt) || (dt.GetStatus() != COleDateTime::valid))) && (bTimePartValid == hitInfo2.bTimePartValid) && (uHitCode == hitInfo2.uHitCode) && (pViewDay == hitInfo2.pViewDay) && (pViewGroup == hitInfo2.pViewGroup) && (pViewEvent == hitInfo2.pViewEvent) && (nDay == hitInfo2.nDay) && (nGroup == hitInfo2.nGroup) && (nEvent == hitInfo2.nEvent); };