]> git.saurik.com Git - wxWidgets.git/blame - src/msw/datectrl.cpp
Fixed a long-standing issue where wxSlider controls with a hardcoded size would mispl...
[wxWidgets.git] / src / msw / datectrl.cpp
CommitLineData
feb72429
VZ
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
9b877d18
WS
29#if wxUSE_DATEPICKCTRL
30
feb72429 31#include "wx/datectrl.h"
0aa7cb54
VZ
32#include "wx/app.h"
33#include "wx/intl.h"
34#include "wx/dynlib.h"
feb72429
VZ
35
36#define _WX_DEFINE_DATE_EVENTS_
37#include "wx/dateevt.h"
38
39#include "wx/msw/wrapwin.h"
40#include "wx/msw/wrapcctl.h"
4510fc80 41#include "wx/msw/private.h"
feb72429
VZ
42
43// ============================================================================
44// implementation
45// ============================================================================
46
47// ----------------------------------------------------------------------------
48// helpers for wxDateTime <-> SYSTEMTIME conversion
49// ----------------------------------------------------------------------------
50
51static inline void wxFromSystemTime(wxDateTime *dt, const SYSTEMTIME& st)
52{
53 dt->Set(st.wDay,
54 wx_static_cast(wxDateTime::Month, wxDateTime::Jan + st.wMonth - 1),
55 st.wYear,
56 0, 0, 0);
57}
58
59static inline void wxToSystemTime(SYSTEMTIME *st, const wxDateTime& dt)
60{
61 const wxDateTime::Tm tm(dt.GetTm());
62
3a0c6181
WS
63 st->wYear = (WXWORD)tm.year;
64 st->wMonth = (WXWORD)(tm.mon - wxDateTime::Jan + 1);
feb72429
VZ
65 st->wDay = tm.mday;
66
67 st->wDayOfWeek =
68 st->wHour =
69 st->wMinute =
70 st->wSecond =
71 st->wMilliseconds = 0;
72}
73
74// ----------------------------------------------------------------------------
75// wxDatePickerCtrl creation
76// ----------------------------------------------------------------------------
77
78bool
79wxDatePickerCtrl::Create(wxWindow *parent,
80 wxWindowID id,
81 const wxDateTime& dt,
82 const wxPoint& pos,
83 const wxSize& size,
84 long style,
85 const wxValidator& validator,
86 const wxString& name)
87{
0aa7cb54
VZ
88 // although we already call InitCommonControls() in app.cpp which is
89 // supposed to initialize all common controls, in comctl32.dll 4.72 (and
90 // presumably earlier versions 4.70 and 4.71, date time picker not being
91 // supported in < 4.70 anyhow) it does not do it and we have to initialize
92 // it explicitely
93 static bool s_initDone = false; // MT-ok: used from GUI thread only
94 if ( !s_initDone )
95 {
96 if ( wxTheApp->GetComCtl32Version() < 470 )
97 {
98 wxLogError(_("This system doesn't support date picker control, please upgrade your version of comctl32.dll"));
99
100 return false;
101 }
102
103 INITCOMMONCONTROLSEX icex;
104 icex.dwSize = sizeof(icex);
105 icex.dwICC = ICC_DATE_CLASSES;
106
107 wxDynamicLibrary dllComCtl32(_T("comctl32.dll"), wxDL_VERBATIM);
108
109 typedef BOOL (WINAPI *ICCEx_t)(INITCOMMONCONTROLSEX *);
110 wxDYNLIB_FUNCTION( ICCEx_t, InitCommonControlsEx, dllComCtl32 );
111
112 if ( pfnInitCommonControlsEx )
113 {
114 (*pfnInitCommonControlsEx)(&icex);
115 }
116
117 s_initDone = true;
118 }
119
120
5385747e
VZ
121 // use wxDP_SPIN if wxDP_DEFAULT (0) was given as style
122 if ( !(style & wxDP_DROPDOWN) )
123 style |= wxDP_SPIN;
124
feb72429
VZ
125 // initialize the base class
126 if ( !CreateControl(parent, id, pos, size, style, validator, name) )
127 return false;
128
129 // create the native control
130 if ( !MSWCreateControl(DATETIMEPICK_CLASS, _T(""), pos, size) )
131 return false;
132
133 if ( dt.IsValid() )
134 SetValue(dt);
135
136 return true;
137}
138
139WXDWORD wxDatePickerCtrl::MSWGetStyle(long style, WXDWORD *exstyle) const
140{
141 WXDWORD styleMSW = wxDatePickerCtrlBase::MSWGetStyle(style, exstyle);
142
0aa7cb54
VZ
143 // although MSDN doesn't mention it, DTS_UPDOWN doesn't work with
144 // comctl32.dll 4.72
145 if ( wxTheApp->GetComCtl32Version() > 472 && (style & wxDP_SPIN) )
29c86948
VZ
146 styleMSW |= DTS_UPDOWN;
147 //else: drop down by default
148
2cfbeac8
VZ
149#ifdef DTS_SHORTDATECENTURYFORMAT
150 if ( style & wxDP_SHOWCENTURY )
151 styleMSW |= DTS_SHORTDATECENTURYFORMAT;
152 else
153#endif // DTS_SHORTDATECENTURYFORMAT
154 styleMSW |= DTS_SHORTDATEFORMAT;
feb72429
VZ
155
156 return styleMSW;
157}
158
159// TODO: handle WM_WININICHANGE
160
161// ----------------------------------------------------------------------------
162// wxDatePickerCtrl geometry
163// ----------------------------------------------------------------------------
164
165wxSize wxDatePickerCtrl::DoGetBestSize() const
166{
167 const int y = GetCharHeight();
168
169 return wxSize(DEFAULT_ITEM_WIDTH, EDIT_HEIGHT_FROM_CHAR_HEIGHT(y));
170}
171
172// ----------------------------------------------------------------------------
173// wxDatePickerCtrl operations
174// ----------------------------------------------------------------------------
175
dc2e9133
RR
176#ifndef DateTime_GetSystemtime
177 #define DateTime_GetSystemtime DateTime_GetSystemTime
178#endif
179
180#ifndef DateTime_SetSystemtime
181 #define DateTime_SetSystemtime DateTime_SetSystemTime
182#endif
183
feb72429
VZ
184void wxDatePickerCtrl::SetValue(const wxDateTime& dt)
185{
186 // as we don't support DTS_SHOWNONE style so far, we don't allow setting
187 // the control to an invalid date, but this restriction may be lifted in
188 // the future
189 wxCHECK_RET( dt.IsValid(), _T("invalid date") );
190
191 SYSTEMTIME st;
192 wxToSystemTime(&st, dt);
193 if ( !DateTime_SetSystemtime(GetHwnd(), GDT_VALID, &st) )
194 {
195 wxLogDebug(_T("DateTime_SetSystemtime() failed"));
196 }
197}
198
199wxDateTime wxDatePickerCtrl::GetValue() const
200{
201 wxDateTime dt;
202 SYSTEMTIME st;
203 if ( DateTime_GetSystemtime(GetHwnd(), &st) == GDT_VALID )
204 {
205 wxFromSystemTime(&dt, st);
206 }
207
208 return dt;
209}
210
211void wxDatePickerCtrl::SetRange(const wxDateTime& dt1, const wxDateTime& dt2)
212{
213 SYSTEMTIME st[2];
214
215 DWORD flags = 0;
216 if ( dt1.IsValid() )
217 {
218 wxToSystemTime(&st[0], dt1);
219 flags |= GDTR_MIN;
220 }
221
222 if ( dt2.IsValid() )
223 {
224 wxToSystemTime(&st[1], dt2);
225 flags |= GDTR_MAX;
226 }
227
228 if ( !DateTime_SetRange(GetHwnd(), flags, st) )
229 {
230 wxLogDebug(_T("DateTime_SetRange() failed"));
231 }
232}
233
234bool wxDatePickerCtrl::GetRange(wxDateTime *dt1, wxDateTime *dt2) const
235{
236 SYSTEMTIME st[2];
237
238 DWORD flags = DateTime_GetRange(GetHwnd(), st);
239 if ( dt1 )
240 {
241 if ( flags & GDTR_MIN )
242 wxFromSystemTime(dt1, st[0]);
243 else
244 *dt1 = wxDefaultDateTime;
245 }
246
247 if ( dt2 )
248 {
249 if ( flags & GDTR_MAX )
250 wxFromSystemTime(dt2, st[1]);
251 else
252 *dt2 = wxDefaultDateTime;
253 }
254
255 return flags != 0;
256}
257
258// ----------------------------------------------------------------------------
259// wxDatePickerCtrl events
260// ----------------------------------------------------------------------------
261
262bool
263wxDatePickerCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
264{
265 NMHDR* hdr = (NMHDR *)lParam;
266 switch ( hdr->code )
267 {
268 case DTN_DATETIMECHANGE:
269 NMDATETIMECHANGE *dtch = (NMDATETIMECHANGE *)hdr;
270 wxDateTime dt;
271 if ( dtch->dwFlags == GDT_VALID )
272 wxFromSystemTime(&dt, dtch->st);
273
274 wxDateEvent event(this, dt, wxEVT_DATE_CHANGED);
275 if ( GetEventHandler()->ProcessEvent(event) )
276 {
277 *result = 0;
278 return true;
279 }
280 }
281
282 return wxDatePickerCtrlBase::MSWOnNotify(idCtrl, lParam, result);
283}
284
9b877d18 285#endif // wxUSE_DATEPICKCTRL
29c86948 286