Objective Toolkit : Chapter 4 Simple Controls : Date/Time Edit Control
Date/Time Edit Control
The date/time edit control implements an edit field that allows users to edit date information in various display formats using either keyboard or mouse with optional spin buttons. The date is internally represented with a COleDateTime object, limiting it to 32-bit environments.
Some features of the date time control include:
Default and customizable display formats
Null date entry mode
Fast entry mode (automatic cursor advancement as data is entered)
Minimum/maximum range restriction
Spinner buttons
Popup calendar
Y2K compliance
 
Figure 24 – Example Date Time Control with Default Display Formats
 
Figure 25 – Example Date Time Control with a Custom Display Format
The SECDateTimeCtrl class implements the date/time control. The entry field is divided into a number of subfields, depending on the specified format. Each subfield or component is controlled by a gadget class specialized for the input and display of that particular subfield. Each gadget class is based on SECDTGadget.
Figure 26 – The Date/time Control Class Hierarchy
SECDateTimeCtrl
SECDateTimeCtrl is a date/time editing control class. SECDateTimeCtrl manages several gadget objects to display the data in a specified format.
SECDateTimeCtrl styles
You can set the following extended styles when the control is:
Created.
Attached to an edit control in a dialog resource using AttachDateTimeCtrl().
You can set the styles with the Create() or CreateEx() methods. The Y2K styles determine which century is added to a two-digit year.
Table 11 – Extended Styles for SECDateTimeCtrl 
SEC_DTS_CALENDAR
Adds calendar drop-down button.
SEC_DTS_UPDOWN
Adds spinner control.
SEC_DTS_Y2K_NOFIX
Ignores Y2K fix (for backward compatibility). The current century is used to expand two-digit years.If not defined, the century is chosen so that the resulting date is within 50 years of either the current date or the date previously stored in the control, depending on SEC_DTS_Y2K_CONTEXT.
SEC_DTS_Y2K_CONTEXT
If SEC_DTS_Y2K_NOFIX is not defined, the century is based on the date previously stored in the control.
 
SECDateTimeCtrl messages
SECDateTimeCtrl only supports the following edit control messages.
SECDTN_CHANGED or EN_CHANGE
SECDTN_KILLFOCUS or EN_KILLFOCUS
SECDTN_SETFOCUS or EN_SETFOCUS
SECDTGadget
SECDTGadget is an abstract base class that handles the input and display of data in the subfields of a date/time control. SECDateTimeCtrl uses several subclasses of SECDTGadget including:
SECDTStaticGadget. Implements a non-editable text gadget.
SECDTNumericGadget. Implements an editable numeric gadget.
SECDTListGadget. Implements a text gadget with a defined list of possible strings.
SECDTButtonGadget. Implements a simple push button gadget.
SECDTSpinGadget. Implements a spin button gadget.
Date Formats
SECDataTimeCtrl’s SetFormat() method specifies how the date or time data is displayed. The format determines which subfields or gadgets are shown. Several predefined format types are available. In addition, you can specify custom formats using codes in a user-defined string.
Predefined Format Types
The table below lists the format types that the application can pass as a parameter to SetFormat(). To specify a custom format, the user-defined string is passed to SetFormat(); don’t pass SECDateTimeCtrl::Custom.
Table 12 – Supported Format Types for SetFormat() 
Format type
Description
Example
SECDateTimeCtrl::Time
Locale time format
11:54
SECDateTimeCtrl::ShortDate
Locale short date format
7/21/98
SECDateTimeCtrl::LongDate
Locale long date format
Tuesday July 21, 1998
SECDateTimeCtrl::Custom
A user supplied date/time format string
July 21, 1998 (Tuesday)
 
Format Strings
You can use the codes in the following table to build a custom format string.
Table 13 – Format Strings Supported by SECDateTimeCtrl 
Format string
Description
h
Hours, 12 hour format, no leading zero
hh
Hours, 12-hour format with leading zero
H
Hours, 24-hour format, no leading zero
HH
Hours, 24-hour format with leading zero
m
Minutes, no leading zero
mm
Minutes with leading zero
s
Seconds, no leading zero
ss
Seconds with leading zero
t
Abbreviated AM/PM designator
tt
Full AM/PM designator
d
Numeric day
dd
Numeric day with leading zero
ddd
Abbreviated day name
dddd
Full day name
M
Month
MM
Month with leading zero
MMM
Abbreviated month
MMMM
Full month name
y
Year without century
yy
Year with leading zero, without century
yyyy
Year including century
gg
Era (ignored)
‘text'
Quoted text passed straight through
 
Null Data Entry Mode
SECDateTimeCtrl supports a null date entry mode. This mode allows you to enter date time information in an empty control. You can specify a character to fill the fields of the control so that the user can see them. The following figure is an example date time control that has been put into null date entry mode.
Figure 27 – Example Date Time Controls in Null Data Entry Mode
The user can now begin entering data. The control remains in null entry mode until all of the required fields are completed.
Figure 28 – Using Date Time Controls in Null Data Entry Mode
When not in null date entry mode, GetDateTime() always returns a COleDateTime object containing the currently displayed date/time. When the application is in null date entry mode, GetDateTime() returns one of the following:
A COleDateTime object with a status of COleDateTime::null if the date is incomplete.
A COleDateTime object with a status of COleDateTime::invalid if the date is complete, but invalid (out of range).
A COleDateTime object containing the entered date/time.
Using SECDateTimeCtrl
The following sections give tips on using the SECDateTimeCtrl class.
To use the date/time control in a dialog:
1. Create an edit control on a dialog resource in the resource editor.
2. Add a data member to the dialog class for the date time control. For example:
 
SECDateTimeCtrl m_dateCtrl;
3. In the OnInitDialog() method of the dialog, set the display format for the date time object with the SetFormat() method. For example:
 
m_dateCtrl.SetFormat(SECDateTimeCtrl::Time);
4. After setting the display format, attach the resource edit control to the date time object with the AttachDateTimeCtrl() method. For example:
 
VERIFY(m_dateCtrl.AttachDateTimeCtrl(IDC_TIME, this, SEC_DTS_UPDOWN));
To set the date or time for the control:
Call the SetDateTime(), SetDate(), or SetTime() methods. For example:
 
m_dateCtrl.SetDateTime(minDate);
To change a date/time control to the null date entry mode:
Call the SetNull() method. This method accepts a character that is used to blank out the control. For example:
 
m_dateCtrl.SetNull('_');
To make the control always remain in the null date entry mode:
 
m_dateCtrl.SetNull('_', TRUE);
To clear the control using the delete key:
1. Derive a class from SECDateTimeCtrl.
2. Override the OnKeyDown() method. In this override, test for the VK_DELETE key, and if detected, call the SetNull() method. For example:
 
void CMyDateTimeCtrl::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: Add your message handler code here and/or call default
SECDateTimeCtrl::OnKeyDown(nChar, nRepCnt, nFlags);
 
if (VK_DELETE == nChar) {
SetNull('_');
}
}
To set focus back to the first gadget of the control:
1. Derive a class from SECDateTimeCtrl.
2. Create a method, or in a method override, use the following code to locate the first gadget index:
 
// Find first gadget
int nGadget;
for(nGadget = m_nFixed;
nGadget < m_gadgets.GetSize() &&
!(m_gadgets[nGadget]->GetStyle() & SECDTGadget::WantFocus);
nGadget++);
3. When you locate the first gadget index, call the Enable() method on the gadget, and then call the BringIntoView() method. For example:
 
if(nGadget >= m_nFixed && nGadget < m_gadgets.GetSize())
{
m_gadgets[m_nCurGadget = nGadget]->Enable(TRUE);
BringIntoView(m_nCurGadget);
}
To change the color of the text in the control:
1. In the parent window, override OnCtlColor() and set the text and background colors using the SetBkColor() and SetTextColor() methods. For example:
 
HBRUSH CDatetimeDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CPropertyPage::OnCtlColor(pDC, pWnd,
nCtlColor);
if (pWnd-> IsKindOf(RUNTIME_CLASS(SECDateTimeCtrl)) &&
nCtlColor == CTLCOLOR_EDIT)
{
//pDC->SetBkMode(OPAQUE);
pDC->SetBkColor(RGB(75,75,255));
pDC->SetTextColor(RGB(255,255,0));
}
// for all other windows, use the default brush from the
// base class
else
hbr = CPropertyPage::OnCtlColor(pDC, pWnd, nCtlColor);
return hbr;
}
Date/Time Edit Control Sample
See the datetime sample in the Samples\Toolkit\MFC\Controls\datetime directory for a demonstration of how to use the SECDateTimeCtrl classes. This sample is not shipped with the product. For information on how to obtain this sample, see “Location of Sample Code” in the Getting Started part.