![]() |
MFC Controls - Month Calendar |
|
Introduction |
|
The Win32 API provides a control used to select dates on a colorful calendar. The dates used and the way they display are based on the Regional Settings of the Control Panel. It may also depend on the operating system: ![]() |
|
This convenient control is called Month Calendar. The title bar of the control displays two buttons and two labels. The left button allows the user to select the previous month by clicking the button. The left label displays the currently selected month. The right label displays the year of the displayed date. The right button is used to get to the next month. ![]() If the control is displaying more than one month, the buttons would increment or decrement by the previous or next month in the list. For example, if the control is displaying April and May, if the user clicks the left button, the control would display March and April. If the control is displaying April and May and the user clicks the right button, the control would display May and June. Also, to select any month of the current year, the user can click the name of the month, which displays the list of months and this allows the user to click the desired month: ![]() To select a year, the user clicks the year number. This changes the year label into a spin button: ![]()
To change the year, the user can click the up or down arrows of the spin button. As the spin button is displaying, the user can also use the arrow keys of the keyboard to increase or decrease the value.
To create a calendar, on the Toolbox, you can click the Month Calendar Control button and click a dialog box, a form or the desired container. The Month Calendar control is based on the CMonthCalCtrl class. Therefore, to dynamically create this control, declare a CMonthCalCtrl variable or a pointer to CMonthCalCtrl. Here is an example: // Exercise1Dlg.h : header file
class CExercise1Dlg : public CDialog
{
// Construction
public:
CExercise1Dlg(CWnd* pParent = NULL); // standard constructor
private:
CMonthCalCtrl *ctlCalendar;
};
The CMonthCalCtrl class, like all other control-oriented classes of the MFC library, is equipped with a Create() method that can be used to programmatically create a calendar and place it on a form or container. Here is an example: CExercise1Dlg::CExercise1Dlg(CWnd* pParent /*=NULL*/)
: CDialog(CExercise1Dlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CExercise1Dlg)
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
ctlCalendar = new CMonthCalCtrl;
}
. . . No Change
/////////////////////////////////////////////////////////////////////////////
// CExercise1Dlg message handlers
BOOL CExercise1Dlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
ctlCalendar->Create(WS_TABSTOP | WS_CHILD |
WS_VISIBLE | WS_BORDER,
CPoint(20, 20), this, 0x224);
return TRUE; // return TRUE unless you set the focus to a control
}
After placing a Month Calendar on a dialog box or a form, it displays the current month and only one month. This is because, by default, its width and height are set enough to accommodate a month. To display more than one month, change the width of the control to provide enough space:
In the same way, you can increase the height to display many months. To change the colors of the Month Calendar control, you can call the CMonthCalCtrl::SetColor() method. Its syntax is: COLORREF SetColor(int nRegion, COLORREF ref);
|
| By default, the title of the Month Calendar control appears on top of a blue background. If you want a different color, pass the nRegion argument as MCSC_TITLEBK, and pass the color of your choice as the ref argument: | ![]() |
![]() |
By default, the labels on the title bar display in a white color. To change the color used to paint the text of the labels, you can pass the nRegion argument as MCSC_TITLETEXT, and pass the color of your choice as the ref argument |
|
Under the title bar, the short names of week days display, using the format set in Control Panel. In US English, the first day is Sunday. If you want to start with a different day, call the SetFirstDayOfWeek() method. Its syntax is: BOOL SetFirstDayOfWeek(int iDay, int* lpnOld = NULL); The first argument, and the only one required, must be an integer of the following values:
int GetFirstDayOfWeek(BOOL* pbLocal = NULL) const; This method returns an integer that is one of the values in the above table. |
![]() |
The numbers of the days of the month display in two colors. The real days of the selected month display, by default, in a black color as the WindowText system color. To change this color, pass the nRegion of the SetColor() method as MCSC_TRAILINGTEXT, and pass the color of your choice as the ref argument. | ![]() |
|
Under the names of the week and their line separator, the numeric days of the month are listed. These days display in a different color. To specify the color of the days of the current month, pass the
nRegion of the SetColor() method as MCSC_TEXT, and pass the color of your choice as the
ref argument.
If it is unchecked or set to False, a circled label would not appear at the bottom of the control as seen in the previous screenshots. |
BOOL CExercise1Dlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
ctlCalendar->Create(WS_TABSTOP | WS_CHILD |
WS_VISIBLE | WS_BORDER | MCS_NOTODAY,
CPoint(20, 20), this, 0x224);
return TRUE; // return TRUE unless you set the focus to a control
}
|
We also mentioned that today date appears with a circle. If you want to hide just the circle, apply the MCS_NOTODAYCIRCLE style: |
BOOL CExercise1Dlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
ctlCalendar->Create(WS_TABSTOP | WS_CHILD |
WS_VISIBLE | WS_BORDER |
MCS_NOTODAYCIRCLE,
CPoint(20, 20), this, 0x224);
return TRUE; // return TRUE unless you set the focus to a control
}

|
At any time, a particular date is selected and has an ellipse with the same color as the background of the title bar. By default, the selected date is today's date. When the user clicks the calendar, a date is selected. To find out what date the user selected, you can access the CMonthCalCtrl::GetCurSel() method. It is overloaded in three versions whose syntaxes are: BOOL GetCurSel(COleDateTime& refDateTime) const; BOOL GetCurSel(CTime& refDateTime) const; BOOL GetCurSel(LPSYSTEMTIME pDateTime) const; Here is an example: |
void CExercise1Dlg::OnRetrieveBtn()
{
// TODO: Add your control notification handler code here
UpdateData();
CTime tme = this->m_dtpCurrent.GetCurrentTime();
this->m_Result.Format("%s", tme.Format("%A, %B %d, %Y"));
UpdateData(FALSE);
}
|
When the user clicks the Month Calendar control, one date is selected. To control whether the user can select one or more dates, at design time, set the value of the Multi Select property accordingly. For example, if you want the user to select a range of dates on the control, set the Muilti Select property to true (MSVC .NET) or check its check box (MSVC 6). To programmatically allow the user to select more than one day, apply the MCS_MULTISELECT style: |
BOOL CExercise1Dlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
ctlCalendar->Create(WS_TABSTOP | WS_CHILD |
WS_VISIBLE | WS_BORDER |
MCS_NOTODAYCIRCLE | MCS_MULTISELECT,
CPoint(20, 20), this, 0x224);
return TRUE; // return TRUE unless you set the focus to a control
}

|
With this property set, the user can select many days in the calendar. You also can programmatically select a range of days. To to this, you can call the CMonthCalCtrl::SetSelRange() method. It comes in three versions whose syntaxes are: BOOL SetSelRange(const COleDateTime& pMinRange, const COleDateTime& pMaxRange); BOOL SetSelRange(const CTime& pMinRange, const CTime& pMaxRange); BOOL SetSelRange(const LPSYSTEMTIME pMinRange, const LPSYSTEMTIME pMaxRange); After the user has selected a range date on the calendar, to find out what that range is, you can call the
CMonthCalCtrl::GetSelRange() method. BOOL SetRange(const COleDateTime* pMinRange, const COleDateTime* pMaxRange); BOOL SetRange(const CTime* pMinRange, const CTime* pMaxRange); BOOL SetRange(const LPSYSTEMTIME pMinRange, const LPSYSTEMTIME pMaxRange); The first argument, nMinRange is the starting date of the desired range. The second argument,
nMaxRange, is the end desired date the user can navigate to. |
|
|
| Copyright © 2004-2005 FunctionX, Inc. |
|
|