
Introduction
For my latest project (a fitness management software), I needed a flexible calendar view allowing the user to easily schedule his or her workout activity. Here is my implementation.
CCalendarCtrl
is a small CWnd
-based class that implements a scrolling calendar. The calendar displays a series of weeks (rows) that can belong to different consecutive months, and allows the user to navigate and select multiple weeks/days at a time using the keyboard or the mouse.
The following illustration shows the control in a real world application perf'Control Personal edition:

Features :
- Easy navigation using arrow keys
- Multi selection using the mouse or keyboard (Shift or Ctrl + Arrows to move, space to select)
- Scroll bar and mouse wheel
- Each date can hold multiple lines of text
- Each date can be "marked"
- Custom First day of the week (Monday, Tuesday...)
- Using callback to populate the date.
- Resizable (see screenshot 1)
- Boundaries

Limitations?
- Err.. I can pretty much predict that the control will die ungraciously on the 19 of January, 2038 (around 3 AM) :-)
- There are two sections of code that will need to be modified in order to get it working with dates beyond 2038.
DateToSeconds()
which converts COleDateTime
local time to UTC and returns the number of seconds since EPOCH.
- Date range and selection handling which stores the date as
time_t
.
How to use it:
It's pretty straighforward. Additionally, the demo project shows you how to setup a callback for populating the calendar cells with custom data. The callback function is called for every cell each time the date is set (via a call to Goto()
).
Note: CCalendarCtrl
also calls the callback function (internally)whenever scrolling occurs. This can be a potential issue (slow down) if your callback code gets its data from a database or file. In my application, the data are stored both in a database and in XML files. To overcome this issue, I slightly modified the code in order to prevent the callback from being called to often (i.e., if the user does not release the arrow key when scrolling I don't call it). For clarity purposes I did not include this in the test app.
Quick setup:
- Include both CalendarCtrl.h and CalendarCtrl.cpp in your project
- Add the
#include "CalendarCtrl.h"
directive and declare a member variable CCalendarCtrl
- Call
CCalendarCtrl::Create()
with the pointer to your callback function (LPFN_CALENDAR_DATA_CALLBACK
)
CCalendarCtrl::Reset()
to initialize the control
- 31/08/2006 - Just discovered a bug regarding calendar selection and Time zone. The problem may cause an infinite loop in calendar when calling
GetSelectedItems()
- Problem: The code computes the GMT bias using the current settings. So when selecting the date on which the system is changing from daylight time to standard time,
DateToSeconds()
returns a date in the past and this creates an infinite loop.
- Current fix: Modified
DateToSeconds()
to compute the bias according to the date and not current settings (removed GetTimeZoneInformation()
). Also modified GetSelectedItems()
to prevent error propagation (because of the missing hour). See comments in code for more information. This is a quick fix, it works but may need better handling.
Conclusion
I hope you'll find it useful... If you like it, feel free to use it.
Feel free to contact me for any questions regarding this article.
Acknowledgments
Thanks to everyone sharing code on this website.