X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/b3ed70208bcae02080d48217b7e0165a7b21ffec..96b2cbe8b39292fed91654ff0d1f4b1c16561acb:/src/msw/calctrl.cpp diff --git a/src/msw/calctrl.cpp b/src/msw/calctrl.cpp index 53e802a827..90faa55f47 100644 --- a/src/msw/calctrl.cpp +++ b/src/msw/calctrl.cpp @@ -56,6 +56,9 @@ wxCalendarCtrl::Create(wxWindow *parent, if ( !wxMSWDateControls::CheckInitialization() ) return false; + // we need the arrows for the navigation + style |= wxWANTS_CHARS; + // initialize the base class if ( !CreateControl(parent, id, pos, size, style, wxDefaultValidator, name) ) return false; @@ -87,9 +90,16 @@ wxCalendarCtrl::Create(wxWindow *parent, if ( !MSWCreateControl(clsname, wxEmptyString, pos, size) ) return false; + // initialize the control + UpdateFirstDayOfWeek(); + SetDate(dt.IsValid() ? dt : wxDateTime::Today()); + UpdateMarks(); + Connect(wxEVT_LEFT_DOWN, + wxMouseEventHandler(wxCalendarCtrl::MSWOnClick)); + Connect(wxEVT_LEFT_DCLICK, wxMouseEventHandler(wxCalendarCtrl::MSWOnDoubleClick)); return true; @@ -99,23 +109,37 @@ WXDWORD wxCalendarCtrl::MSWGetStyle(long style, WXDWORD *exstyle) const { WXDWORD styleMSW = wxCalendarCtrlBase::MSWGetStyle(style, exstyle); - // right now we don't support any native styles but we should add wx styles - // corresponding to MCS_NOTODAY, MCS_NOTODAYCIRCLE and MCS_WEEKNUMBERS - // probably (TODO) + // right now we don't support all native styles but we should add wx styles + // corresponding to MCS_NOTODAY and MCS_NOTODAYCIRCLE probably (TODO) // for compatibility with the other versions, just turn off today display // unconditionally for now styleMSW |= MCS_NOTODAY; + // we also need this style for Mark() to work + styleMSW |= MCS_DAYSTATE; + + if ( style & wxCAL_SHOW_WEEK_NUMBERS ) + styleMSW |= MCS_WEEKNUMBERS; + return styleMSW; } -// TODO: handle WM_WININICHANGE +void wxCalendarCtrl::SetWindowStyleFlag(long style) +{ + const bool hadMondayFirst = HasFlag(wxCAL_MONDAY_FIRST); + + wxCalendarCtrlBase::SetWindowStyleFlag(style); + + if ( HasFlag(wxCAL_MONDAY_FIRST) != hadMondayFirst ) + UpdateFirstDayOfWeek(); +} // ---------------------------------------------------------------------------- // wxCalendarCtrl geometry // ---------------------------------------------------------------------------- +// TODO: handle WM_WININICHANGE wxSize wxCalendarCtrl::DoGetBestSize() const { RECT rc; @@ -153,7 +177,7 @@ wxCalendarCtrl::HitTest(const wxPoint& pos, case MCHT_CALENDARDATE: if ( date ) - wxMSWDateControls::FromSystemTime(date, hti.st); + date->SetFromMSWSysTime(hti.st); return wxCAL_HITTEST_DAY; case MCHT_CALENDARDAY: @@ -184,7 +208,7 @@ bool wxCalendarCtrl::SetDate(const wxDateTime& dt) wxCHECK_MSG( dt.IsValid(), false, "invalid date" ); SYSTEMTIME st; - wxMSWDateControls::ToSystemTime(&st, dt); + dt.GetAsMSWSysTime(&st); if ( !MonthCal_SetCurSel(GetHwnd(), &st) ) { wxLogDebug(_T("DateTime_SetSystemtime() failed")); @@ -208,8 +232,7 @@ wxDateTime wxCalendarCtrl::GetDate() const return wxDefaultDateTime; } - wxDateTime dt; - wxMSWDateControls::FromSystemTime(&dt, st); + wxDateTime dt(st); wxASSERT_MSG( dt == m_date, "mismatch between data and control" ); #endif // __WXDEBUG__ @@ -224,13 +247,13 @@ bool wxCalendarCtrl::SetDateRange(const wxDateTime& dt1, const wxDateTime& dt2) DWORD flags = 0; if ( dt1.IsValid() ) { - wxMSWDateControls::ToSystemTime(&st[0], dt1); + dt1.GetAsMSWSysTime(st + 0); flags |= GDTR_MIN; } if ( dt2.IsValid() ) { - wxMSWDateControls::ToSystemTime(&st[1], dt2); + dt2.GetAsMSWSysTime(st + 1); flags |= GDTR_MAX; } @@ -250,7 +273,7 @@ bool wxCalendarCtrl::GetDateRange(wxDateTime *dt1, wxDateTime *dt2) const if ( dt1 ) { if ( flags & GDTR_MIN ) - wxMSWDateControls::FromSystemTime(dt1, st[0]); + dt1->SetFromMSWSysTime(st[0]); else *dt1 = wxDefaultDateTime; } @@ -258,7 +281,7 @@ bool wxCalendarCtrl::GetDateRange(wxDateTime *dt1, wxDateTime *dt2) const if ( dt2 ) { if ( flags & GDTR_MAX ) - wxMSWDateControls::FromSystemTime(dt2, st[1]); + dt2->SetFromMSWSysTime(st[1]); else *dt2 = wxDefaultDateTime; } @@ -292,7 +315,36 @@ bool wxCalendarCtrl::EnableMonthChange(bool enable) void wxCalendarCtrl::Mark(size_t day, bool mark) { - wxFAIL_MSG( "not implemented" ); + wxCHECK_RET( day > 0 && day < 32, "invalid day" ); + + int mask = 1 << (day - 1); + if ( mark ) + m_marks |= mask; + else + m_marks &= ~mask; + + // calling Refresh() here is not enough to change the day appearance + UpdateMarks(); +} + +void wxCalendarCtrl::UpdateMarks() +{ + MONTHDAYSTATE states[3]; + const int nMonths = MonthCal_GetMonthRange(GetHwnd(), GMR_DAYSTATE, NULL); + wxCHECK_RET( nMonths <= (int)WXSIZEOF(states), "unexpected months range" ); + + for ( int i = 0; i < nMonths; i++ ) + states[i] = m_marks; + + if ( !MonthCal_SetDayState(GetHwnd(), nMonths, states) ) + { + wxLogLastError(_T("MonthCal_SetDayState")); + } +} + +void wxCalendarCtrl::UpdateFirstDayOfWeek() +{ + MonthCal_SetFirstDayOfWeek(GetHwnd(), HasFlag(wxCAL_MONDAY_FIRST) ? 0 : 6); } // ---------------------------------------------------------------------------- @@ -305,25 +357,39 @@ bool wxCalendarCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) switch ( hdr->code ) { 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); + // 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; + m_date.SetFromMSWSysTime(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); + } + } + break; - *result = 0; - return true; + case MCN_GETDAYSTATE: + { + const NMDAYSTATE * const ds = (NMDAYSTATE *)lParam; + for ( int i = 0; i < ds->cDayState; i++ ) + { + ds->prgDayState[i] = m_marks; + } } + break; + + default: + return wxCalendarCtrlBase::MSWOnNotify(idCtrl, lParam, result); } - return wxCalendarCtrlBase::MSWOnNotify(idCtrl, lParam, result); + *result = 0; + return true; } void wxCalendarCtrl::MSWOnDoubleClick(wxMouseEvent& event) @@ -337,4 +403,13 @@ void wxCalendarCtrl::MSWOnDoubleClick(wxMouseEvent& event) event.Skip(); } +void wxCalendarCtrl::MSWOnClick(wxMouseEvent& event) +{ + // for some reason, the control doesn't get focus on its own when the user + // clicks in it + SetFocus(); + + event.Skip(); +} + #endif // wxUSE_CALENDARCTRL