What is this Control?
This is an attempt to reproduce the functionality of the MS Outlook miniature
calendar control as it appears in the date picker control and as it
appears in the day-view scheduler. It supports many of the same features
as the MS control.
Below are some screen shots of the control.
(Standard 1 month view demonstrating Today and None buttons)
(12 month view)
(8 month view demonstrating the header-picker pop up)
(4 month view demonstrating multi-select)
What can this Control do?
- Support for 3d border similar to
MS outlooks (optional)
- Support for Today and/or a None
button. (both optional)
- Supports different font for
header, day of week row, day numbers and special day numbers.
- Supports highlighting today's
date. (Optional)
- Supports for N rows and N
columns. (see screen shots)
- Single or multi-select.
(Multi-select works across months)
- Multi-select works across
months.
- Support for special days
highlighting. (See screen shots)
- Support for automatic font size
selection based on screen resolution, number of rows/columns and size of
parent window.
- Header date picker popup list.
(See screen shot)
- Multi-select can be limited to a
maximum selection of X # of continuous days.
- Displays a 6 week calendar when in 1 row, 1 column is set
and displays days preceding the beginning on the upper-left cell and
days following the end on the lower-right when more than 1 row or 1
column is set.
How does this control work?
This control consists of a CWnd derived class named CFPSMiniCalendarCtrl
and numerous support classes. Several available window styles control how
the control will appear to the user. The numbers of rows and columns can
be specified with a simple method call. The fonts can also be customized
through method calls.
Window Styles
|
FMC_MULTISELECT |
Enable multi-select mode |
|
FMC_NOHIGHLIGHTTODAY |
Disable highlighting of today's
date |
|
FMC_TODAYBUTTON |
Enable today button |
|
FMC_NONEBUTTON |
Enable none button |
|
FMC_AUTOSETTINGS |
Auto configures control based on
rows/columns and size of parent |
|
FMC_NO3DBORDER |
Disable custom 3d border |
|
FMC_NOSHOWNONMONTHDAYS |
Disable display of non-month
days. Usually when displaying a single row/single column calendar
the days in the preceding and following months which fit on the 6 week
calendar are displayed in gray. This option disables display of
those days. |
|
|
|
Methods of Importance
|
SetRowsAndColumns |
(int iRows, int iCols)
Sets the number of rows and columns the control will display. |
|
SetCurrentMonthAndYear |
(int iMonth, int iYear)
Sets the month/year the control will display in the first row and
column. Other cells will progress from this date. |
|
SetBackColor |
(COLORREF cColor)
Sets the background color for the control. Defaults to
GetSysColor(COLOR_WINDOW) |
|
SetMaxSize |
(SIZE size)
If auto-configure settings is enabled, this method sets the maximum size
the control can occupy. You can use any SIZE you wish or one of
two constants FMC_MAX_SIZE_NONE and FMC_MAX_SIZE_PARENT |
|
SetMaxSelDays |
(int iValue)
If multi-select is enabled, this method sets the maximum number of
continuous days that may be selected. You can use any positive value
starting from 1, or you can use the constant FMC_NO_MAX_SEL_DAYS. |
|
SetDefaultMinFontSize |
(int iValue)
If auto-configure is enabled, this sets the minimum font size the
control can use to achieve a fit. If it reaches the min font size
and still does not fit, the control stops trying to auto-fit and uses
this font size. The internal default (if this method is not
called) is 5. |
|
SetDefaultFont |
(LPCTSTR lpszValue)
If auto-configure is enabled, sets the font name to use for the various
options. The internal default (if this method is not called) is
"Tahoma" |
|
SetHeaderFont |
(LPCTSTR lpszFont, int iSize, BOOL bBold, BOOL bItalic, BOOL bUnderline, COLORREF cColor)
Sets the font to be used by the header. This header contains the
month name and year number. |
|
SetDaysOfWeekFont |
(LPCTSTR lpszFont, int iSize, BOOL
bBold, BOOL bItalic, BOOL bUnderline, COLORREF cColor)
Sets the font to be used by the days-of-week header. This header
contains the days of week labels (S M T W T F S). |
|
SetDaysFont |
(LPCTSTR lpszFont, int iSize, BOOL
bBold, BOOL bItalic, BOOL bUnderline, COLORREF cColor)
Sets the font to be used by the day numbers. |
|
SetSpecialDaysFont |
(LPCTSTR lpszFont, int iSize, BOOL
bBold, BOOL bItalic, BOOL bUnderline, COLORREF cColor)
Sets the font to be used by the day numbers when the day is a
"special" day. |
|
GetDate |
Returns the data selected in the
control. Used when single-select is set. |
|
GetDateSel |
(COleDateTime& dtBegin, COleDateTime& dtEnd)
Retrieves the date range selected when in multi-select mode. Also
works in single-select mode. |
|
IsDateSelected |
(COleDateTime& dt)
Returns TRUE if the date specified is selected, otherwise returns FALSE. |
|
ScrollLeft |
(int iCount)
Scrolls the month back the specified number of months. |
|
ScrollRight |
(int iCount)
Scrolls the month forward the specified number of months. |
|
SetSpecialDaysCallback |
(funcSPECIALDATE pValue)
The control uses a callback function so the containing application can
provide information on special dates. This function is used to set
this callback function. By default, there are no special
dates.
The format of this function is:
typedef BOOL (CALLBACK* funcSPECIALDATE)(COleDateTime&); |
How to use this Control
The demonstration application provided with this article is an excellent
example of how the control works and how to implement the control in your own
applications. Below are the basic steps to using the control.
- Add the "FPSMiniCalendarCtrl.h", "FPSMiniCalendarCtrl.cpp",
"FPSMiniCalendarListCtrl.h" and "FPSMiniCalendarListCtrl.cpp"
files to your project.
- Include "FPSMiniCalendarCtrl.h" in your "stdafx.h"
file. (You can also include it in each class header where you plan
to use it.)
- In your classes .h file, decalre a member of type CFPSMiniCalendarCtrl.
(See sample 1 below)
- In your classes .cpp file (the OnCreate, OnInitialUpdate or OnInitDialog
functions will all work). Call the Create function with the required
styles and desired position for the control. (See sample 2 below.)
- If needed, set the date selection by calling the SetDate or SetDateSel
method.
- If needed, set the number of rows and columns desired by calling the SetRowsAndColumns
method.
- If needed, set the special dates call back function required for your
needs by calling the SetSpecialDaysCallback method.
- If you are not using auto-configure, you should call the RedrawWindow
method to insure the user is presented with the refreshed settings.
- You will probably also want to setup a notification message map in your
class to be notified when the date selection changes. (See sample 3
below.)
Using the Special Days Callback Function
The special days callback function is used so that the control can
highlight (usually in bold) days which are special for some reason. This
may be holidays, scheduled appointments, etc. The callback function must
be defined as below.
BOOL CALLBACK IsSpecialDateCallback(COleDateTime &dt);
It can be either a global function or a static method of one of your classes.
The implementation should return FALSE if the given date is not special and
TRUE if it is.
NOTE: This function is called quite often so try not to perform any long
running processes in this function.
SAMPLE 1 (modifications to .h file)
CFPSMiniCalendarCtrl m_wndCalendar;
SAMPLE 2 (modifications to .cpp file, OnCreate function)
#define WMID_CALENDAR WM_USER+1
m_wndCalendar.Create(NULL, NULL, WS_CHILD | WS_VISIBLE | FMC_MULTISELECT |
FMC_AUTOSETTINGS | FMC_TODAYBUTTON |
FMC_NONEBUTTON,
CalendarRect, this, WMID_CALENDAR);
m_wndCalendar.SetDate(COleDateTime::GetCurrentTime());
m_wndCalendar.SetRowsAndColumns(3,4);
m_wndCalendar.SetSpecialDaysCallback(IsSpecialDateCallback);
SAMPLE 3 (how to be notified of selection changes)
afx_msg void OnCalendarClick(NMHDR * pNotifyStruct, LRESULT * result );
ON_NOTIFY(NM_CLICK, WMID_CALENDAR, OnCalendarClick)
void CYourClassName::OnCalendarClick(NMHDR * , LRESULT * )
{
COleDateTime dtBegin;
COleDateTime dtEnd;
m_wndCalendar.GetDateSel(dtBegin, dtEnd);
}
Notes
This code is not perfect and not suited for all situations but at least for
my project it has been very well received (especially by the end users.) I
am working to implement this control as a picker for the date edit control I
posted previously. (Click here to see the date edit control.)
I
would appreciate any comments you have to make regarding my implementation or
code. Thanks.
Updates
Jan 28, 2002 |
Thanks to Pierre MEINDRE for
pointing out some international issues related to days-of-week names and
the first day of the week also thanks for suggestion for option to
disable display of non-month days in calendar view. Also, thanks
to Rainer Mangold for pointing out the correct method (presumably)
for determining the first day of the week.
CHANGES:
Added a SetDayOfWeekName and GetDayOfWeekName function so that the
days-of-week header row will display correctly according to
locale.
Added a SetFirstDayOfWeek function to set the first day-of week to be
displayed in the days of week header and in the days display area.
Added an option to enable/disable display of non-month days in the
calendar. There is now a new window style which can be set during
creation and functions SetShowNoneMonthDay and GetShowNoneMonthDay .
Corrected a problem with the popup header-list where it was possible to
highlight 2 items at a time.
Modified OnLButtonDown and OnMouseMove code so that NM_CLICK message is
not sent for single-click mode calendar until the mouse button is
released (ie. OnLButtonUp ). This better simulates the MS Outlook
control. |
|
|