// implementation only from now on
+protected:
// generate the given calendar event(s)
void GenerateEvent(wxEventType type)
{
wxCalendarEvent event(this, GetDate(), type);
HandleWindowEvent(event);
}
+
+ // generate all the events for the selection change from dateOld to current
+ // date: SEL_CHANGED, PAGE_CHANGED if necessary and also one of (deprecated)
+ // YEAR/MONTH/DAY_CHANGED ones
+ void GenerateAllChangeEvents(const wxDateTime& dateOld);
};
// ----------------------------------------------------------------------------
virtual bool MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result);
private:
+ wxDateTime m_date;
+
DECLARE_DYNAMIC_CLASS(wxCalendarCtrl)
DECLARE_NO_COPY_CLASS(wxCalendarCtrl)
};
return true;
}
+void wxCalendarCtrlBase::GenerateAllChangeEvents(const wxDateTime& dateOld)
+{
+ const wxDateTime::Tm tm1 = dateOld.GetTm(),
+ tm2 = GetDate().GetTm();
+
+ GenerateEvent(wxEVT_CALENDAR_SEL_CHANGED);
+ if ( tm1.year != tm2.year || tm1.mon != tm2.mon )
+ GenerateEvent(wxEVT_CALENDAR_PAGE_CHANGED);
+
+ // send also one of the deprecated events
+ if ( tm1.year != tm2.year )
+ GenerateEvent(wxEVT_CALENDAR_YEAR_CHANGED);
+ else if ( tm1.mon != tm2.mon )
+ GenerateEvent(wxEVT_CALENDAR_MONTH_CHANGED);
+ else
+ GenerateEvent(wxEVT_CALENDAR_DAY_CHANGED);
+}
+
#endif // wxUSE_CALENDARCTRL
void wxGenericCalendarCtrl::SetDateAndNotify(const wxDateTime& date)
{
- wxDateTime::Tm tm1 = m_date.GetTm(),
- tm2 = date.GetTm();
-
- const bool pageChanged = tm1.year != tm2.year || tm1.mon != tm2.mon;
-
- if ( !pageChanged && tm1.mday == tm2.mday )
- return;
-
- if ( SetDate(date) )
+ const wxDateTime dateOld = GetDate();
+ if ( date != dateOld && SetDate(date) )
{
- GenerateEvent(wxEVT_CALENDAR_SEL_CHANGED);
- if ( !pageChanged )
- GenerateEvent(wxEVT_CALENDAR_PAGE_CHANGED);
-
- // send also one of the deprecated events
- if ( tm1.year != tm2.year )
- GenerateEvent(wxEVT_CALENDAR_YEAR_CHANGED);
- else if ( tm1.mon != tm2.mon )
- GenerateEvent(wxEVT_CALENDAR_MONTH_CHANGED);
- else
- GenerateEvent(wxEVT_CALENDAR_DAY_CHANGED);
+ GenerateAllChangeEvents(dateOld);
}
}
ChangeDay(date);
GenerateEvent(wxEVT_CALENDAR_SEL_CHANGED);
+
+ // we know that the month/year never change when the user
+ // clicks on the control so there is no need to call
+ // GenerateAllChangeEvents() here, we know which event to send
GenerateEvent(wxEVT_CALENDAR_DAY_CHANGED);
}
break;
return false;
}
+ m_date = dt;
+
return true;
}
wxDateTime wxCalendarCtrl::GetDate() const
{
+#ifdef __WXDEBUG__
SYSTEMTIME st;
if ( !MonthCal_GetCurSel(GetHwnd(), &st) )
+ {
+ wxASSERT_MSG( !m_date.IsValid(), "mismatch between data and control" );
+
return wxDefaultDateTime;
+ }
wxDateTime dt;
wxMSWDateControls::FromSystemTime(&dt, st);
- return dt;
+
+ wxASSERT_MSG( dt == m_date, "mismatch between data and control" );
+#endif // __WXDEBUG__
+
+ return m_date;
}
bool wxCalendarCtrl::SetDateRange(const wxDateTime& dt1, const wxDateTime& dt2)
NMHDR* hdr = (NMHDR *)lParam;
switch ( hdr->code )
{
- case MCN_SELECT:
- NMSELCHANGE *sch = (NMSELCHANGE *)hdr;
- GenerateEvent(wxEVT_CALENDAR_SEL_CHANGED);
- *result = 0;
- return true;
+ case MCN_SELCHANGE:
+ // we need to update m_date first, before calling the user code
+ // which expects GetDate() to return the new date
+ const wxDateTime dateOld = m_date;
+ const NMSELCHANGE * const sch = (NMSELCHANGE *)lParam;
+ wxMSWDateControls::FromSystemTime(&m_date, sch->stSelStart);
+
+ // changing the year or the month results in a second dummy
+ // MCN_SELCHANGE event on this system which doesn't really change
+ // anything -- filter it out
+ if ( m_date != dateOld )
+ {
+ GenerateAllChangeEvents(dateOld);
+
+ *result = 0;
+ return true;
+ }
}
return wxCalendarCtrlBase::MSWOnNotify(idCtrl, lParam, result);