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:
- 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)
- 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.
COleDateTime local time to UTC and returns the number of seconds since EPOCH.
- Date range and selection handling which stores the date as
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
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.
- Include both CalendarCtrl.h and CalendarCtrl.cpp in your project
- Add the
#include "CalendarCtrl.h" directive and declare a member variable
CCalendarCtrl::Create() with the pointer to your callback function (
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
- 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.
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.
Thanks to everyone sharing code on this website.
My name is Frederic Rezeau, I am a certified MCSD IT Professional. Based in London, I have a background in the medical industry developing components related to the UK National Program for IT. Prior to that, I worked in the banking sector in France developing distributed security applications.
Visit my website for more information.