From 10acc3ef6a2c65181b869ca4c1bdfbecf51ee4cd Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 4 May 2010 21:59:17 +0000 Subject: [PATCH] Ignore time component of SYSTEMTIME in wxCalendarCtrl. Native month calendar functions doesn't always return correct values in the time part of SYSTEMTIME so ignore it and use just the date component. To simplify doing it, add helper (MSW-specific) SetFromMSWSysDate() and GetAsMSWSysDate() functions which convert between wxDateTime and SYSTEMTIME but take only date component into account. This commit partially replaces changes of r63560 and closes #11276. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@64208 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/datetime.h | 9 ++++++--- src/common/datetime.cpp | 24 ++++++++++++++++++++++++ src/msw/calctrl.cpp | 21 ++++++++++----------- 3 files changed, 40 insertions(+), 14 deletions(-) diff --git a/include/wx/datetime.h b/include/wx/datetime.h index 2531c54686..49aa4d6dc6 100644 --- a/include/wx/datetime.h +++ b/include/wx/datetime.h @@ -947,12 +947,15 @@ public: // SYSTEMTIME format // ------------------------------------------------------------------------ #ifdef __WXMSW__ - // convert SYSTEMTIME to wxDateTime - wxDateTime& SetFromMSWSysTime(const struct _SYSTEMTIME&); + wxDateTime& SetFromMSWSysTime(const struct _SYSTEMTIME& st); // convert wxDateTime to SYSTEMTIME - void GetAsMSWSysTime(struct _SYSTEMTIME*) const; + void GetAsMSWSysTime(struct _SYSTEMTIME* st) const; + + // same as above but only take date part into account, time is always zero + wxDateTime& SetFromMSWSysDate(const struct _SYSTEMTIME& st); + void GetAsMSWSysDate(struct _SYSTEMTIME* st) const; #endif // __WXMSW__ // comparison (see also functions below for operator versions) diff --git a/src/common/datetime.cpp b/src/common/datetime.cpp index e9f1935bb3..d6e965cb09 100644 --- a/src/common/datetime.cpp +++ b/src/common/datetime.cpp @@ -2347,6 +2347,14 @@ wxDateTime& wxDateTime::SetFromMSWSysTime(const SYSTEMTIME& st) st.wHour, st.wMinute, st.wSecond, st.wMilliseconds); } +wxDateTime& wxDateTime::SetFromMSWSysDate(const SYSTEMTIME& st) +{ + return Set(st.wDay, + static_cast(wxDateTime::Jan + st.wMonth - 1), + st.wYear, + 0, 0, 0, 0); +} + void wxDateTime::GetAsMSWSysTime(SYSTEMTIME* st) const { const wxDateTime::Tm tm(GetTm()); @@ -2361,6 +2369,22 @@ void wxDateTime::GetAsMSWSysTime(SYSTEMTIME* st) const st->wSecond = tm.sec; st->wMilliseconds = tm.msec; } + +void wxDateTime::GetAsMSWSysDate(SYSTEMTIME* st) const +{ + const wxDateTime::Tm tm(GetTm()); + + st->wYear = (WXWORD)tm.year; + st->wMonth = (WXWORD)(tm.mon - wxDateTime::Jan + 1); + st->wDay = tm.mday; + + st->wDayOfWeek = + st->wHour = + st->wMinute = + st->wSecond = + st->wMilliseconds = 0; +} + #endif // __WXMSW__ #endif // wxUSE_DATETIME diff --git a/src/msw/calctrl.cpp b/src/msw/calctrl.cpp index 529209551f..859a549bd6 100644 --- a/src/msw/calctrl.cpp +++ b/src/msw/calctrl.cpp @@ -214,7 +214,7 @@ wxCalendarCtrl::HitTest(const wxPoint& pos, case MCHT_CALENDARDATE: if ( date ) - date->SetFromMSWSysTime(hti.st); + date->SetFromMSWSysDate(hti.st); return wxCAL_HITTEST_DAY; case MCHT_CALENDARDAY: @@ -263,10 +263,8 @@ bool wxCalendarCtrl::SetDate(const wxDateTime& dt) { wxCHECK_MSG( dt.IsValid(), false, "invalid date" ); - const wxDateTime date = dt.GetDateOnly(); - SYSTEMTIME st; - date.GetAsMSWSysTime(&st); + dt.GetAsMSWSysDate(&st); if ( !MonthCal_SetCurSel(GetHwnd(), &st) ) { wxLogDebug(wxT("DateTime_SetSystemtime() failed")); @@ -274,7 +272,7 @@ bool wxCalendarCtrl::SetDate(const wxDateTime& dt) return false; } - m_date = date; + m_date = dt.GetDateOnly(); return true; } @@ -283,6 +281,7 @@ wxDateTime wxCalendarCtrl::GetDate() const { #if wxDEBUG_LEVEL SYSTEMTIME st; + if ( !MonthCal_GetCurSel(GetHwnd(), &st) ) { wxASSERT_MSG( !m_date.IsValid(), "mismatch between data and control" ); @@ -290,14 +289,14 @@ wxDateTime wxCalendarCtrl::GetDate() const return wxDefaultDateTime; } - wxDateTime dt(st); + wxDateTime dt; + dt.SetFromMSWSysDate(st); // Windows XP and earlier didn't include the time component into the // returned date but Windows 7 does, so we can't compare the full objects // in the same way under all the Windows versions, just compare their date // parts - wxASSERT_MSG( dt.GetDateOnly() == m_date.GetDateOnly(), - "mismatch between data and control" ); + wxASSERT_MSG( dt.IsSameDate(m_date), "mismatch between data and control" ); #endif // wxDEBUG_LEVEL return m_date; @@ -336,7 +335,7 @@ bool wxCalendarCtrl::GetDateRange(wxDateTime *dt1, wxDateTime *dt2) const if ( dt1 ) { if ( flags & GDTR_MIN ) - dt1->SetFromMSWSysTime(st[0]); + dt1->SetFromMSWSysDate(st[0]); else *dt1 = wxDefaultDateTime; } @@ -344,7 +343,7 @@ bool wxCalendarCtrl::GetDateRange(wxDateTime *dt1, wxDateTime *dt2) const if ( dt2 ) { if ( flags & GDTR_MAX ) - dt2->SetFromMSWSysTime(st[1]); + dt2->SetFromMSWSysDate(st[1]); else *dt2 = wxDefaultDateTime; } @@ -454,7 +453,7 @@ bool wxCalendarCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) // which expects GetDate() to return the new date const wxDateTime dateOld = m_date; const NMSELCHANGE * const sch = (NMSELCHANGE *)lParam; - m_date.SetFromMSWSysTime(sch->stSelStart); + m_date.SetFromMSWSysDate(sch->stSelStart); // changing the year or the month results in a second dummy // MCN_SELCHANGE event on this system which doesn't really -- 2.45.2