File: winforms\Managed\System\WinForms\DateTimePicker.cs
Project: ndp\fx\src\System.Windows.Forms.csproj (System.Windows.Forms)
//------------------------------------------------------------------------------
// <copyright file="DateTimePicker.cs" company="Microsoft">
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
 
/*
 */
namespace System.Windows.Forms {
    using System.Runtime.InteropServices;
    using System.Runtime.Remoting;
 
    using System.Diagnostics;
 
    using System;
    using System.Security.Permissions;
 
    using System.Drawing;
    using System.Windows.Forms.Internal;
    using System.Windows.Forms.Layout;
    using System.ComponentModel;
    using System.ComponentModel.Design;
    using System.Globalization;
 
    using Microsoft.Win32;
 
    /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker"]/*' />
    /// <devdoc>
    ///     Date/DateTime picker control
    /// </devdoc>
    [
    ComVisible(true),
    ClassInterface(ClassInterfaceType.AutoDispatch),
    DefaultProperty("Value"),
    DefaultEvent("ValueChanged"),
    DefaultBindingProperty("Value"),
    Designer("System.Windows.Forms.Design.DateTimePickerDesigner, " + AssemblyRef.SystemDesign),
    SRDescription(SR.DescriptionDateTimePicker)
    ]
    public class DateTimePicker : Control {
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.DefaultTitleBackColor"]/*' />
        /// <devdoc>
        ///    <para>Specifies the default title back color. This field is read-only.</para>
        /// </devdoc>
        protected static readonly Color DefaultTitleBackColor = SystemColors.ActiveCaption;
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.DefaultTitleForeColor"]/*' />
        /// <devdoc>
        ///    <para>Specifies the default foreground color. This field is read-only.</para>
        /// </devdoc>
        protected static readonly Color DefaultTitleForeColor = SystemColors.ActiveCaptionText;
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.DefaultMonthBackColor"]/*' />
        /// <devdoc>
        ///    <para>Specifies the default month background color. This field is read-only.</para>
        /// </devdoc>
        protected static readonly Color DefaultMonthBackColor = SystemColors.Window;
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.DefaultTrailingForeColor"]/*' />
        /// <devdoc>
        ///    <para>Specifies the default trailing forground color. This field is read-only.</para>
        /// </devdoc>
        protected static readonly Color DefaultTrailingForeColor = SystemColors.GrayText;
 
        private static readonly object EVENT_FORMATCHANGED = new object();
 
        private static readonly string DateTimePickerLocalizedControlTypeString = SR.GetString(SR.DateTimePickerLocalizedControlType);
 
        private const int TIMEFORMAT_NOUPDOWN = NativeMethods.DTS_TIMEFORMAT & (~NativeMethods.DTS_UPDOWN);
        private EventHandler                    onCloseUp;
        private EventHandler                    onDropDown;
        private EventHandler                    onValueChanged;
        private EventHandler                    onRightToLeftLayoutChanged;
 
        // We need to restrict the available dates because of limitations in the comctl
        // DateTime and MonthCalendar controls
        //
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.MinDateTime"]/*' />
        /// <devdoc>
        ///    <para>Specifies the minimum date value. This field is read-only.</para>
        /// </devdoc>
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public static readonly DateTime MinDateTime = new DateTime(1753, 1, 1);
 
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.MaxDateTime"]/*' />
        /// <devdoc>
        ///    <para>Specifies the maximum date value. This field is read-only.</para>
        /// </devdoc>
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public static readonly DateTime MaxDateTime = new DateTime(9998, 12, 31);
 
        private int                             style;
        private short                           prefHeightCache = -1;
 
        /// <devdoc>
        ///     validTime determines whether the CheckBox in the DTP is checked.  The CheckBox is only
        ///     displayed when ShowCheckBox is true.
        /// </devdoc>
        /// <internalonly/>
        private bool                            validTime = true;
 
        // DateTime changeover: DateTime is a value class, not an object, so we need to keep track
        // of whether or not its values have been initialised in a separate boolean.
        private bool                            userHasSetValue = false;
        private DateTime                        value = DateTime.Now;
        private DateTime                        creationTime = DateTime.Now;
        // VSWhidbey 400284: Reconcile out-of-range min/max values in the property getters.
        private DateTime                        max = DateTime.MaxValue;
        private DateTime                        min = DateTime.MinValue;
        private Color                           calendarForeColor = DefaultForeColor;
        private Color                           calendarTitleBackColor = DefaultTitleBackColor;
        private Color                           calendarTitleForeColor = DefaultTitleForeColor;
        private Color                           calendarMonthBackground = DefaultMonthBackColor;
        private Color                           calendarTrailingText = DefaultTrailingForeColor;
        private Font                            calendarFont = null;
        private FontHandleWrapper               calendarFontHandleWrapper = null;
 
        // Since there is no way to get the customFormat from the DTP, we need to
        // cache it. Also we have to track if the user wanted customFormat or
        // shortDate format (shortDate is the lack of being in Long or DateTime format
        // without a customFormat). What fun!
        //
        private string                          customFormat;
 
        private DateTimePickerFormat           format;
 
        private bool                            rightToLeftLayout = false;
 
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.DateTimePicker"]/*' />
        /// <devdoc>
        /// <para>Initializes a new instance of the <see cref='System.Windows.Forms.DateTimePicker'/> class.</para>
        /// </devdoc>
        public DateTimePicker()
        : base() {
            // this class overrides GetPreferredSizeCore, let Control automatically cache the result
            SetState2(STATE2_USEPREFERREDSIZECACHE, true);  
           
            SetStyle(ControlStyles.FixedHeight, true);
 
            // Since DateTimePicker does its own mouse capturing, we do not want
            // to receive standard click events, or we end up with mismatched mouse
            // button up and button down messages.
            //
            SetStyle(ControlStyles.UserPaint |
                     ControlStyles.StandardClick, false);
 
            // Set default flags here...
            //
            format = DateTimePickerFormat.Long;
 
            if (AccessibilityImprovements.Level3) {
                SetStyle(ControlStyles.UseTextForAccessibility, false);
            }
        }
 
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.BackColor"]/*' />
        /// <devdoc>
        ///    <para>[To be supplied.]</para>
        /// </devdoc>
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public override Color BackColor {
            get {
                if (ShouldSerializeBackColor()) {
                    return base.BackColor;
                }
                else {
                    return SystemColors.Window;
                }
            }
            set {
                base.BackColor = value;
            }
        }
 
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.BackColorChanged"]/*' />
        /// <internalonly/>
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        new public event EventHandler BackColorChanged {
            add {
                base.BackColorChanged += value;
            }
            remove {
                base.BackColorChanged -= value;
            }
        }
 
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.BackgroundImage"]/*' />
        /// <devdoc>
        ///    <para>[To be supplied.]</para>
        /// </devdoc>
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public override Image BackgroundImage {
            get {
                return base.BackgroundImage;
            }
            set {
                base.BackgroundImage = value;
            }
        }
 
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.BackgroundImageChanged"]/*' />
        /// <internalonly/>
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        new public event EventHandler BackgroundImageChanged {
            add {
                base.BackgroundImageChanged += value;
            }
            remove {
                base.BackgroundImageChanged -= value;
            }
        }
 
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.BackgroundImageLayout"]/*' />
        /// <devdoc>
        ///    <para>[To be supplied.]</para>
        /// </devdoc>
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public override ImageLayout BackgroundImageLayout {
            get {
                return base.BackgroundImageLayout;
            }
            set {
                base.BackgroundImageLayout = value;
            }
        }
 
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.BackgroundImageLayoutChanged"]/*' />
        /// <internalonly/>
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        new public event EventHandler BackgroundImageLayoutChanged {
            add {
                base.BackgroundImageLayoutChanged += value;
            }
            remove {
                base.BackgroundImageLayoutChanged -= value;
            }
        }
 
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.CalendarForeColor"]/*' />
        /// <devdoc>
        ///     The current value of the CalendarForeColor property.
        /// </devdoc>
        [
        SRCategory(SR.CatAppearance),
        SRDescription(SR.DateTimePickerCalendarForeColorDescr)
        ]
        public Color CalendarForeColor {
            get {
                return calendarForeColor;
            }
 
            set {
                if (value.IsEmpty) {
                    throw new ArgumentException(SR.GetString(SR.InvalidNullArgument,
                                                              "value"));
                }
                if (!value.Equals(calendarForeColor)) {
                    calendarForeColor = value;
                    SetControlColor(NativeMethods.MCSC_TEXT, value);
                }
            }
        }
 
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.CalendarFont"]/*' />
        /// <devdoc>
        ///     The current value of the CalendarFont property.
        /// </devdoc>
        [
        SRCategory(SR.CatAppearance),
        Localizable(true),
        AmbientValue(null),
        SRDescription(SR.DateTimePickerCalendarFontDescr)
        ]
        public Font CalendarFont {
            get {
                if (calendarFont == null) {
                    return Font;
                }
                return calendarFont;
            }
 
            set {
                if ((value == null && calendarFont != null) || (value != null && !value.Equals(calendarFont))) {
                    calendarFont = value;
                    calendarFontHandleWrapper = null;
                    SetControlCalendarFont();
                }
            }
        }
 
        private IntPtr CalendarFontHandle {
            get {
                if (calendarFont == null) {
                    Debug.Assert(calendarFontHandleWrapper == null, "font handle out of sync with Font");
                    return FontHandle;
                }
 
                if (calendarFontHandleWrapper == null) {
                    calendarFontHandleWrapper = new FontHandleWrapper(CalendarFont);
                }
 
                return calendarFontHandleWrapper.Handle;
            }
        }
 
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.CalendarTitleBackColor"]/*' />
        /// <devdoc>
        ///     The current value of the CalendarTitleBackColor property.
        /// </devdoc>
        [
        SRCategory(SR.CatAppearance),
        SRDescription(SR.DateTimePickerCalendarTitleBackColorDescr)
        ]
        public Color CalendarTitleBackColor {
            get {
                return calendarTitleBackColor;
            }
 
            set {
                if (value.IsEmpty) {
                    throw new ArgumentException(SR.GetString(SR.InvalidNullArgument,
                                                              "value"));
                }
                if (!value.Equals(calendarTitleBackColor)) {
                    calendarTitleBackColor = value;
                    SetControlColor(NativeMethods.MCSC_TITLEBK, value);
                }
            }
        }
 
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.CalendarTitleForeColor"]/*' />
        /// <devdoc>
        ///     The current value of the CalendarTitleForeColor property.
        /// </devdoc>
        [
        SRCategory(SR.CatAppearance),
        SRDescription(SR.DateTimePickerCalendarTitleForeColorDescr)
        ]
        public Color CalendarTitleForeColor {
            get {
                return calendarTitleForeColor;
            }
 
            set {
                if (value.IsEmpty) {
                    throw new ArgumentException(SR.GetString(SR.InvalidNullArgument,
                                                              "value"));
                }
                if (!value.Equals(calendarTitleForeColor)) {
                    calendarTitleForeColor = value;
                    SetControlColor(NativeMethods.MCSC_TITLETEXT, value);
                }
            }
        }
 
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.CalendarTrailingForeColor"]/*' />
        /// <devdoc>
        ///     The current value of the CalendarTrailingForeColor property.
        /// </devdoc>
        [
        SRCategory(SR.CatAppearance),
        SRDescription(SR.DateTimePickerCalendarTrailingForeColorDescr)
        ]
        public Color CalendarTrailingForeColor {
            get {
                return calendarTrailingText;
            }
 
            set {
                if (value.IsEmpty) {
                    throw new ArgumentException(SR.GetString(SR.InvalidNullArgument,
                                                              "value"));
                }
                if (!value.Equals(calendarTrailingText)) {
                    calendarTrailingText = value;
                    SetControlColor(NativeMethods.MCSC_TRAILINGTEXT, value);
                }
            }
        }
 
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.CalendarMonthBackground"]/*' />
        /// <devdoc>
        ///     The current value of the CalendarMonthBackground property.
        /// </devdoc>
        [
        SRCategory(SR.CatAppearance),
        SRDescription(SR.DateTimePickerCalendarMonthBackgroundDescr)
        ]
        public Color CalendarMonthBackground {
            get {
                return calendarMonthBackground;
            }
 
            set {
                if (value.IsEmpty) {
                    throw new ArgumentException(SR.GetString(SR.InvalidNullArgument,
                                                              "value"));
                }
                if (!value.Equals(calendarMonthBackground)) {
                    calendarMonthBackground = value;
                    SetControlColor(NativeMethods.MCSC_MONTHBK, value);
                }
            }
        }
 
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.Checked"]/*' />
        /// <devdoc>
        /// <para>Indicates whether the <see cref='System.Windows.Forms.DateTimePicker.Value'/> property has been set.</para>
        /// </devdoc>
        [
        SRCategory(SR.CatBehavior),
        DefaultValue(true),
        Bindable(true),
        SRDescription(SR.DateTimePickerCheckedDescr)
        ]
        public bool Checked {
            get {
                // the information from win32 DateTimePicker is reliable only when ShowCheckBoxes is True
                if (this.ShowCheckBox && IsHandleCreated) {
                    NativeMethods.SYSTEMTIME sys = new NativeMethods.SYSTEMTIME();
                    int gdt = (int)UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), NativeMethods.DTM_GETSYSTEMTIME, 0, sys);
                    return gdt == NativeMethods.GDT_VALID;
                } else {
                    return validTime;
                }
            }
            set {
                if (this.Checked != value) {
                    // set the information into the win32 DateTimePicker only if ShowCheckBoxes is True
                    if (this.ShowCheckBox && IsHandleCreated) {
                        if (value) {
                            int gdt = NativeMethods.GDT_VALID;
                            NativeMethods.SYSTEMTIME sys = DateTimePicker.DateTimeToSysTime(Value);
                            UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), NativeMethods.DTM_SETSYSTEMTIME, gdt, sys);
                        }
                        else {
                            int gdt = NativeMethods.GDT_NONE;
                            NativeMethods.SYSTEMTIME sys = null;
                            UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), NativeMethods.DTM_SETSYSTEMTIME, gdt, sys);
                        }
                    }
                    // this.validTime is used when the DateTimePicker receives date time change notification
                    // from the Win32 control. this.validTime will be used to know when we transition from valid time to unvalid time
                    // also, validTime will be used when ShowCheckBox == false
                    this.validTime = value;
                }
            }
        }
 
        [
        Browsable(false),
        EditorBrowsable(EditorBrowsableState.Never)
        ]
        new public event EventHandler Click {
            add { base.Click += value; }
            remove { base.Click -= value; }
        }
 
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.CreateParams"]/*' />
        /// <devdoc>
        ///     Returns the CreateParams used to create this window.
        /// </devdoc>
        protected override CreateParams CreateParams {
            [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]
            get {
                CreateParams cp = base.CreateParams;
                cp.ClassName = NativeMethods.WC_DATETIMEPICK;
 
                cp.Style |= style;
 
                switch (format) {
                    case DateTimePickerFormat.Long:
                        cp.Style |= NativeMethods.DTS_LONGDATEFORMAT;
                        break;
                    case DateTimePickerFormat.Short:
                        break;
                    case DateTimePickerFormat.Time:
                        cp.Style |= TIMEFORMAT_NOUPDOWN;
                        break;
                    case DateTimePickerFormat.Custom:
                        break;
                }
 
                cp.ExStyle |= NativeMethods.WS_EX_CLIENTEDGE;
 
                if (RightToLeft == RightToLeft.Yes && RightToLeftLayout == true) {
                    //We want to turn on mirroring for DateTimePicker explicitly.
                    cp.ExStyle |= NativeMethods.WS_EX_LAYOUTRTL;
                    //Don't need these styles when mirroring is turned on.
                    cp.ExStyle &= ~(NativeMethods.WS_EX_RTLREADING | NativeMethods.WS_EX_RIGHT | NativeMethods.WS_EX_LEFTSCROLLBAR);
                }
 
                return cp;
            }
        }
 
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.CustomFormat"]/*' />
        /// <devdoc>
        ///     Returns the custom format.
        /// </devdoc>
        [
        DefaultValue(null),
        Localizable(true),
        RefreshProperties(RefreshProperties.Repaint),
        SRCategory(SR.CatBehavior),
        SRDescription(SR.DateTimePickerCustomFormatDescr)
        ]
        public string CustomFormat {
            get {
                return customFormat;
            }
 
            set {
                if ((value != null && !value.Equals(customFormat)) ||
                    (value == null && customFormat != null)) {
 
                    customFormat = value;
 
                    if (IsHandleCreated) {
                        if (format == DateTimePickerFormat.Custom)
                            SendMessage(NativeMethods.DTM_SETFORMAT, 0, customFormat);
                    }
                }
            }
        }
 
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.DefaultSize"]/*' />
        /// <devdoc>
        ///     Deriving classes can override this to configure a default size for their control.
        ///     This is more efficient than setting the size in the control's constructor.
        /// </devdoc>
        protected override Size DefaultSize {
            get {
                return new Size(200, PreferredHeight);
            }
        }
 
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.DoubleBuffered"]/*' />
        /// <devdoc>
        ///     This property is overridden and hidden from statement completion
        ///     on controls that are based on Win32 Native Controls.
        /// </devdoc>
        [EditorBrowsable(EditorBrowsableState.Never)]
        protected override bool DoubleBuffered {
            get {
                return base.DoubleBuffered;
            }
            set {
                base.DoubleBuffered = value;
            }
        }
 
        [
        Browsable(false),
        EditorBrowsable(EditorBrowsableState.Never)
        ]
        new public event EventHandler DoubleClick {
            add { base.DoubleClick += value; }
            remove { base.DoubleClick -= value; }
        }
 
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.DropDownAlign"]/*' />
        /// <devdoc>
        ///     The current value of the dropDownAlign property.  The calendar
        ///     dropDown can be aligned to the left or right of the control.
        /// </devdoc>
        [
        DefaultValue(LeftRightAlignment.Left),
        SRCategory(SR.CatAppearance),
        Localizable(true),
        SRDescription(SR.DateTimePickerDropDownAlignDescr)
        ]
        public LeftRightAlignment DropDownAlign {
            get {
                return((style & NativeMethods.DTS_RIGHTALIGN) != 0)
                ? LeftRightAlignment.Right
                : LeftRightAlignment.Left;
            }
 
            set {
                //valid values are 0x0 to 0x1
                if (!ClientUtils.IsEnumValid(value, (int)value, (int)LeftRightAlignment.Left, (int)LeftRightAlignment.Right)){
                    throw new InvalidEnumArgumentException("value", (int)value, typeof(LeftRightAlignment));
                }
 
                SetStyleBit((value == LeftRightAlignment.Right), NativeMethods.DTS_RIGHTALIGN);
            }
        }
 
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.ForeColor"]/*' />
        /// <devdoc>
        ///    <para>[To be supplied.]</para>
        /// </devdoc>
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public override Color ForeColor {
            get {
                if (ShouldSerializeForeColor()) {
                    return base.ForeColor;
                }
                else {
                    return SystemColors.WindowText;
                }
            }
            set {
                base.ForeColor = value;
            }
        }
 
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.ForeColorChanged"]/*' />
        /// <internalonly/>
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        new public event EventHandler ForeColorChanged {
            add {
                base.ForeColorChanged += value;
            }
            remove {
                base.ForeColorChanged -= value;
            }
        }
 
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.Format"]/*' />
        /// <devdoc>
        ///     Returns the current value of the format property. This determines the
        ///     style of format the date is displayed in.
        /// </devdoc>
        [
        SRCategory(SR.CatAppearance),
        RefreshProperties(RefreshProperties.Repaint),
        SRDescription(SR.DateTimePickerFormatDescr)
        ]
        public DateTimePickerFormat Format {
            get {
                return format;
            }
 
            set {
                //valid values are 0x1, 0x2,0x4,0x8. max number of bits on at a time is 1
                if (!ClientUtils.IsEnumValid(value, (int)value, (int)DateTimePickerFormat.Long, (int)DateTimePickerFormat.Custom, /*maxNumberOfBitsOn*/1))
                {
                    throw new InvalidEnumArgumentException("value", (int)value, typeof(DateTimePickerFormat));
                }
 
                if (format != value) {
 
                    format = value;
                    RecreateHandle();
 
                    OnFormatChanged(EventArgs.Empty);
                }
            }
        }
 
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.FormatChanged"]/*' />
        /// <devdoc>
        ///    <para>[To be supplied.]</para>
        /// </devdoc>
        [SRCategory(SR.CatPropertyChanged), SRDescription(SR.DateTimePickerOnFormatChangedDescr)]
        public event EventHandler FormatChanged {
            add {
                Events.AddHandler(EVENT_FORMATCHANGED, value);
            }
            remove {
                Events.RemoveHandler(EVENT_FORMATCHANGED, value);
            }
        }
 
        /// <include file='doc\DateTimepicker.uex' path='docs/doc[@for="DateTimepicker.Paint"]/*' />
        /// <devdoc>
        ///     DateTimePicker Paint.
        /// </devdoc>
        /// <internalonly/><hideinheritance/>
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public new event PaintEventHandler Paint {
            add {
                base.Paint += value;
            }
            remove {
                base.Paint -= value;
            }
        }
 
        //Make sure the passed in minDate respects the current culture: this
        //is especially important if the culture changes from a Gregorian or 
        //other calendar with a lowish minDate (see comment on MinimumDateTime)
        //to ----'s calendar, which has a minimum date of 1/1/1912 (VSW 400284).
        static internal DateTime EffectiveMinDate(DateTime minDate)
        {
            DateTime minSupportedDate = DateTimePicker.MinimumDateTime;
            if (minDate < minSupportedDate)
            {
                return minSupportedDate;
            }
            return minDate;
        }
 
        //Similarly, make sure the maxDate respects the current culture.  No
        //problems are anticipated here: I don't believe there are calendars 
        //around that have max dates on them.  But if there are, we'll deal with
        //them correctly.
        static internal DateTime EffectiveMaxDate(DateTime maxDate)
        {
            DateTime maxSupportedDate = DateTimePicker.MaximumDateTime;
            if (maxDate > maxSupportedDate)
            {
                return maxSupportedDate;
            }
            return maxDate;
        }
 
 
 
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.MaxDate"]/*' />
        /// <devdoc>
        ///    <para> Indicates the maximum date and time
        ///       selectable in the control.</para>
        /// </devdoc>
        [
        SRCategory(SR.CatBehavior),
        SRDescription(SR.DateTimePickerMaxDateDescr)
        ]
        public DateTime MaxDate {
            get {
                return EffectiveMaxDate(max);
            }
            set {
                if (value != max) {
                    if (value < EffectiveMinDate(min))
                    {
                        throw new ArgumentOutOfRangeException("MaxDate", SR.GetString(SR.InvalidLowBoundArgumentEx, "MaxDate", FormatDateTime(value), "MinDate"));
                    }
 
                    // If trying to set the maximum greater than MaxDateTime, throw.
                    if (value > MaximumDateTime) {
                        throw new ArgumentOutOfRangeException("MaxDate", SR.GetString(SR.DateTimePickerMaxDate, FormatDateTime(DateTimePicker.MaxDateTime)));
                    }
 
                    max = value;
                    SetRange();
 
                    //If Value (which was once valid) is suddenly greater than the max (since we just set it)
                    //then adjust this...
                    if (Value > max) {
                        Value = max;
                    }
                }
            }
        }
 
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.MaximumDateTime"]/*' />
        /// <devdoc>
        ///    <para>Specifies the maximum date value. This property is read-only.</para>
        /// </devdoc>
        public static DateTime MaximumDateTime {
		get {
                 DateTime maxSupportedDateTime = CultureInfo.CurrentCulture.Calendar.MaxSupportedDateTime;
                 if (maxSupportedDateTime.Year > MaxDateTime.Year)
                 {
                     return MaxDateTime;
                 }
                 return maxSupportedDateTime;
             }
        }
 
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.MinDate"]/*' />
        /// <devdoc>
        ///    <para> Indicates the minimum date and time
        ///       selectable in the control.</para>
        /// </devdoc>
        [
        SRCategory(SR.CatBehavior),
        SRDescription(SR.DateTimePickerMinDateDescr)
        ]
        public DateTime MinDate {
            get {
                return EffectiveMinDate(min);
            }
            set
            {
                if (value != min)
                {
                    if (value > EffectiveMaxDate(max))
                    {
                        throw new ArgumentOutOfRangeException("MinDate", SR.GetString(SR.InvalidHighBoundArgument, "MinDate", FormatDateTime(value), "MaxDate"));
                    }
 
                    // If trying to set the minimum less than MinimumDateTime, throw.
                    if (value < MinimumDateTime)
                    {
                        throw new ArgumentOutOfRangeException("MinDate", SR.GetString(SR.DateTimePickerMinDate, FormatDateTime(DateTimePicker.MinimumDateTime)));
                    }
 
                    min = value;
                    SetRange();
 
                    //If Value (which was once valid) is suddenly less than the min (since we just set it)
                    //then adjust this...
                    if (Value < min)
                    {
                        Value = min;
                    }
                }
            }
        }
 
        // We restrict the available dates to >= 1753 because of oddness in the Gregorian calendar about
        // that time.  We do this even for cultures that don't use the Gregorian calendar -- we're not
        // really that worried about calendars for >250 years ago.
        //
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.MinimumDateTime"]/*' />
        /// <devdoc>
        ///    <para>Specifies the minimum date value. This property is read-only.</para>
        /// </devdoc>
        public static DateTime MinimumDateTime {
             get {
                 DateTime minSupportedDateTime = CultureInfo.CurrentCulture.Calendar.MinSupportedDateTime;
                 if (minSupportedDateTime.Year < 1753)
                 {
                     return new DateTime(1753, 1, 1);
                 }
                 return minSupportedDateTime;
             }
        }
 
        [
        Browsable(false),
        EditorBrowsable(EditorBrowsableState.Never)
        ]
        new public event MouseEventHandler MouseClick {
            add { base.MouseClick += value; }
            remove { base.MouseClick -= value; }
        }
 
        [
        Browsable(false),
        EditorBrowsable(EditorBrowsableState.Never)
        ]
        new public event MouseEventHandler MouseDoubleClick {
            add { base.MouseDoubleClick += value; }
            remove { base.MouseDoubleClick -= value; }
        }
 
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.Padding"]/*' />
        /// <devdoc>
        ///    <para>
        ///    <para>[To be supplied.]</para>
        ///    </para>
        /// </devdoc>
        [
        Browsable(false),
        EditorBrowsable(EditorBrowsableState.Never),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
        ]
        public new Padding Padding {
            get { return base.Padding; }
            set { base.Padding = value;}
        }
 
        [
        Browsable(false),
        EditorBrowsable(EditorBrowsableState.Never)
        ]
        public new event EventHandler PaddingChanged {
            add { base.PaddingChanged += value; }
            remove { base.PaddingChanged -= value; }
        }
 
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.PreferredHeight"]/*' />
        /// <devdoc>
        ///    <para>Indicates the preferred height of the DateTimePicker control. This property is read-only.</para>
        /// </devdoc>
        [
        Browsable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
        ]
        public int PreferredHeight {
            get {
                if (prefHeightCache > -1)
                    return(int)prefHeightCache;
 
                // Base the preferred height on the current font
                int height = FontHeight;
 
                // Adjust for the border
                height += SystemInformation.BorderSize.Height * 4 + 3;
                prefHeightCache = (short)height;
 
                return height;
            }
        }
 
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.RightToLeftLayout"]/*' />
        /// <devdoc>
        ///     This is used for international applications where the language
        ///     is written from RightToLeft. When this property is true,
        //      and the RightToLeft is true, mirroring will be turned on on the form, and
        ///     control placement and text will be from right to left.
        /// </devdoc>
        [
        SRCategory(SR.CatAppearance),
        Localizable(true),
        DefaultValue(false),
        SRDescription(SR.ControlRightToLeftLayoutDescr)
        ]
        public virtual bool RightToLeftLayout {
            get {
 
                return rightToLeftLayout;
            }
 
            set {
                if (value != rightToLeftLayout) {
                    rightToLeftLayout = value;
                    using(new LayoutTransaction(this, this, PropertyNames.RightToLeftLayout)) {
                        OnRightToLeftLayoutChanged(EventArgs.Empty);
                    }
                }
            }
        }
 
 
 
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.ShowCheckBox"]/*' />
        /// <devdoc>
        ///    <para>
        ///       Indicates whether a check box is displayed to toggle the NoValueSelected property
        ///       value.</para>
        /// </devdoc>
        [
        DefaultValue(false),
        SRCategory(SR.CatAppearance),
        SRDescription(SR.DateTimePickerShowNoneDescr)
        ]
        public bool ShowCheckBox {
            get {
                return(style & NativeMethods.DTS_SHOWNONE) != 0;
            }
            set {
                SetStyleBit(value, NativeMethods.DTS_SHOWNONE);
            }
        }
 
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.ShowUpDown"]/*' />
        /// <devdoc>
        ///    <para> Indicates
        ///       whether an up-down control is used to adjust the time values.</para>
        /// </devdoc>
        [
        DefaultValue(false),
        SRCategory(SR.CatAppearance),
        SRDescription(SR.DateTimePickerShowUpDownDescr)
        ]
        public bool ShowUpDown {
            get {
                return(style & NativeMethods.DTS_UPDOWN) != 0;
            }
            set {
                if (ShowUpDown != value) {
                    SetStyleBit(value, NativeMethods.DTS_UPDOWN);
                }
            }
        }
 
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.Text"]/*' />
        /// <devdoc>
        ///     Overrides Text to allow for setting of the value via a string.  Also, returns
        ///     a formatted Value when getting the text.  The DateTime class will throw
        ///     an exception if the string (value) being passed in is invalid.
        /// </devdoc>
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Advanced), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override string Text {
            get {
                return base.Text;
            }
            set {
                // Clause to check length
                //
                if (value == null || value.Length == 0) {
                    ResetValue();
                }
                else {
                    Value = DateTime.Parse(value, CultureInfo.CurrentCulture);
                }
            }
        }
 
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.TextChanged"]/*' />
        /// <internalonly/>
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Advanced)]
        new public event EventHandler TextChanged {
            add {
                base.TextChanged += value;
            }
            remove {
                base.TextChanged -= value;
            }
        }
 
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.Value"]/*' />
        /// <devdoc>
        ///    <para>Indicates the DateTime value assigned to the control.</para>
        /// </devdoc>
        [
        SRCategory(SR.CatBehavior),
        Bindable(true),
        RefreshProperties(RefreshProperties.All),
        SRDescription(SR.DateTimePickerValueDescr)
        ]
        public DateTime Value {
            get {
                //checkbox clicked, no value set - no value set state should never occur, but just in case
                if (!userHasSetValue && validTime)
                    return creationTime;
                else
                    return value;
            }
            set {
                bool valueChanged = !DateTime.Equals(this.Value, value);
                // Check for value set here; if we've not set the value yet, it'll be Now, so the second
                // part of the test will fail.
                // So, if userHasSetValue isn't set, we don't care if the value is still the same - and we'll
                // update anyway.
                if (!userHasSetValue || valueChanged) {
                    if ((value < MinDate) || (value > MaxDate)) {
                        throw new ArgumentOutOfRangeException("Value", SR.GetString(SR.InvalidBoundArgument, "Value", FormatDateTime(value), "'MinDate'", "'MaxDate'"));
                    }
 
                    string oldText = this.Text;
 
                    this.value = value;
                    userHasSetValue = true;
 
                    if (IsHandleCreated) {
                        /*
                        * Make sure any changes to this code
                        * get propagated to createHandle
                        */
                        int gdt = NativeMethods.GDT_VALID;
                        NativeMethods.SYSTEMTIME sys = DateTimePicker.DateTimeToSysTime(value);
                        UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), NativeMethods.DTM_SETSYSTEMTIME, gdt, sys);
                    }
 
                    if (valueChanged) {
                        OnValueChanged(EventArgs.Empty);
                    }
 
                    if (!oldText.Equals(this.Text)) {
                        OnTextChanged(EventArgs.Empty);
                    }
                }
            }
        }
 
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.CloseUp"]/*' />
        /// <devdoc>
        ///    <para>Occurs when the dropdown calendar is dismissed and disappears.</para>
        /// </devdoc>
        [SRCategory(SR.CatAction), SRDescription(SR.DateTimePickerOnCloseUpDescr)]
        public event EventHandler CloseUp {
            add {
                onCloseUp += value;
            }
            remove {
                onCloseUp -= value;
            }
        }
 
 
        /// <include file='doc\Form.uex' path='docs/doc[@for="Form.RightToLeftLayoutChanged"]/*' />
        /// <devdoc>
        ///    <para>[To be supplied.]</para>
        /// </devdoc>
        [SRCategory(SR.CatPropertyChanged), SRDescription(SR.ControlOnRightToLeftLayoutChangedDescr)]
        public event EventHandler RightToLeftLayoutChanged {
            add {
                onRightToLeftLayoutChanged += value;
            }
            remove {
                onRightToLeftLayoutChanged -= value;
            }
        }
 
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.ValueChanged"]/*' />
        /// <devdoc>
        ///    <para>Occurs when the value for the control changes.</para>
        /// </devdoc>
        [SRCategory(SR.CatAction), SRDescription(SR.valueChangedEventDescr)]
        public event EventHandler ValueChanged {
            add {
                onValueChanged += value;
            }
            remove {
                onValueChanged -= value;
            }
        }
 
 
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.DropDown"]/*' />
        /// <devdoc>
        ///    <para>Occurs when the drop down calendar is shown.</para>
        /// </devdoc>
        [SRCategory(SR.CatAction), SRDescription(SR.DateTimePickerOnDropDownDescr)]
        public event EventHandler DropDown {
            add {
                onDropDown += value;
            }
            remove {
                onDropDown -= value;
            }
        }
     
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.CreateAccessibilityInstance"]/*' />
        /// <internalonly/>
        /// <summary>
        /// <para>
        /// Constructs the new instance of the accessibility object for this control. Subclasses
        /// should not call base.CreateAccessibilityObject.
        /// </para>
        /// </summary>
        protected override AccessibleObject CreateAccessibilityInstance() {
            return new DateTimePickerAccessibleObject(this);
        }
 
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.CreateHandle"]/*' />
        /// <devdoc>
        ///     Creates the physical window handle.
        /// </devdoc>
        protected override void CreateHandle() {
            if (!RecreatingHandle) {
                IntPtr userCookie = UnsafeNativeMethods.ThemingScope.Activate();
                        
                try {
                    NativeMethods.INITCOMMONCONTROLSEX icc = new NativeMethods.INITCOMMONCONTROLSEX();
                    icc.dwICC = NativeMethods.ICC_DATE_CLASSES;
                    SafeNativeMethods.InitCommonControlsEx(icc);
                }
                finally {
                    UnsafeNativeMethods.ThemingScope.Deactivate(userCookie);
                }
            }
 
            creationTime = DateTime.Now;
 
            base.CreateHandle();
 
            if (userHasSetValue && validTime) {
                /*
                * Make sure any changes to this code
                * get propagated to setValue
                */
                int gdt = NativeMethods.GDT_VALID;
                NativeMethods.SYSTEMTIME sys = DateTimePicker.DateTimeToSysTime(Value);
                UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), NativeMethods.DTM_SETSYSTEMTIME, gdt, sys);
            }
            else if (!validTime) {
                int gdt = NativeMethods.GDT_NONE;
                NativeMethods.SYSTEMTIME sys = null;
                UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), NativeMethods.DTM_SETSYSTEMTIME, gdt, sys);
            }
 
            if (format == DateTimePickerFormat.Custom) {
                SendMessage(NativeMethods.DTM_SETFORMAT, 0, customFormat);
            }
 
            UpdateUpDown();
            SetAllControlColors();
            SetControlCalendarFont();
            SetRange();
        }
 
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.DestroyHandle"]/*' />
        /// <devdoc>
        ///     Destroys the physical window handle.
        /// </devdoc>
        [UIPermission(SecurityAction.LinkDemand, Window=UIPermissionWindow.AllWindows)]
        protected override void DestroyHandle() {
            value = Value;
            base.DestroyHandle();
        }
 
        // Return a localized string representation of the given DateTime value.
        // Used for throwing exceptions, etc.
        //
        private static string FormatDateTime(DateTime value) {
            return value.ToString("G", CultureInfo.CurrentCulture);
        }
 
        // GetPreferredSize and SetBoundsCore call this method to allow controls to self impose
        // constraints on their size.
        internal override Rectangle ApplyBoundsConstraints(int suggestedX, int suggestedY, int proposedWidth, int proposedHeight) {
              // Lock DateTimePicker to its preferred height.
            return base.ApplyBoundsConstraints(suggestedX,suggestedY, proposedWidth, PreferredHeight);
        }
 
        internal override Size GetPreferredSizeCore(Size proposedConstraints) {
            int height = PreferredHeight;
            int width = CommonProperties.GetSpecifiedBounds(this).Width;
            return new Size(width, height);
        }
 
 
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.IsInputKey"]/*' />
        /// <devdoc>
        ///      Handling special input keys, such as pgup, pgdown, home, end, etc...
        /// </devdoc>
        protected override bool IsInputKey(Keys keyData) {
            if ((keyData & Keys.Alt) == Keys.Alt) return false;
            switch (keyData & Keys.KeyCode) {
                case Keys.PageUp:
                case Keys.PageDown:
                case Keys.Home:
                case Keys.End:
                    return true;
            }
            return base.IsInputKey(keyData);
        }
 
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.OnCloseUp"]/*' />
        /// <devdoc>
        /// <para>Raises the <see cref='System.Windows.Forms.DateTimePicker.CloseUp'/>
        /// event.</para>
        /// </devdoc>
        protected virtual void OnCloseUp(EventArgs eventargs) {
            if (onCloseUp != null) onCloseUp(this, eventargs);
        }
 
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.OnDropDown"]/*' />
        /// <devdoc>
        /// <para>Raises the <see cref='System.Windows.Forms.DateTimePicker.DropDown'/> event.</para>
        /// </devdoc>
        protected virtual void OnDropDown(EventArgs eventargs) {
            if (onDropDown != null) {
                onDropDown(this, eventargs);
            }
        }
 
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.OnFormatChanged"]/*' />
        /// <devdoc>
        ///    <para>[To be supplied.]</para>
        /// </devdoc>
        protected virtual void OnFormatChanged(EventArgs e) {
            EventHandler eh = Events[EVENT_FORMATCHANGED] as EventHandler;
            if (eh != null) {
                 eh(this, e);
            }
        }
 
 
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.OnHandleCreated"]/*' />
        /// <devdoc>
        ///    <para>Add/remove SystemEvents in OnHandleCreated/Destroyed for robustness</para>
        /// </devdoc>
        protected override void OnHandleCreated(EventArgs e)
        {
            base.OnHandleCreated(e);
            SystemEvents.UserPreferenceChanged += new UserPreferenceChangedEventHandler(this.MarshaledUserPreferenceChanged);
        }
 
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.OnHandleDestroyed"]/*' />
        /// <devdoc>
        ///    <para>Add/remove SystemEvents in OnHandleCreated/Destroyed for robustness</para>
        /// </devdoc>
        protected override void OnHandleDestroyed(EventArgs e)
        {
            SystemEvents.UserPreferenceChanged -= new UserPreferenceChangedEventHandler(this.MarshaledUserPreferenceChanged);
            base.OnHandleDestroyed(e);
        }
 
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.OnValueChanged"]/*' />
        /// <devdoc>
        /// <para>Raises the <see cref='System.Windows.Forms.DateTimePicker.ValueChanged'/> event.</para>
        /// </devdoc>
        protected virtual void OnValueChanged(EventArgs eventargs) {
            if (onValueChanged != null) {
                onValueChanged(this, eventargs);
            }
        }
 
        /// <include file='doc\Form.uex' path='docs/doc[@for="Form.OnRightToLeftLayoutChanged"]/*' />
        /// <devdoc>
        ///    <para>[To be supplied.]</para>
        /// </devdoc>
        [EditorBrowsable(EditorBrowsableState.Advanced)]
        protected virtual void OnRightToLeftLayoutChanged(EventArgs e) {
            if (GetAnyDisposingInHierarchy()) {
                return;
            }
 
            if (RightToLeft == RightToLeft.Yes) {
                RecreateHandle();
            }
 
            if (onRightToLeftLayoutChanged != null) {
                 onRightToLeftLayoutChanged(this, e);
            }
        }
 
 
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.OnFontChanged"]/*' />
        /// <internalonly/>
        /// <devdoc>
        ///    Occurs when a property for the control changes.
        /// </devdoc>
        protected override void OnFontChanged(EventArgs e) {
            base.OnFontChanged(e);
 
            //clear the pref height cache
            prefHeightCache = -1;
 
            Height = PreferredHeight;
 
            if (calendarFont == null) {
                calendarFontHandleWrapper = null;
                SetControlCalendarFont();
            }
        }
 
        private void ResetCalendarForeColor() {
            CalendarForeColor = DefaultForeColor;
        }
 
        private void ResetCalendarFont() {
            CalendarFont = null;
        }
 
        private void ResetCalendarMonthBackground() {
            CalendarMonthBackground =  DefaultMonthBackColor;
        }
 
        private void ResetCalendarTitleBackColor() {
            CalendarTitleBackColor = DefaultTitleBackColor;
        }
 
        private void ResetCalendarTitleForeColor() {
            CalendarTitleBackColor = DefaultForeColor;
        }
 
        private void ResetCalendarTrailingForeColor() {
            CalendarTrailingForeColor = DefaultTrailingForeColor;
        }
 
        /// <devdoc>
        /// <para>Resets the <see cref='System.Windows.Forms.DateTimePicker.Format'/> property to its default
        ///    value.</para>
        /// </devdoc>
        private void ResetFormat() {
            Format = DateTimePickerFormat.Long;
        }
 
        /// <devdoc>
        /// <para>Resets the <see cref='System.Windows.Forms.DateTimePicker.MaxDate'/> property to its default value. </para>
        /// </devdoc>
        private void ResetMaxDate() {
            MaxDate = MaximumDateTime;
        }
 
        /// <devdoc>
        /// <para>Resets the <see cref='System.Windows.Forms.DateTimePicker.MinDate'/> property to its default value. </para>
        /// </devdoc>
        private void ResetMinDate() {
            MinDate = MinimumDateTime;
        }
 
        /// <devdoc>
        /// <para> Resets the <see cref='System.Windows.Forms.DateTimePicker.Value'/> property to its default value.</para>
        /// </devdoc>
        private void ResetValue() {
 
            // always update on reset with ShowNone = false -- as it'll take the current time.
            this.value = DateTime.Now;
 
            // If ShowCheckBox = true, then userHasSetValue can be false (null value).
            // otherwise, userHasSetValue is valid...
            // userHasSetValue = !ShowCheckBox;
 
            // After ResetValue() the flag indicating whether the user
            // has set the value should be false.
            userHasSetValue = false;
 
            // Update the text displayed in the DateTimePicker
            if (IsHandleCreated) {
                int gdt = NativeMethods.GDT_VALID;
                NativeMethods.SYSTEMTIME sys = DateTimePicker.DateTimeToSysTime(value);
                UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), NativeMethods.DTM_SETSYSTEMTIME, gdt, sys);
            }
 
            // Updating Checked to false will set the control to "no date",
            // and clear its checkbox.
            Checked = false;
 
            OnValueChanged(EventArgs.Empty);
            OnTextChanged(EventArgs.Empty);
        }
 
        /// <devdoc>
        ///     If the handle has been created, this applies the color to the control
        /// </devdoc>
        /// <internalonly/>
        private void SetControlColor(int colorIndex, Color value) {
            if (IsHandleCreated) {
                SendMessage(NativeMethods.DTM_SETMCCOLOR, colorIndex, ColorTranslator.ToWin32(value));
            }
        }
 
        /// <devdoc>
        ///     If the handle has been created, this applies the font to the control.
        /// </devdoc>
        /// <internalonly/>
        private void SetControlCalendarFont() {
            if (IsHandleCreated) {
                SendMessage(NativeMethods.DTM_SETMCFONT, CalendarFontHandle, NativeMethods.InvalidIntPtr);
            }
        }
 
        /// <devdoc>
        ///     Applies all the colors to the control.
        /// </devdoc>
        /// <internalonly/>
        private void SetAllControlColors() {
            SetControlColor(NativeMethods.MCSC_MONTHBK, calendarMonthBackground);
            SetControlColor(NativeMethods.MCSC_TEXT, calendarForeColor);
            SetControlColor(NativeMethods.MCSC_TITLEBK, calendarTitleBackColor);
            SetControlColor(NativeMethods.MCSC_TITLETEXT, calendarTitleForeColor);
            SetControlColor(NativeMethods.MCSC_TRAILINGTEXT, calendarTrailingText);
        }
 
        /// <devdoc>
        ///     Updates the window handle with the min/max ranges if it has been
        ///     created.
        /// </devdoc>
        /// <internalonly/>
        private void SetRange() {
            SetRange(EffectiveMinDate(min), EffectiveMaxDate(max));
        }
 
        private void SetRange(DateTime min, DateTime max) {
            if (IsHandleCreated) {
                int flags = 0;
 
                NativeMethods.SYSTEMTIMEARRAY sa = new NativeMethods.SYSTEMTIMEARRAY();
 
                flags |= NativeMethods.GDTR_MIN | NativeMethods.GDTR_MAX;
                NativeMethods.SYSTEMTIME sys = DateTimePicker.DateTimeToSysTime(min);
                sa.wYear1 = sys.wYear;
                sa.wMonth1 = sys.wMonth;
                sa.wDayOfWeek1 = sys.wDayOfWeek;
                sa.wDay1 = sys.wDay;
                sa.wHour1 = sys.wHour;
                sa.wMinute1 = sys.wMinute;
                sa.wSecond1 = sys.wSecond;
                sa.wMilliseconds1 = sys.wMilliseconds;
                sys = DateTimePicker.DateTimeToSysTime(max);
                sa.wYear2 = sys.wYear;
                sa.wMonth2 = sys.wMonth;
                sa.wDayOfWeek2 = sys.wDayOfWeek;
                sa.wDay2 = sys.wDay;
                sa.wHour2 = sys.wHour;
                sa.wMinute2 = sys.wMinute;
                sa.wSecond2 = sys.wSecond;
                sa.wMilliseconds2 = sys.wMilliseconds;
                UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), NativeMethods.DTM_SETRANGE, flags, sa);
            }
        }
 
        /// <devdoc>
        ///     Turns on or off a given style bit
        /// </devdoc>
        /// <internalonly/>
        private void SetStyleBit(bool flag, int bit) {
            if (((style & bit) != 0) == flag) return;
 
            if (flag) {
                style |= bit;
            }
            else {
                style &= ~bit;
            }
 
            if (IsHandleCreated) {
                RecreateHandle();
                Invalidate();
                Update();
            }
        }
 
        /// <devdoc>
        /// <para> Determines if the <see cref='System.Windows.Forms.DateTimePicker.CalendarForeColor'/> property needs to be
        ///    persisted.</para>
        /// </devdoc>
        private bool ShouldSerializeCalendarForeColor() {
            return !CalendarForeColor.Equals(DefaultForeColor);
        }
 
        /// <devdoc>
        /// <para>Determines if the <see cref='System.Windows.Forms.DateTimePicker.CalendarFont'/> property needs to be persisted.</para>
        /// </devdoc>
        private bool ShouldSerializeCalendarFont() {
            return calendarFont != null;
        }
 
        /// <devdoc>
        /// <para>Determines if the <see cref='System.Windows.Forms.DateTimePicker.CalendarTitleBackColor'/> property needs to be persisted.</para>
        /// </devdoc>
        private bool ShouldSerializeCalendarTitleBackColor() {
            return !calendarTitleBackColor.Equals(DefaultTitleBackColor);
        }
 
        /// <devdoc>
        /// <para>Determines if the <see cref='System.Windows.Forms.DateTimePicker.CalendarTitleForeColor'/> property needs to be persisted.</para>
        /// </devdoc>
        private bool ShouldSerializeCalendarTitleForeColor() {
            return !calendarTitleForeColor.Equals(DefaultTitleForeColor);
        }
 
        /// <devdoc>
        /// <para>Determines if the <see cref='System.Windows.Forms.DateTimePicker.CalendarTrailingForeColor'/> property needs to be persisted.</para>
        /// </devdoc>
        private bool ShouldSerializeCalendarTrailingForeColor() {
            return !calendarTrailingText.Equals(DefaultTrailingForeColor);
        }
 
        /// <devdoc>
        /// <para>Determines if the <see cref='System.Windows.Forms.DateTimePicker.CalendarMonthBackground'/> property needs to be persisted.</para>
        /// </devdoc>
        private bool ShouldSerializeCalendarMonthBackground() {
            return !calendarMonthBackground.Equals(DefaultMonthBackColor);
        }
 
        /// <devdoc>
        /// <para>Determines if the <see cref='System.Windows.Forms.DateTimePicker.MaxDate'/> property needs to be persisted.</para>
        /// </devdoc>
        private bool ShouldSerializeMaxDate() {
            return max != MaximumDateTime && max != DateTime.MaxValue;
        }
 
        /// <devdoc>
        /// <para>Determines if the <see cref='System.Windows.Forms.DateTimePicker.MinDate'/> property needs to be persisted.</para>
        /// </devdoc>
        private bool ShouldSerializeMinDate() {
            return min != MinimumDateTime && min != DateTime.MinValue;
        }
 
        /// <devdoc>
        /// <para>Determines if the <see cref='System.Windows.Forms.DateTimePicker.Value'/> property needs to be persisted.</para>
        /// </devdoc>
        private bool ShouldSerializeValue() {
            return userHasSetValue;
        }
 
        /// <devdoc>
        /// <para>Determines if the <see cref='System.Windows.Forms.DateTimePicker.Format'/> property needs to be persisted.</para>
        /// </devdoc>
        private bool ShouldSerializeFormat() {
            return(Format != DateTimePickerFormat.Long);
        }
 
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.ToString"]/*' />
        /// <devdoc>
        ///     Returns the control as a string
        /// </devdoc>
        /// <internalonly/>
        public override string ToString() {
 
            string s = base.ToString();
            return s + ", Value: " + FormatDateTime(Value);
        }
 
        /// <devdoc>
        ///     Forces a repaint of the updown control if it is displayed.
        /// </devdoc>
        /// <internalonly/>
        private void UpdateUpDown() {
            // The upDown control doesn't repaint correctly.
            //
            if (ShowUpDown) {
                EnumChildren c = new EnumChildren();
                NativeMethods.EnumChildrenCallback cb = new NativeMethods.EnumChildrenCallback(c.enumChildren);
                UnsafeNativeMethods.EnumChildWindows(new HandleRef(this, Handle), cb, NativeMethods.NullHandleRef);
                if (c.hwndFound != IntPtr.Zero) {
                    SafeNativeMethods.InvalidateRect(new HandleRef(c, c.hwndFound), null, true);
                    SafeNativeMethods.UpdateWindow(new HandleRef(c, c.hwndFound));
                }
            }
        }
 
        private void MarshaledUserPreferenceChanged(object sender, UserPreferenceChangedEventArgs pref) {
            try {
                //use begininvoke instead of invoke in case the destination thread is not processing messages.
                BeginInvoke(new UserPreferenceChangedEventHandler(this.UserPreferenceChanged), new object[] { sender, pref });
            }
            catch (InvalidOperationException) { } //if the destination thread does not exist, don't send.
        }
 
        private void UserPreferenceChanged(object sender, UserPreferenceChangedEventArgs pref) {
            if (pref.Category == UserPreferenceCategory.Locale) {
               // We need to recreate the monthcalendar handle when the locale changes, because
                // the day names etc. are only updated on a handle recreate (comctl32 limitation).
                //
                RecreateHandle();
            }
        }
 
        /// <devdoc>
        ///     Handles the DTN_CLOSEUP notification
        /// </devdoc>
        /// <internalonly/>
        private void WmCloseUp(ref Message m) {
            OnCloseUp(EventArgs.Empty);
        }
 
        /// <devdoc>
        ///     Handles the DTN_DATETIMECHANGE notification
        /// </devdoc>
        /// <internalonly/>
        private void WmDateTimeChange(ref Message m) {
            NativeMethods.NMDATETIMECHANGE nmdtc = (NativeMethods.NMDATETIMECHANGE)m.GetLParam(typeof(NativeMethods.NMDATETIMECHANGE));
            DateTime temp = value;
            bool oldvalid = validTime;
            if (nmdtc.dwFlags != NativeMethods.GDT_NONE) {
                validTime = true;
                value = DateTimePicker.SysTimeToDateTime(nmdtc.st);
                userHasSetValue = true;
            }
            else {
                validTime = false;
            }
            if (value!=temp || oldvalid != validTime) {
                OnValueChanged(EventArgs.Empty);
                OnTextChanged(EventArgs.Empty);
            }
        }
 
        /// <devdoc>
        ///     Handles the DTN_DROPDOWN notification
        /// </devdoc>
        /// <internalonly/>
        private void WmDropDown(ref Message m) {
 
            if (this.RightToLeftLayout == true && this.RightToLeft == RightToLeft.Yes) {
                IntPtr handle = SendMessage(NativeMethods.DTM_GETMONTHCAL, 0,0);
                if (handle != IntPtr.Zero) {
                    int style = unchecked((int)((long)UnsafeNativeMethods.GetWindowLong(new HandleRef(this, handle), NativeMethods.GWL_EXSTYLE)));
                    style |= NativeMethods.WS_EX_LAYOUTRTL | NativeMethods.WS_EX_NOINHERITLAYOUT;
                    style &= ~(NativeMethods.WS_EX_RIGHT | NativeMethods.WS_EX_RTLREADING);
                    UnsafeNativeMethods.SetWindowLong(new HandleRef(this, handle), NativeMethods.GWL_EXSTYLE, new HandleRef(this, (IntPtr)style));
                }
            }
            OnDropDown(EventArgs.Empty);
        }
 
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.OnSystemColorsChanged"]/*' />
        /// <devdoc>
        ///     Handles system color changes
        /// </devdoc>
        /// <internalonly/>
        protected override void OnSystemColorsChanged(EventArgs e) {
            SetAllControlColors();
            base.OnSystemColorsChanged(e);
        }
 
        /// <devdoc>
        ///     Handles the WM_COMMAND messages reflected from the parent control.
        /// </devdoc>
        /// <internalonly/>
        private void WmReflectCommand(ref Message m) {
            if (m.HWnd == Handle) {
 
                NativeMethods.NMHDR nmhdr = (NativeMethods.NMHDR)m.GetLParam(typeof(NativeMethods.NMHDR));
                switch (nmhdr.code) {
                    case NativeMethods.DTN_CLOSEUP:
                        WmCloseUp(ref m);
                        break;
                    case NativeMethods.DTN_DATETIMECHANGE:
                        WmDateTimeChange(ref m);
                        break;
                    case NativeMethods.DTN_DROPDOWN:
                        WmDropDown(ref m);
                        break;
                }
            }
        }
 
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePicker.WndProc"]/*' />
        /// <devdoc>
        ///     Overrided wndProc
        /// </devdoc>
        /// <internalonly/>
        [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]
        protected override void WndProc(ref Message m) {
            switch (m.Msg) {
                case NativeMethods.WM_LBUTTONDOWN:
                    FocusInternal();
                    if (!ValidationCancelled) {
                        base.WndProc(ref m);
                    }
                    break;
                case NativeMethods.WM_REFLECT + NativeMethods.WM_NOTIFY:
                    WmReflectCommand(ref m);
                    base.WndProc(ref m);
                    break;
                case NativeMethods.WM_WINDOWPOSCHANGED:
                    base.WndProc(ref m);
                    UpdateUpDown();
                    break;
                default:
                    base.WndProc(ref m);
                    break;
            }
        }
 
        /// <devdoc>
        ///     Takes a DateTime value and returns a SYSTEMTIME struct
        ///     Note: 1 second granularity
        /// </devdoc>
        internal static NativeMethods.SYSTEMTIME DateTimeToSysTime(DateTime time) {
            NativeMethods.SYSTEMTIME sys = new NativeMethods.SYSTEMTIME();
            sys.wYear = (short)time.Year;
            sys.wMonth = (short)time.Month;
            sys.wDayOfWeek = (short)time.DayOfWeek;
            sys.wDay = (short)time.Day;
            sys.wHour = (short)time.Hour;
            sys.wMinute = (short)time.Minute;
            sys.wSecond = (short)time.Second;
            sys.wMilliseconds = 0;
            return sys;
        }
 
        /// <devdoc>
        ///     Takes a SYSTEMTIME struct and returns a DateTime value
        ///     Note: 1 second granularity.
        /// </devdoc>
        internal static DateTime SysTimeToDateTime(NativeMethods.SYSTEMTIME s) {
            return new DateTime(s.wYear, s.wMonth, s.wDay, s.wHour, s.wMinute, s.wSecond);
        }
 
        /// <devdoc>
        /// </devdoc>
        private sealed class EnumChildren {
            public IntPtr hwndFound = IntPtr.Zero;
 
            public bool enumChildren(IntPtr hwnd, IntPtr lparam) {
                hwndFound = hwnd;
                return true;
            }
        }
 
        /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePickerAccessibleObject"]/*' />
        /// <internalonly/>
        /// <summary>
        /// </summary>
        [ComVisible(true)]
        public class DateTimePickerAccessibleObject : ControlAccessibleObject {
 
            /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePickerAccessibleObject.DateTimePickerAccessibleObject"]/*' />
            public DateTimePickerAccessibleObject(DateTimePicker owner) : base(owner) {
            }
 
            /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePickerAccessibleObject.KeyboardShorcut"]/*' />
            public override string KeyboardShortcut {
                get {
                    // APP COMPAT. When computing DateTimePickerAccessibleObject::get_KeyboardShorcut the previous label 
                    // takes precedence over DTP::Text.
                    // This code was copied from the Everett sources.
                    // vsw 541672.
                    Label previousLabel = this.PreviousLabel;
 
                    if (previousLabel != null) {
                        char previousLabelMnemonic = WindowsFormsUtils.GetMnemonic(previousLabel.Text, false /*convertToUpperCase*/);
                        if (previousLabelMnemonic != (char) 0) {
                            return "Alt+" + previousLabelMnemonic;
                        }
                    }
 
                    string baseShortcut = base.KeyboardShortcut;
                    
                    if ((baseShortcut == null || baseShortcut.Length == 0)) {
                        char ownerTextMnemonic = WindowsFormsUtils.GetMnemonic(this.Owner.Text, false /*convertToUpperCase*/);
                        if (ownerTextMnemonic != (char) 0) {
                            return "Alt+" + ownerTextMnemonic;
                        }
                    }
                        
                    return baseShortcut;
                }
            }
 
            /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePickerAccessibleObject.Value"]/*' />
            public override string Value {
                [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
                get {
                    string baseValue = base.Value;
                    if (baseValue == null || baseValue.Length == 0) {
                        return Owner.Text;
                    }
                    return baseValue;
                }
            }
 
            /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePickerAccessibleObject.State"]/*' />
            public override AccessibleStates State {
                get {
                    AccessibleStates state = base.State;
 
                    if(((DateTimePicker)Owner).ShowCheckBox &&
                       ((DateTimePicker)Owner).Checked) {
                       state |= AccessibleStates.Checked;
                    }
 
                    return state;
                }
            }
 
            /// <include file='doc\DateTimePicker.uex' path='docs/doc[@for="DateTimePickerAccessibleObject.Role"]/*' />
            public override AccessibleRole Role {
                get {
                    AccessibleRole role = Owner.AccessibleRole;
                    if (role != AccessibleRole.Default) {
                        return role;
                    }
                    return AccessibilityImprovements.Level3 ? AccessibleRole.ComboBox : AccessibleRole.DropList;
                }
            }
 
            internal override bool IsIAccessibleExSupported() {
                if (AccessibilityImprovements.Level3) {
                    return true;
                }
 
                return base.IsIAccessibleExSupported();
            }
 
            internal override object GetPropertyValue(int propertyID) {
                switch (propertyID) {
                    case NativeMethods.UIA_IsTogglePatternAvailablePropertyId:
                        return IsPatternSupported(NativeMethods.UIA_TogglePatternId);
                    case NativeMethods.UIA_LocalizedControlTypePropertyId:
                        return DateTimePickerLocalizedControlTypeString;
                    default:
                        return base.GetPropertyValue(propertyID);
                }
            }
 
            internal override bool IsPatternSupported(int patternId) {
                if (patternId == NativeMethods.UIA_TogglePatternId && ((DateTimePicker)Owner).ShowCheckBox) {
                    return true;
                }
 
                return base.IsPatternSupported(patternId);
            }
 
            #region Toggle Pattern
 
            internal override UnsafeNativeMethods.ToggleState ToggleState {
                get {
                    return ((DateTimePicker)Owner).Checked ? 
                        UnsafeNativeMethods.ToggleState.ToggleState_On : 
                        UnsafeNativeMethods.ToggleState.ToggleState_Off;
                }
            }
 
            internal override void Toggle() {
                ((DateTimePicker)Owner).Checked = !((DateTimePicker)Owner).Checked;
            }
 
            #endregion
        }
    }
}