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