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