initial native implementation of wxCalendarCtrl for MSW
[wxWidgets.git] / src / msw / calctrl.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/msw/calctrl.cpp
3 // Purpose: wxCalendarCtrl implementation
4 // Author: Vadim Zeitlin
5 // Created: 2008-04-04
6 // RCS-ID: $Id:$
7 // Copyright: (C) 2008 Vadim Zeitlin <vadim@wxwidgets.org>
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10
11 // ============================================================================
12 // declarations
13 // ============================================================================
14
15 // ----------------------------------------------------------------------------
16 // headers
17 // ----------------------------------------------------------------------------
18
19 #include "wx/wxprec.h"
20
21 #ifdef __BORLANDC__
22 #pragma hdrstop
23 #endif
24
25 #if wxUSE_CALENDARCTRL
26
27 #ifndef WX_PRECOMP
28 #include "wx/msw/wrapwin.h"
29 #include "wx/msw/wrapcctl.h" // include <commctrl.h> "properly"
30 #endif
31
32 #include "wx/calctrl.h"
33
34 #include "wx/msw/private/datecontrols.h"
35
36 IMPLEMENT_DYNAMIC_CLASS(wxCalendarCtrl, wxControl)
37
38 // ============================================================================
39 // implementation
40 // ============================================================================
41
42 // ----------------------------------------------------------------------------
43 // wxCalendarCtrl creation
44 // ----------------------------------------------------------------------------
45
46 bool
47 wxCalendarCtrl::Create(wxWindow *parent,
48 wxWindowID id,
49 const wxDateTime& dt,
50 const wxPoint& pos,
51 const wxSize& size,
52 long style,
53 const wxString& name)
54 {
55 if ( !wxMSWDateControls::CheckInitialization() )
56 return false;
57
58 // initialize the base class
59 if ( !CreateControl(parent, id, pos, size, style, wxDefaultValidator, name) )
60 return false;
61
62 // create the native control
63 if ( !MSWCreateControl(MONTHCAL_CLASS, wxEmptyString, pos, size) )
64 return false;
65
66 SetDate(dt.IsValid() ? dt : wxDateTime::Today());
67
68 return true;
69 }
70
71 WXDWORD wxCalendarCtrl::MSWGetStyle(long style, WXDWORD *exstyle) const
72 {
73 WXDWORD styleMSW = wxCalendarCtrlBase::MSWGetStyle(style, exstyle);
74
75 // right now we don't support any native styles but we should add wx styles
76 // corresponding to MCS_NOTODAY, MCS_NOTODAYCIRCLE and MCS_WEEKNUMBERS
77 // probably (TODO)
78
79 // for compatibility with the other versions, just turn off today display
80 // unconditionally for now
81 styleMSW |= MCS_NOTODAY;
82
83 return styleMSW;
84 }
85
86 // TODO: handle WM_WININICHANGE
87
88 // ----------------------------------------------------------------------------
89 // wxCalendarCtrl geometry
90 // ----------------------------------------------------------------------------
91
92 wxSize wxCalendarCtrl::DoGetBestSize() const
93 {
94 RECT rc;
95 if ( !GetHwnd() || !MonthCal_GetMinReqRect(GetHwnd(), &rc) )
96 {
97 return wxCalendarCtrlBase::DoGetBestSize();
98 }
99
100 const wxSize best = wxRectFromRECT(rc).GetSize() + GetWindowBorderSize();
101 CacheBestSize(best);
102 return best;
103 }
104
105 // ----------------------------------------------------------------------------
106 // wxCalendarCtrl operations
107 // ----------------------------------------------------------------------------
108
109 bool wxCalendarCtrl::SetDate(const wxDateTime& dt)
110 {
111 wxCHECK_MSG( dt.IsValid(), false, "invalid date" );
112
113 SYSTEMTIME st;
114 wxMSWDateControls::ToSystemTime(&st, dt);
115 if ( !MonthCal_SetCurSel(GetHwnd(), &st) )
116 {
117 wxLogDebug(_T("DateTime_SetSystemtime() failed"));
118
119 return false;
120 }
121
122 return true;
123 }
124
125 wxDateTime wxCalendarCtrl::GetDate() const
126 {
127 SYSTEMTIME st;
128 if ( !MonthCal_GetCurSel(GetHwnd(), &st) )
129 return wxDefaultDateTime;
130
131 wxDateTime dt;
132 wxMSWDateControls::FromSystemTime(&dt, st);
133 return dt;
134 }
135
136 bool wxCalendarCtrl::SetDateRange(const wxDateTime& dt1, const wxDateTime& dt2)
137 {
138 SYSTEMTIME st[2];
139
140 DWORD flags = 0;
141 if ( dt1.IsValid() )
142 {
143 wxMSWDateControls::ToSystemTime(&st[0], dt1);
144 flags |= GDTR_MIN;
145 }
146
147 if ( dt2.IsValid() )
148 {
149 wxMSWDateControls::ToSystemTime(&st[1], dt2);
150 flags |= GDTR_MAX;
151 }
152
153 if ( !MonthCal_SetRange(GetHwnd(), flags, st) )
154 {
155 wxLogDebug(_T("MonthCal_SetRange() failed"));
156 }
157
158 return flags != 0;
159 }
160
161 bool wxCalendarCtrl::GetDateRange(wxDateTime *dt1, wxDateTime *dt2) const
162 {
163 SYSTEMTIME st[2];
164
165 DWORD flags = MonthCal_GetRange(GetHwnd(), st);
166 if ( dt1 )
167 {
168 if ( flags & GDTR_MIN )
169 wxMSWDateControls::FromSystemTime(dt1, st[0]);
170 else
171 *dt1 = wxDefaultDateTime;
172 }
173
174 if ( dt2 )
175 {
176 if ( flags & GDTR_MAX )
177 wxMSWDateControls::FromSystemTime(dt2, st[1]);
178 else
179 *dt2 = wxDefaultDateTime;
180 }
181
182 return flags != 0;
183 }
184
185 // ----------------------------------------------------------------------------
186 // other wxCalendarCtrl operations
187 // ----------------------------------------------------------------------------
188
189 bool wxCalendarCtrl::EnableMonthChange(bool enable)
190 {
191 wxFAIL_MSG( "not implemented" );
192
193 return false;
194 }
195
196 void wxCalendarCtrl::Mark(size_t day, bool mark)
197 {
198 wxFAIL_MSG( "not implemented" );
199 }
200
201 // ----------------------------------------------------------------------------
202 // wxCalendarCtrl events
203 // ----------------------------------------------------------------------------
204
205 bool wxCalendarCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
206 {
207 NMHDR* hdr = (NMHDR *)lParam;
208 switch ( hdr->code )
209 {
210 case MCN_SELECT:
211 NMSELCHANGE *sch = (NMSELCHANGE *)hdr;
212 GenerateEvent(wxEVT_CALENDAR_SEL_CHANGED);
213 *result = 0;
214 return true;
215 }
216
217 return wxCalendarCtrlBase::MSWOnNotify(idCtrl, lParam, result);
218 }
219
220 #endif // wxUSE_CALENDARCTRL