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
This commit is contained in:
Vadim Zeitlin
2010-05-04 21:59:17 +00:00
parent 79309be9db
commit 10acc3ef6a
3 changed files with 40 additions and 14 deletions

View File

@@ -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)

View File

@@ -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::Month>(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

View File

@@ -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