use wxDP_SPIN by default under Win32
[wxWidgets.git] / src / msw / datectrl.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: msw/datectrl.cpp
3 // Purpose: wxDatePickerCtrl implementation
4 // Author: Vadim Zeitlin
5 // Modified by:
6 // Created: 2005-01-09
7 // RCS-ID: $Id$
8 // Copyright: (c) 2005 Vadim Zeitlin <vadim@wxwindows.org>
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 #include "wx/wxprec.h"
21
22 #ifdef __BORLANDC__
23 #pragma hdrstop
24 #endif
25
26 #ifndef WX_PRECOMP
27 #endif
28
29 #if wxUSE_DATEPICKCTRL
30
31 #include "wx/datectrl.h"
32
33 #define _WX_DEFINE_DATE_EVENTS_
34 #include "wx/dateevt.h"
35
36 #include "wx/msw/wrapwin.h"
37 #include "wx/msw/wrapcctl.h"
38 #include "wx/msw/private.h"
39
40 // ============================================================================
41 // implementation
42 // ============================================================================
43
44 // ----------------------------------------------------------------------------
45 // helpers for wxDateTime <-> SYSTEMTIME conversion
46 // ----------------------------------------------------------------------------
47
48 static inline void wxFromSystemTime(wxDateTime *dt, const SYSTEMTIME& st)
49 {
50 dt->Set(st.wDay,
51 wx_static_cast(wxDateTime::Month, wxDateTime::Jan + st.wMonth - 1),
52 st.wYear,
53 0, 0, 0);
54 }
55
56 static inline void wxToSystemTime(SYSTEMTIME *st, const wxDateTime& dt)
57 {
58 const wxDateTime::Tm tm(dt.GetTm());
59
60 st->wYear = tm.year;
61 st->wMonth = tm.mon - wxDateTime::Jan + 1;
62 st->wDay = tm.mday;
63
64 st->wDayOfWeek =
65 st->wHour =
66 st->wMinute =
67 st->wSecond =
68 st->wMilliseconds = 0;
69 }
70
71 // ----------------------------------------------------------------------------
72 // wxDatePickerCtrl creation
73 // ----------------------------------------------------------------------------
74
75 bool
76 wxDatePickerCtrl::Create(wxWindow *parent,
77 wxWindowID id,
78 const wxDateTime& dt,
79 const wxPoint& pos,
80 const wxSize& size,
81 long style,
82 const wxValidator& validator,
83 const wxString& name)
84 {
85 // use wxDP_SPIN if wxDP_DEFAULT (0) was given as style
86 if ( !(style & wxDP_DROPDOWN) )
87 style |= wxDP_SPIN;
88
89 // initialize the base class
90 if ( !CreateControl(parent, id, pos, size, style, validator, name) )
91 return false;
92
93 // create the native control
94 if ( !MSWCreateControl(DATETIMEPICK_CLASS, _T(""), pos, size) )
95 return false;
96
97 if ( dt.IsValid() )
98 SetValue(dt);
99
100 return true;
101 }
102
103 WXDWORD wxDatePickerCtrl::MSWGetStyle(long style, WXDWORD *exstyle) const
104 {
105 WXDWORD styleMSW = wxDatePickerCtrlBase::MSWGetStyle(style, exstyle);
106
107 if ( style & wxDP_SPIN )
108 styleMSW |= DTS_UPDOWN;
109 //else: drop down by default
110
111 styleMSW |= DTS_SHORTDATEFORMAT;
112
113 return styleMSW;
114 }
115
116 // TODO: handle WM_WININICHANGE
117
118 // ----------------------------------------------------------------------------
119 // wxDatePickerCtrl geometry
120 // ----------------------------------------------------------------------------
121
122 wxSize wxDatePickerCtrl::DoGetBestSize() const
123 {
124 const int y = GetCharHeight();
125
126 return wxSize(DEFAULT_ITEM_WIDTH, EDIT_HEIGHT_FROM_CHAR_HEIGHT(y));
127 }
128
129 // ----------------------------------------------------------------------------
130 // wxDatePickerCtrl operations
131 // ----------------------------------------------------------------------------
132
133 void wxDatePickerCtrl::SetValue(const wxDateTime& dt)
134 {
135 // as we don't support DTS_SHOWNONE style so far, we don't allow setting
136 // the control to an invalid date, but this restriction may be lifted in
137 // the future
138 wxCHECK_RET( dt.IsValid(), _T("invalid date") );
139
140 SYSTEMTIME st;
141 wxToSystemTime(&st, dt);
142 if ( !DateTime_SetSystemtime(GetHwnd(), GDT_VALID, &st) )
143 {
144 wxLogDebug(_T("DateTime_SetSystemtime() failed"));
145 }
146 }
147
148 wxDateTime wxDatePickerCtrl::GetValue() const
149 {
150 wxDateTime dt;
151 SYSTEMTIME st;
152 if ( DateTime_GetSystemtime(GetHwnd(), &st) == GDT_VALID )
153 {
154 wxFromSystemTime(&dt, st);
155 }
156
157 return dt;
158 }
159
160 void wxDatePickerCtrl::SetRange(const wxDateTime& dt1, const wxDateTime& dt2)
161 {
162 SYSTEMTIME st[2];
163
164 DWORD flags = 0;
165 if ( dt1.IsValid() )
166 {
167 wxToSystemTime(&st[0], dt1);
168 flags |= GDTR_MIN;
169 }
170
171 if ( dt2.IsValid() )
172 {
173 wxToSystemTime(&st[1], dt2);
174 flags |= GDTR_MAX;
175 }
176
177 if ( !DateTime_SetRange(GetHwnd(), flags, st) )
178 {
179 wxLogDebug(_T("DateTime_SetRange() failed"));
180 }
181 }
182
183 bool wxDatePickerCtrl::GetRange(wxDateTime *dt1, wxDateTime *dt2) const
184 {
185 SYSTEMTIME st[2];
186
187 DWORD flags = DateTime_GetRange(GetHwnd(), st);
188 if ( dt1 )
189 {
190 if ( flags & GDTR_MIN )
191 wxFromSystemTime(dt1, st[0]);
192 else
193 *dt1 = wxDefaultDateTime;
194 }
195
196 if ( dt2 )
197 {
198 if ( flags & GDTR_MAX )
199 wxFromSystemTime(dt2, st[1]);
200 else
201 *dt2 = wxDefaultDateTime;
202 }
203
204 return flags != 0;
205 }
206
207 // ----------------------------------------------------------------------------
208 // wxDatePickerCtrl events
209 // ----------------------------------------------------------------------------
210
211 bool
212 wxDatePickerCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
213 {
214 NMHDR* hdr = (NMHDR *)lParam;
215 switch ( hdr->code )
216 {
217 case DTN_DATETIMECHANGE:
218 NMDATETIMECHANGE *dtch = (NMDATETIMECHANGE *)hdr;
219 wxDateTime dt;
220 if ( dtch->dwFlags == GDT_VALID )
221 wxFromSystemTime(&dt, dtch->st);
222
223 wxDateEvent event(this, dt, wxEVT_DATE_CHANGED);
224 if ( GetEventHandler()->ProcessEvent(event) )
225 {
226 *result = 0;
227 return true;
228 }
229 }
230
231 return wxDatePickerCtrlBase::MSWOnNotify(idCtrl, lParam, result);
232 }
233
234 #endif // wxUSE_DATEPICKCTRL
235