Whilst I like to use the standard date picker control wherever the user should enter a date, I often find that I need it to be fully editable. The standard control has its own way of becoming editable, but this doesn't give me a plain edit control that I can do what I like with.
The control is based on Microsoft's
CDateTimeCtrl class. I have used a sneaky trick to allow me to completely replace the standard control with my own edit control and button, whilst still allowing the class to be derived from
CDateTimeCtrl. I do this by destroying the existing window and then creating my own and attaching it to the class. See
CDateTimeEditCtrl::OnRecreate for the workings.
Because of the way I have done this, use of the control is the same as using
CDateTimeCtrl. You should add a date picker to your dialog resource as normal and then create a member variable for it of type
CDateTimeEditCtrl. The usual date picker styles are supported, with the exception of
Messages sent to the control are interpreted and acted on in the same way as they would be for the standard control, with the exception of
DTM_SETFORMAT, which are not supported. Notifications of events in the control are sent to the parent exactly as they are in the standard picker. Some extra
public functions have been added to provide enhanced behavior. The
public functions are listed below.
BOOL Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID);
Offers the same behaviour as
CEdit* GetEditControl() const;
Returns a pointer to the edit control part of the control, to allow direct manipulation of its properties.
void EnableButton(BOOL bEnable = TRUE);
Enables or disables the button used to drop down the
void RestoreFocus(BOOL bRestore = TRUE);
Determines the behavior when clicking on the button. If
TRUE, the control resets the focus back to the window which had the focus on clicking the button. Otherwise, the focus is set to the edit control. If the control is not editable, focus is always set back to the previously focused window. The default is for the focus to be set to the edit control.
void SetNonEditable(BOOL bNonEditable = TRUE);
Used to make the edit portion of the control non-editable. The default is editable.
Returns whether the edit control is currently editable.
virtual BOOL IsValidDate(LPCTSTR lpszDate = NULL);
Returns whether the date string passed is valid. If
NULL then it returns whether the text in the edit control is a valid date string.
void SetValidCharsOnly(BOOL bValidCharsOnly = TRUE);
Sets whether the user can only enter characters that are valid.
Returns whether the user can only enter valid characters into the edit control.
void SetValidChars(LPCTSTR lpszValidChars = NULL);
Sets the characters that are valid for the user to type into the edit control. If
NULL is specified, the default characters are used (0-9 and the date separator of the current user's locale). If the user changes the locale settings, then the control will detect this and use the new separator.
Returns the characters that have been set as being valid for the user to type into the edit control.
void SetAllowUpDownKeys(BOOL bAllow = TRUE);
Sets whether the up/down arrow keys will increment/decrement the part of the date string that contains the cursor.
Returns whether the up/down keys will increment/decrement parts of the date string.
BOOL SetButtonImageID(UINT nID, UINT nDisabledID = 0);
Specifies a resource ID from which to load the button image. For the best results, the image should be 13 pixels wide and 12 pixels high.
nDisabledID optionally specifies an image to use for the button in its disabled state.
UINT GetButtonImageID(UINT* pDisabledID = NULL) const;
Returns the current button image's ID. The ID used for the disabled button can be retrieved in
void GetButtonImageIDs(UINT& nID, UINT& nDisabledID) const;
Retrieves the current button images' IDs.
void SetReadOnly(BOOL bReadOnly = TRUE);
Sets the control to read-only. This is similar to the disabled state, but the text is not shown in grey and may be selected.
BOOL GetReadOnly() const;
Returns whether the control is set to read-only.
- 21st-Jan-2008 - Version 3.7
- Updated to work correctly on Vista.
- 20th-Apr-2007 - Version 3.6.1
- Fixed missing and incorrect
- Changed to compile correctly in VC7 (Visual Studio 2003) and VC8 (Visual Studio 2005).
- Added fix to control being shown if hidden in initializing of parent.
- 22nd-Dec-2005 - Version 3.6
- Added "read-only" state, to allow a semi-disabled state.
- Updated to recognize XP theme changes and re-draw accordingly.
- Fixed bug where the calendar could be shown in non-editable mode on F4, and the date could be changed by using up/down keys.
- Added support for a "disabled" image to be used when the control is disabled or read-only.
- Fixed bug where creating control with
ES_READONLY style failed.
- Nested button/edit/calendar/XP-style classes so they don't appear in the top level of the ClassView.
- 04th-Apr-2005 - Version 3.5
- Updated to support XP-styling.
- Changed to grey-out edit if disabled (suggested by Hans-Georg Ulrich).
- Added fix to enable compilation with Visual Studio .NET (thanks to Mark Harmon).
- 09th-Jul-2004 - Version 3.4
- Fixed bug where dismissing the month menu in the
calendar control by clicking outside of the calendar area then prevents the calendar being dismissed without first clicking back on the
calendar control (reported by winkle.)
- Fixed assertion failures on re-creation of the control when two or more instances of the control are on a dialog (reported by pimOOsse and Rick Austin).
- 09th-Jul-2003 - Version 3.3
- Updated to support Unicode.
- 15th-Apr-2003 - Version 3.2
- Extended control to accept the
- Fixed incorrect implementation of
- Added facility to use a bitmap for the button instead of a down arrow.
WM_NOTIFY notifications now passed to the parent window from date control's children.
- Fixed bug where clicking on the current (circled) day when the edit control is empty closed the calendar and did not put the selected day in the edit control.
- 20th-Jan-2003 - Version 3.1
- Fixed bug where, if the new date text is set in the
DTN_DATETIMECHANGE handler (for instance, to constrain the date within some boundary) and the user selects a date which is "out of bounds" and the calendar closes, the selected date is copied to the edit control, overwriting the "fixed" date.
- 17th-Jan-2003 - Version 3
- Fixed bug where a call to
SetFont or any function which resulted in sending of a
DTM_XXX message caused an assertion the first time round, if called from the
OnInitDialog of a parent dialog or equivalent.
- 07th-Jan-2003 - Version 2
- Edit control notifications (e.g.
EN_CHANGE) now sent to the date control's parent window.
- Added features as suggested by Marc Clifton:
- Added function to validate a date string (
- Added function to only allow valid characters to be typed into the edit control. Also added a function to set the valid characters. The default valid characters are 0-9 and the date separator of the current user's locale. If the user changes the locale settings, then the control will automatically pick this up and use the new separator.
- Added ability to use up/down keys to edit portions of the date text. The parent is sent
DTN_DATETIMECHANGE notifications as the date changes.
- 03rd-Jan-2003 - Version 1