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
This commit is contained in:
Vadim Zeitlin
2012-02-11 16:26:47 +00:00
parent 169b83dd23
commit c3d3028a44

View File

@@ -396,10 +396,12 @@ void wxCalendarCtrl::SetHoliday(size_t day)
void wxCalendarCtrl::UpdateMarks() void wxCalendarCtrl::UpdateMarks()
{ {
// we show only one full month but there can be some days from the month // Currently the native control may show more than one month if its size is
// before it and from the one after it so days from 3 different months can // big enough. Ideal would be to prevent this from happening but there
// be partially shown // doesn't seem to be any obvious way to do it, so for now just handle the
MONTHDAYSTATE states[3] = { 0 }; // 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); const DWORD nMonths = MonthCal_GetMonthRange(GetHwnd(), GMR_DAYSTATE, NULL);
// although in principle the calendar might not show any days from the // 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 // 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 // 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 // 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"); // The current, fully visible month is always the second one.
}
else if ( nMonths == WXSIZEOF(states) )
{
// the fully visible month is the one in the middle
states[1] = m_marks | m_holidays; states[1] = m_marks | m_holidays;
if ( !MonthCal_SetDayState(GetHwnd(), nMonths, states) ) if ( !MonthCal_SetDayState(GetHwnd(), nMonths, states) )
@@ -472,9 +470,24 @@ bool wxCalendarCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
case MCN_GETDAYSTATE: case MCN_GETDAYSTATE:
{ {
const NMDAYSTATE * const ds = (NMDAYSTATE *)lParam; 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++ ) 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; break;