**** Merged from MCS ****
[mono-project.git] / mcs / class / System.Windows.Forms / System.Windows.Forms / DateTimePicker.cs
bloba5822eafea004e8267a1ed9520d835a7eef49e87
1 //
2 // System.Windows.Forms.DateTimePicker.cs
3 //
4 // Author:
5 // stubbed out by Richard Baumann (biochem333@nyc.rr.com)
6 // Dennis Hayes (dennish@Raytek.com)
7 // Aleksey Ryabchuk (ryabchuk@yahoo.com)
8 //
9 // (C) Ximian, Inc., 2002/3
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
20 //
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
23 //
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 using System.Drawing;
33 using System.ComponentModel;
34 using System.Runtime.InteropServices;
36 namespace System.Windows.Forms {
38 // <summary>
39 // Represents a Windows date-time picker control.
40 // </summary>
41 public class DateTimePicker : Control {
44 // --- Public Fields
46 public static readonly DateTime MaxDateTime;
47 public static readonly DateTime MinDateTime;
50 // --- Protected Fields
52 protected static readonly Color DefaultMonthBackColor;
53 protected static readonly Color DefaultTitleBackColor;
54 protected static readonly Color DefaultTitleForeColor;
55 protected static readonly Color DefaultTrailingForeColor;
58 // --- Private Fields
60 private Font calendarFont;
61 private Color calendarForeColor;
62 private Color calendarMonthBackground;
63 private Color calendarTitleBackColor;
64 private Color calendarTitleForeColor;
65 private Color calendarTrailingForeColor;
66 private bool CHecked;
67 private string customFormat;
68 private LeftRightAlignment dropDownAlign;
69 private DateTimePickerFormat format;
70 private DateTime maxDate;
71 private DateTime minDate;
72 private int preferredHeight;
73 private bool showCheckBox;
74 private bool showUpDown;
75 private DateTime val;
78 // --- Constructors/Destructors
81 [MonoTODO]
82 public DateTimePicker() : base()
84 // defaults :)
85 calendarFont = Control.DefaultFont;
86 calendarForeColor = ForeColor;
87 calendarMonthBackground = DefaultMonthBackColor;
88 calendarTitleBackColor = DefaultTitleBackColor;
89 calendarTitleForeColor = DefaultTitleForeColor;
90 calendarTrailingForeColor = DefaultTrailingForeColor;
91 CHecked = true;
92 customFormat = null;
93 dropDownAlign = LeftRightAlignment.Left;
94 format = DateTimePickerFormat.Long;
95 maxDate = MaxDateTime;
96 minDate = MinDateTime;
97 showCheckBox = false;
98 showUpDown = false;
99 val = DateTime.Now;
102 [MonoTODO]
103 static DateTimePicker()
105 MaxDateTime = new DateTime(9998,12,31,23,59,59);
106 MinDateTime = new DateTime(1753,1,1,0,0,0);
107 // As usual, the MS docs aren't very helpful...
108 // I'm guessing these are all the right colors... not sure though
109 // I'll check on Windows when I'm in a more masochistic mood ;)
110 DefaultMonthBackColor = System.Drawing.SystemColors.Window;
111 DefaultTitleBackColor = System.Drawing.SystemColors.ActiveCaption;
112 DefaultTitleForeColor = System.Drawing.SystemColors.ActiveCaptionText;
113 DefaultTrailingForeColor = System.Drawing.SystemColors.WindowText;
117 // --- Public Methods
119 public override string ToString(){
120 return GetType().FullName.ToString() + ", Value: " + Value.ToString( );
124 // --- Protected Methods
126 [MonoTODO]
127 protected override AccessibleObject CreateAccessibilityInstance()
129 //FIXME:
130 return base.CreateAccessibilityInstance();;
133 [MonoTODO]
134 protected override void CreateHandle()
136 initCommonControlsLibrary();
137 base.CreateHandle();
140 [MonoTODO]
141 protected override void DestroyHandle()
143 //FIXME:
144 base.DestroyHandle();
147 [MonoTODO]
148 protected override void Dispose(bool disposing){
149 base.Dispose(disposing);
152 [MonoTODO]
153 protected override bool IsInputKey(Keys keyData)
155 //FIXME:
156 return base.IsInputKey(keyData);
159 protected virtual void OnCloseUp(EventArgs eventargs) {
160 if ( CloseUp != null )
161 CloseUp( this, eventargs );
164 protected virtual void OnDropDown(EventArgs eventargs) {
165 if ( DropDown != null )
166 DropDown( this, eventargs );
169 [MonoTODO]
170 protected override void OnFontChanged(EventArgs e)
172 //FIXME:
173 //if (FontChanged != null) {
174 // FontChanged(this, e);
178 protected virtual void OnFormatChanged(EventArgs e) {
179 if (FormatChanged != null)
180 FormatChanged(this, e);
183 [MonoTODO]
184 protected override void OnSystemColorsChanged(EventArgs e)
186 base.OnSystemColorsChanged( e );
189 //FIXME: should be inherated
190 protected override void OnHandleCreated(EventArgs e) {
191 base.OnHandleCreated(e);
192 setControlRange( );
193 setControlValue( );
194 setCalendarColors( );
195 setCustomFormat( );
196 setCalendarFont( );
199 protected virtual void OnValueChanged(EventArgs eventargs) {
200 if (ValueChanged != null)
201 ValueChanged(this, eventargs);
204 [MonoTODO]
205 protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified)
207 //FIXME:
208 base.SetBoundsCore(x, y, width, height, specified);
211 [MonoTODO]
212 protected override void WndProc(ref Message m)
214 switch ((Msg) m.Msg) {
215 case Msg.WM_NOTIFY:
216 if ( m.LParam != IntPtr.Zero )
217 handleNotification ( ref m );
218 else
219 CallControlWndProc(ref m);
220 break;
221 default:
222 CallControlWndProc(ref m);
223 break;
228 // --- Public Events
230 public event EventHandler CloseUp;
231 public event EventHandler DropDown;
232 public event EventHandler FormatChanged;
233 public event EventHandler ValueChanged;
236 // --- Public Properties
238 [EditorBrowsable (EditorBrowsableState.Never)]
239 public override Color BackColor {
240 get { return base.BackColor; }
241 set { base.BackColor = value; }
244 [EditorBrowsable (EditorBrowsableState.Never)]
245 public override Image BackgroundImage {
246 get { return base.BackgroundImage; }
247 set { base.BackgroundImage = value;}
250 public Font CalendarFont {
251 get { return calendarFont; }
252 set {
253 calendarFont = value;
254 setCalendarFont( );
258 public Color CalendarForeColor {
259 get { return calendarForeColor; }
260 set {
261 if ( calendarForeColor != value ) {
262 calendarForeColor = value;
263 setCalendarColor( (int) MonthCalColors.MCSC_TEXT, value );
268 public Color CalendarMonthBackground {
269 get { return calendarMonthBackground; }
270 set {
271 if ( calendarMonthBackground != value ) {
272 calendarMonthBackground = value;
273 setCalendarColor( (int) MonthCalColors.MCSC_MONTHBK, value );
278 public Color CalendarTitleBackColor {
279 get { return calendarTitleBackColor; }
280 set {
281 if ( calendarTitleBackColor != value ) {
282 calendarTitleBackColor = value;
283 setCalendarColor( (int) MonthCalColors.MCSC_TITLEBK, value );
288 public Color CalendarTitleForeColor {
289 get { return calendarTitleForeColor; }
290 set {
291 if ( calendarTitleForeColor != value ) {
292 calendarTitleForeColor = value;
293 setCalendarColor( (int) MonthCalColors.MCSC_TITLETEXT, value );
298 public Color CalendarTrailingForeColor {
299 get { return calendarTrailingForeColor; }
300 set {
301 if ( calendarTrailingForeColor != value ) {
302 calendarTrailingForeColor = value;
303 setCalendarColor( (int) MonthCalColors.MCSC_TRAILINGTEXT, value );
308 public bool Checked {
309 get {
310 if ( ShowCheckBox )
311 getControlValue ( false ); // don't actually update the Value property
312 return CHecked;
314 set {
315 CHecked = value;
316 if ( ShowCheckBox )
317 setCheckState ( );
321 public string CustomFormat {
322 get { return customFormat; }
323 set {
324 customFormat = value;
325 setCustomFormat ( );
329 public LeftRightAlignment DropDownAlign
331 get { return dropDownAlign; }
332 set {
333 if ( !Enum.IsDefined ( typeof(LeftRightAlignment), value ) )
334 throw new InvalidEnumArgumentException( "DropDownAlign",
335 (int)value,
336 typeof(LeftRightAlignment));
338 if ( dropDownAlign != value ) {
339 dropDownAlign = value;
340 if ( IsHandleCreated )
341 RecreateHandle();
346 [EditorBrowsable (EditorBrowsableState.Never)]
347 public override Color ForeColor {
348 get { return base.ForeColor; }
349 set { base.ForeColor = value; }
352 public DateTimePickerFormat Format {
353 get { return format; }
354 set {
355 if ( !Enum.IsDefined ( typeof(DateTimePickerFormat), value ) )
356 throw new InvalidEnumArgumentException( "Format",
357 (int)value,
358 typeof(DateTimePickerFormat));
360 if ( format != value ) {
361 int StyleToRemove = formatStyle ( format );
362 format = value;
363 if ( IsHandleCreated )
364 Win32.UpdateWindowStyle ( Handle, StyleToRemove, formatStyle ( format ) );
365 OnFormatChanged( EventArgs.Empty );
370 public DateTime MaxDate {
371 get { return maxDate; }
372 set {
373 if ( value == maxDate )
374 return;
376 if ( value < MinDate )
377 throw new ArgumentException (
378 string.Format ("'{0}' is not a valid value for 'MaxDate'. 'MaxDate' must be greater than or equal to MinDate", value ) );
380 if ( value > MaxDateTime )
381 throw new ArgumentException (
382 string.Format ("DateTimePicker does not support dates after {0}.", MaxDateTime ) );
384 maxDate = value;
385 setControlRange ( );
389 public DateTime MinDate {
390 get { return minDate; }
391 set {
392 if ( value == minDate )
393 return;
395 if ( value >= MaxDate )
396 throw new ArgumentException (
397 string.Format ("'{0}' is not a valid value for 'MinDate'. 'MinDate' must be less than MaxDate.", value ) );
399 if ( value < MinDateTime )
400 throw new ArgumentException (
401 string.Format ("DateTimePicker does not support dates before {0}.", MinDateTime ) );
403 minDate = value;
404 setControlRange ( );
408 [MonoTODO]
409 public int PreferredHeight {
410 get{
411 return 300;
415 public bool ShowCheckBox {
416 get { return showCheckBox; }
417 set {
418 if ( showCheckBox != value ) {
419 showCheckBox = value;
420 if ( IsHandleCreated )
421 RecreateHandle();
426 public bool ShowUpDown {
427 get { return showUpDown; }
428 set {
429 if ( showUpDown != value ) {
430 showUpDown = value;
431 if ( IsHandleCreated )
432 RecreateHandle();
437 [EditorBrowsable (EditorBrowsableState.Never)]
438 public override string Text {
439 get { return base.Text; }
440 set { base.Text = value;}
443 [MonoTODO]
444 public DateTime Value {
445 get {
446 getControlValue( true );
447 return val;
449 set {
450 if ( val != value ) {
451 val = value; // do we need to check that the value is in the range ?
452 setControlValue( );
453 OnValueChanged ( EventArgs.Empty );
459 // --- Protected Properties
461 [MonoTODO]
462 protected override CreateParams CreateParams {
463 get {
464 CreateParams createParams = base.CreateParams;
466 createParams.ClassName = "SysDateTimePick32";
468 createParams.Style = (int) (
469 WindowStyles.WS_CHILDWINDOW |
470 WindowStyles.WS_VISIBLE |
471 WindowStyles.WS_CLIPCHILDREN|
472 WindowStyles.WS_CLIPSIBLINGS);
474 if ( ShowUpDown )
475 createParams.Style |= (int) DateTimePickerControlStyles.DTS_UPDOWN;
477 if ( ShowCheckBox )
478 createParams.Style |= (int) DateTimePickerControlStyles.DTS_SHOWNONE;
480 if ( DropDownAlign == LeftRightAlignment.Right )
481 createParams.Style |= (int) DateTimePickerControlStyles.DTS_RIGHTALIGN;
483 createParams.Style |= formatStyle ( Format );
485 return createParams;
489 protected override Size DefaultSize {
490 get{ return new System.Drawing.Size(200,20); }
493 private void initCommonControlsLibrary ( ) {
494 if ( !RecreatingHandle ) {
495 INITCOMMONCONTROLSEX initEx = new INITCOMMONCONTROLSEX();
496 initEx.dwICC = CommonControlInitFlags.ICC_DATE_CLASSES;
497 Win32.InitCommonControlsEx(initEx);
501 private SYSTIME toSysTime ( DateTime val ) {
502 SYSTIME systime = new SYSTIME() ;
503 systime.wDay = (ushort)val.Day;
504 systime.wHour = (ushort)val.Hour;
505 systime.wMilliseconds = (ushort)val.Millisecond;
506 systime.wMinute = (ushort)val.Minute;
507 systime.wMonth = (ushort)val.Month;
508 systime.wSecond = (ushort)val.Second;
509 systime.wYear = (ushort)val.Year;
510 return systime;
513 private DateTime toDateTime ( ref SYSTIME val ) {
514 return new DateTime( val.wYear, val.wMonth, val.wDay,
515 val.wHour, val.wMinute, val.wSecond,
516 val.wMilliseconds );
519 private void setControlValue ( ) {
520 if ( IsHandleCreated ) {
521 SYSTIME systime = toSysTime ( val ) ;
523 IntPtr ptr = Marshal.AllocHGlobal ( Marshal.SizeOf ( systime ) );
524 Marshal.StructureToPtr( systime, ptr, false );
525 Win32.SendMessage ( Handle, (int)DateTimePickerMessages.DTM_SETSYSTEMTIME,
526 (int)DateTimePickerFlags.GDT_VALID, ptr );
527 Marshal.FreeHGlobal ( ptr );
531 private void setCheckState ( ) {
532 if ( Checked )
533 setControlValue ();
534 else {
535 if ( IsHandleCreated ) {
536 Win32.SendMessage ( Handle, (int)DateTimePickerMessages.DTM_SETSYSTEMTIME,
537 (int)DateTimePickerFlags.GDT_NONE, 0 );
542 private void getControlValue ( bool updateProp ) {
543 if ( IsHandleCreated ) {
544 SYSTIME systime = new SYSTIME();
545 IntPtr ptr = Marshal.AllocHGlobal ( Marshal.SizeOf ( systime ) );
546 Marshal.StructureToPtr( systime, ptr, false );
547 int res = Win32.SendMessage ( Handle, (int)DateTimePickerMessages.DTM_GETSYSTEMTIME,
548 0 , ptr ).ToInt32();
549 if ( res == (int)DateTimePickerFlags.GDT_VALID ) {
550 systime = Marshal.PtrToStructure ( ptr, systime.GetType ( ) ) as SYSTIME;
551 DateTime newValue = toDateTime ( ref systime );
553 CHecked = !( newValue == val || newValue == DateTime.Now );
555 if ( updateProp )
556 val = newValue;
558 else
559 CHecked = false;
560 Marshal.FreeHGlobal ( ptr );
564 private void setControlRange ( ) {
565 if ( IsHandleCreated ) {
566 SYSTIME[] range = { toSysTime ( MinDate ), toSysTime ( MaxDate ) };
567 IntPtr buffer = Marshal.AllocHGlobal ( Marshal.SizeOf( range[0] ) * 2 );
568 IntPtr current = buffer;
569 Marshal.StructureToPtr ( range[0], current, false );
570 current = (IntPtr)( current.ToInt32() + Marshal.SizeOf( range[0] ) );
571 Marshal.StructureToPtr ( range[1], current, false );
572 Win32.SendMessage( Handle, (int)DateTimePickerMessages.DTM_SETRANGE,
573 (int)( DateTimePickerFlags.GDTR_MIN | DateTimePickerFlags.GDTR_MAX ),
574 buffer.ToInt32() );
575 Marshal.FreeHGlobal ( buffer );
579 private void setCalendarColor ( int ColorFlag, Color clr ) {
580 if ( IsHandleCreated )
581 Win32.SendMessage ( Handle, (int)DateTimePickerMessages.DTM_SETMCCOLOR, ColorFlag, Win32.RGB(clr) );
584 private void setCalendarColors ( ) {
585 if ( calendarForeColor != ForeColor )
586 setCalendarColor( (int) MonthCalColors.MCSC_TEXT, calendarForeColor );
587 if ( calendarMonthBackground != DefaultMonthBackColor )
588 setCalendarColor( (int) MonthCalColors.MCSC_MONTHBK, calendarMonthBackground );
589 if ( calendarTitleBackColor != DefaultTitleBackColor )
590 setCalendarColor( (int) MonthCalColors.MCSC_TITLEBK, calendarTitleBackColor );
591 if ( calendarTitleForeColor != DefaultTitleForeColor )
592 setCalendarColor( (int) MonthCalColors.MCSC_TITLETEXT, calendarTitleForeColor );
593 if ( calendarTrailingForeColor != DefaultTrailingForeColor )
594 setCalendarColor( (int) MonthCalColors.MCSC_TRAILINGTEXT, calendarTrailingForeColor );
597 private int formatStyle ( DateTimePickerFormat format ) {
598 int style = 0;
600 switch ( format ) {
601 case DateTimePickerFormat.Long:
602 style = (int)DateTimePickerControlStyles.DTS_LONGDATEFORMAT;
603 break;
604 case DateTimePickerFormat.Short:
605 style = (int)DateTimePickerControlStyles.DTS_SHORTDATEFORMAT;
606 break;
607 case DateTimePickerFormat.Time:
608 style = (int)DateTimePickerControlStyles.DTS_TIMEFORMAT;
609 break;
611 return style;
614 private void setCustomFormat ( ) {
615 if ( Format == DateTimePickerFormat.Custom && IsHandleCreated )
616 Win32.SendMessage ( Handle, (int)DateTimePickerMessages.DTM_SETFORMATA, 0, CustomFormat );
619 private void setCalendarFont ( ) {
620 // This code will not work because Font.Equals is not implemented
622 if ( IsHandleCreated && !CalendarFont.Equals( Control.DefaultFont ) )
623 Win32.SendMessage ( Handle, (int)DateTimePickerMessages.DTM_SETMCFONT,
624 CalendarFont.ToHfont().ToInt32(), 0 );
628 private void handleNotification ( ref Message m ) {
629 NMHDR nmhdr = (NMHDR)Marshal.PtrToStructure ( m.LParam, typeof ( NMHDR ) );
631 m.Result = IntPtr.Zero;
633 switch ( nmhdr.code ) {
634 case (int)DateTimePickerNotifications.DTN_CLOSEUP:
635 OnCloseUp ( EventArgs.Empty );
636 break;
637 case (int)DateTimePickerNotifications.DTN_DROPDOWN:
638 OnDropDown ( EventArgs.Empty );
639 break;
640 case (int)DateTimePickerNotifications.DTN_DATETIMECHANGE:
641 getControlValue ( true );
642 OnValueChanged ( EventArgs.Empty );
643 break;
644 default:
645 CallControlWndProc ( ref m );
646 break;