1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/msw/calctrl.cpp
3 // Purpose: wxCalendarCtrl implementation
4 // Author: Vadim Zeitlin
7 // Copyright: (C) 2008 Vadim Zeitlin <vadim@wxwidgets.org>
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 // ============================================================================
13 // ============================================================================
15 // ----------------------------------------------------------------------------
17 // ----------------------------------------------------------------------------
19 #include "wx/wxprec.h"
25 #if wxUSE_CALENDARCTRL
28 #include "wx/msw/wrapwin.h"
29 #include "wx/msw/wrapcctl.h" // include <commctrl.h> "properly"
30 #include "wx/msw/private.h"
33 #include "wx/calctrl.h"
35 #include "wx/msw/private/datecontrols.h"
37 IMPLEMENT_DYNAMIC_CLASS(wxCalendarCtrl
, wxControl
)
39 // ============================================================================
41 // ============================================================================
43 // ----------------------------------------------------------------------------
44 // wxCalendarCtrl creation
45 // ----------------------------------------------------------------------------
48 wxCalendarCtrl::Create(wxWindow
*parent
,
56 if ( !wxMSWDateControls::CheckInitialization() )
59 // initialize the base class
60 if ( !CreateControl(parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
) )
63 // create the native control
64 if ( !MSWCreateControl(MONTHCAL_CLASS
, wxEmptyString
, pos
, size
) )
67 SetDate(dt
.IsValid() ? dt
: wxDateTime::Today());
72 WXDWORD
wxCalendarCtrl::MSWGetStyle(long style
, WXDWORD
*exstyle
) const
74 WXDWORD styleMSW
= wxCalendarCtrlBase::MSWGetStyle(style
, exstyle
);
76 // right now we don't support any native styles but we should add wx styles
77 // corresponding to MCS_NOTODAY, MCS_NOTODAYCIRCLE and MCS_WEEKNUMBERS
80 // for compatibility with the other versions, just turn off today display
81 // unconditionally for now
82 styleMSW
|= MCS_NOTODAY
;
87 // TODO: handle WM_WININICHANGE
89 // ----------------------------------------------------------------------------
90 // wxCalendarCtrl geometry
91 // ----------------------------------------------------------------------------
93 wxSize
wxCalendarCtrl::DoGetBestSize() const
96 if ( !GetHwnd() || !MonthCal_GetMinReqRect(GetHwnd(), &rc
) )
98 return wxCalendarCtrlBase::DoGetBestSize();
101 const wxSize best
= wxRectFromRECT(rc
).GetSize() + GetWindowBorderSize();
106 wxCalendarHitTestResult
107 wxCalendarCtrl::HitTest(const wxPoint
& pos
,
109 wxDateTime::WeekDay
*wd
)
111 WinStruct
<MCHITTESTINFO
> hti
;
114 switch ( MonthCal_HitTest(GetHwnd(), &hti
) )
117 case MCHT_CALENDARWEEKNUM
:
118 wxFAIL_MSG( "unexpected" );
122 case MCHT_CALENDARBK
:
124 case MCHT_TITLEMONTH
:
126 return wxCAL_HITTEST_NOWHERE
;
128 case MCHT_CALENDARDATE
:
130 wxMSWDateControls::FromSystemTime(date
, hti
.st
);
131 return wxCAL_HITTEST_DAY
;
133 case MCHT_CALENDARDAY
:
136 *wd
= wx_static_cast(wxDateTime::WeekDay
, hti
.st
.wDayOfWeek
);
138 return wxCAL_HITTEST_HEADER
;
140 case MCHT_TITLEBTNNEXT
:
141 return wxCAL_HITTEST_INCMONTH
;
143 case MCHT_TITLEBTNPREV
:
144 return wxCAL_HITTEST_DECMONTH
;
146 case MCHT_CALENDARDATENEXT
:
147 case MCHT_CALENDARDATEPREV
:
148 return wxCAL_HITTEST_SURROUNDING_WEEK
;
152 // ----------------------------------------------------------------------------
153 // wxCalendarCtrl operations
154 // ----------------------------------------------------------------------------
156 bool wxCalendarCtrl::SetDate(const wxDateTime
& dt
)
158 wxCHECK_MSG( dt
.IsValid(), false, "invalid date" );
161 wxMSWDateControls::ToSystemTime(&st
, dt
);
162 if ( !MonthCal_SetCurSel(GetHwnd(), &st
) )
164 wxLogDebug(_T("DateTime_SetSystemtime() failed"));
172 wxDateTime
wxCalendarCtrl::GetDate() const
175 if ( !MonthCal_GetCurSel(GetHwnd(), &st
) )
176 return wxDefaultDateTime
;
179 wxMSWDateControls::FromSystemTime(&dt
, st
);
183 bool wxCalendarCtrl::SetDateRange(const wxDateTime
& dt1
, const wxDateTime
& dt2
)
190 wxMSWDateControls::ToSystemTime(&st
[0], dt1
);
196 wxMSWDateControls::ToSystemTime(&st
[1], dt2
);
200 if ( !MonthCal_SetRange(GetHwnd(), flags
, st
) )
202 wxLogDebug(_T("MonthCal_SetRange() failed"));
208 bool wxCalendarCtrl::GetDateRange(wxDateTime
*dt1
, wxDateTime
*dt2
) const
212 DWORD flags
= MonthCal_GetRange(GetHwnd(), st
);
215 if ( flags
& GDTR_MIN
)
216 wxMSWDateControls::FromSystemTime(dt1
, st
[0]);
218 *dt1
= wxDefaultDateTime
;
223 if ( flags
& GDTR_MAX
)
224 wxMSWDateControls::FromSystemTime(dt2
, st
[1]);
226 *dt2
= wxDefaultDateTime
;
232 // ----------------------------------------------------------------------------
233 // other wxCalendarCtrl operations
234 // ----------------------------------------------------------------------------
236 bool wxCalendarCtrl::EnableMonthChange(bool enable
)
238 if ( !wxCalendarCtrlBase::EnableMonthChange(enable
) )
241 wxDateTime dtStart
, dtEnd
;
247 dtEnd
= dtStart
.GetLastMonthDay();
249 //else: leave them invalid to remove the restriction
251 SetDateRange(dtStart
, dtEnd
);
256 void wxCalendarCtrl::Mark(size_t day
, bool mark
)
258 wxFAIL_MSG( "not implemented" );
261 // ----------------------------------------------------------------------------
262 // wxCalendarCtrl events
263 // ----------------------------------------------------------------------------
265 bool wxCalendarCtrl::MSWOnNotify(int idCtrl
, WXLPARAM lParam
, WXLPARAM
*result
)
267 NMHDR
* hdr
= (NMHDR
*)lParam
;
271 NMSELCHANGE
*sch
= (NMSELCHANGE
*)hdr
;
272 GenerateEvent(wxEVT_CALENDAR_SEL_CHANGED
);
277 return wxCalendarCtrlBase::MSWOnNotify(idCtrl
, lParam
, result
);
280 #endif // wxUSE_CALENDARCTRL