From c3d3028a446641a687a7619cf2c492fcaa94b46f Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 11 Feb 2012 16:26:47 +0000 Subject: [PATCH] Update marks in non-current months shown in wxMSW wxCalendarCtrl. Native wxMSW calendar control can show more than just the current month. When other months are shown, ensure that they don't have marks for the days marked in the current month as this doesn't make sense. See #13934. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@70568 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/msw/calctrl.cpp | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/src/msw/calctrl.cpp b/src/msw/calctrl.cpp index b168a1b..467ced1 100644 --- a/src/msw/calctrl.cpp +++ b/src/msw/calctrl.cpp @@ -396,10 +396,12 @@ void wxCalendarCtrl::SetHoliday(size_t day) void wxCalendarCtrl::UpdateMarks() { - // we show only one full month but there can be some days from the month - // before it and from the one after it so days from 3 different months can - // be partially shown - MONTHDAYSTATE states[3] = { 0 }; + // Currently the native control may show more than one month if its size is + // big enough. Ideal would be to prevent this from happening but there + // doesn't seem to be any obvious way to do it, so for now just handle the + // possibility that we can display several of them: one before the current + // one and up to 12 after it. + MONTHDAYSTATE states[14] = { 0 }; const DWORD nMonths = MonthCal_GetMonthRange(GetHwnd(), GMR_DAYSTATE, NULL); // although in principle the calendar might not show any days from the @@ -412,13 +414,9 @@ void wxCalendarCtrl::UpdateMarks() // in its window if you "zoom out" of it by double clicking on free areas // so the return value can be (much, in case of decades view) greater than // 3 but in this case marks are not visible anyhow so simply ignore it - if ( nMonths < WXSIZEOF(states) ) + if ( nMonths >= 2 && nMonths <= WXSIZEOF(states) ) { - wxFAIL_MSG("unexpectedly few months shown in the control"); - } - else if ( nMonths == WXSIZEOF(states) ) - { - // the fully visible month is the one in the middle + // The current, fully visible month is always the second one. states[1] = m_marks | m_holidays; if ( !MonthCal_SetDayState(GetHwnd(), nMonths, states) ) @@ -472,9 +470,24 @@ bool wxCalendarCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) case MCN_GETDAYSTATE: { const NMDAYSTATE * const ds = (NMDAYSTATE *)lParam; + + wxDateTime startDate; + startDate.SetFromMSWSysDate(ds->stStart); + + wxDateTime currentDate = m_date; + // Set to the start of month for comparison with startDate to + // work correctly. + currentDate.SetDay(1); + for ( int i = 0; i < ds->cDayState; i++ ) { - ds->prgDayState[i] = m_marks | m_holidays; + // set holiday/marks only for the "current" month + if ( startDate == currentDate ) + ds->prgDayState[i] = m_marks | m_holidays; + else + ds->prgDayState[i] = 0; + + startDate += wxDateSpan::Month(); } } break; -- 2.7.4