///////////////////////////////////////////////////////////////////////////// // Name: src/msw/calctrl.cpp // Purpose: wxCalendarCtrl implementation // Author: Vadim Zeitlin // Created: 2008-04-04 // RCS-ID: $Id$ // Copyright: (C) 2008 Vadim Zeitlin // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// // ============================================================================ // declarations // ============================================================================ // ---------------------------------------------------------------------------- // headers // ---------------------------------------------------------------------------- #include "wx/wxprec.h" #ifdef __BORLANDC__ #pragma hdrstop #endif #if wxUSE_CALENDARCTRL #ifndef WX_PRECOMP #include "wx/msw/wrapwin.h" #include "wx/msw/wrapcctl.h" // include "properly" #include "wx/msw/private.h" #endif #include "wx/calctrl.h" #include "wx/msw/private/datecontrols.h" IMPLEMENT_DYNAMIC_CLASS(wxCalendarCtrl, wxControl) // ============================================================================ // implementation // ============================================================================ // ---------------------------------------------------------------------------- // wxCalendarCtrl creation // ---------------------------------------------------------------------------- bool wxCalendarCtrl::Create(wxWindow *parent, wxWindowID id, const wxDateTime& dt, const wxPoint& pos, const wxSize& size, long style, const wxString& name) { if ( !wxMSWDateControls::CheckInitialization() ) return false; // initialize the base class if ( !CreateControl(parent, id, pos, size, style, wxDefaultValidator, name) ) return false; // create the native control if ( !MSWCreateControl(MONTHCAL_CLASS, wxEmptyString, pos, size) ) return false; SetDate(dt.IsValid() ? dt : wxDateTime::Today()); return true; } 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) // for compatibility with the other versions, just turn off today display // unconditionally for now styleMSW |= MCS_NOTODAY; return styleMSW; } // TODO: handle WM_WININICHANGE // ---------------------------------------------------------------------------- // wxCalendarCtrl geometry // ---------------------------------------------------------------------------- wxSize wxCalendarCtrl::DoGetBestSize() const { RECT rc; if ( !GetHwnd() || !MonthCal_GetMinReqRect(GetHwnd(), &rc) ) { return wxCalendarCtrlBase::DoGetBestSize(); } const wxSize best = wxRectFromRECT(rc).GetSize() + GetWindowBorderSize(); CacheBestSize(best); return best; } // ---------------------------------------------------------------------------- // wxCalendarCtrl operations // ---------------------------------------------------------------------------- bool wxCalendarCtrl::SetDate(const wxDateTime& dt) { wxCHECK_MSG( dt.IsValid(), false, "invalid date" ); SYSTEMTIME st; wxMSWDateControls::ToSystemTime(&st, dt); if ( !MonthCal_SetCurSel(GetHwnd(), &st) ) { wxLogDebug(_T("DateTime_SetSystemtime() failed")); return false; } return true; } wxDateTime wxCalendarCtrl::GetDate() const { SYSTEMTIME st; if ( !MonthCal_GetCurSel(GetHwnd(), &st) ) return wxDefaultDateTime; wxDateTime dt; wxMSWDateControls::FromSystemTime(&dt, st); return dt; } bool wxCalendarCtrl::SetDateRange(const wxDateTime& dt1, const wxDateTime& dt2) { SYSTEMTIME st[2]; DWORD flags = 0; if ( dt1.IsValid() ) { wxMSWDateControls::ToSystemTime(&st[0], dt1); flags |= GDTR_MIN; } if ( dt2.IsValid() ) { wxMSWDateControls::ToSystemTime(&st[1], dt2); flags |= GDTR_MAX; } if ( !MonthCal_SetRange(GetHwnd(), flags, st) ) { wxLogDebug(_T("MonthCal_SetRange() failed")); } return flags != 0; } bool wxCalendarCtrl::GetDateRange(wxDateTime *dt1, wxDateTime *dt2) const { SYSTEMTIME st[2]; DWORD flags = MonthCal_GetRange(GetHwnd(), st); if ( dt1 ) { if ( flags & GDTR_MIN ) wxMSWDateControls::FromSystemTime(dt1, st[0]); else *dt1 = wxDefaultDateTime; } if ( dt2 ) { if ( flags & GDTR_MAX ) wxMSWDateControls::FromSystemTime(dt2, st[1]); else *dt2 = wxDefaultDateTime; } return flags != 0; } // ---------------------------------------------------------------------------- // other wxCalendarCtrl operations // ---------------------------------------------------------------------------- bool wxCalendarCtrl::EnableMonthChange(bool enable) { if ( !wxCalendarCtrlBase::EnableMonthChange(enable) ) return false; wxDateTime dtStart, dtEnd; if ( !enable ) { dtStart = GetDate(); dtStart.SetDay(1); dtEnd = dtStart.GetLastMonthDay(); } //else: leave them invalid to remove the restriction SetDateRange(dtStart, dtEnd); return true; } void wxCalendarCtrl::Mark(size_t day, bool mark) { wxFAIL_MSG( "not implemented" ); } // ---------------------------------------------------------------------------- // wxCalendarCtrl events // ---------------------------------------------------------------------------- bool wxCalendarCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) { NMHDR* hdr = (NMHDR *)lParam; switch ( hdr->code ) { case MCN_SELECT: NMSELCHANGE *sch = (NMSELCHANGE *)hdr; GenerateEvent(wxEVT_CALENDAR_SEL_CHANGED); *result = 0; return true; } return wxCalendarCtrlBase::MSWOnNotify(idCtrl, lParam, result); } #endif // wxUSE_CALENDARCTRL