
This section provides information and sample code for implementing month calendar controls.
To create a month calendar control, use the CreateWindowEx function, specifying MONTHCAL_CLASS as the window class. You must first register the window class by calling the InitCommonControlsEx function, specifying the ICC_DATE_CLASSES bit in the accompanying INITCOMMONCONTROLSEX structure.
The following example demonstrates how to create a month calendar control in an existing modeless dialog box. Note that the size values passed to CreateWindowEx are all zeros. Because the minimum required size depends on the font the control uses, the DoNotify example function uses the MonthCal_GetMinReqRect macro to request size information and then resizes the control by calling SetWindowPos.
// CreateMonthCal -- Creates a month calendar control in a dialog box.
// Returns the handle to the month calendar control
// if successful, or NULL otherwise.
//
// hwndOwner -- Handle to the owner of the dialog box.
// g_hinst -- Global handle to the program instance.
//
/////
HWND WINAPI CreateMonthCal(HWND hwndOwner)
{
HWND hwnd;
RECT rc;
INITCOMMONCONTROLSEX icex;
// Load the window class.
icex.dwSize = sizeof(icex);
icex.dwICC = ICC_DATE_CLASSES;
InitCommonControlsEx(&icex);
// Create a modeless dialog box to hold the control.
g_hwndDlg = CreateDialog(g_hinst,
MAKEINTRESOURCE(IDD_DIALOG1),
hwndOwner,
DlgProc);
// Create the month calendar.
hwnd = CreateWindowEx(0,
MONTHCAL_CLASS,
"",
WS_BORDER | WS_CHILD | WS_VISIBLE | MCS_DAYSTATE,
0,0,0,0, // resize it later
g_hwndDlg,
NULL,
g_hinst,
NULL);
// Get the size required to show an entire month.
MonthCal_GetMinReqRect(hwnd, &rc);
// Arbitrary values
#define LEFT 35
#define TOP 40
// Resize the control now that the size values have been obtained.
SetWindowPos(hwnd, NULL, TOP, LEFT,
LEFT + rc.right, TOP + rc.bottom,
SWP_NOZORDER);
// Set colors for aesthetics.
MonthCal_SetColor(hwnd, MCSC_BACKGROUND, RGB(175,175,175));
MonthCal_SetColor(hwnd, MCSC_MONTHBK, RGB(248,245,225));
return(hwnd);
}
Month calendar controls send the MCN_GETDAYSTATE notification message to request information about how the days within the visible months should be displayed. The following application-defined function, DoNotify, processes MCN_GETDAYSTATE by filling an array of MONTHDAYSTATE values to highlight the 15th day of each month.
DoNotify extracts the number of MONTHDAYSTATE values needed from the cDayState member of the NMDAYSTATE structure that lParam points to. It then loops to set the 15th bit in each element of the array, using the application-defined BOLDDAY macro.
BOOL WINAPI DoNotify(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
#define BOLDDAY(ds,iDay) if(iDay>0 && iDay<32)\
(ds)|=(0x00000001<<(iDay-1))
#define lpnmDS ((NMDAYSTATE *)lParam)
#define MAX_MONTHS 12
MONTHDAYSTATE mds[MAX_MONTHS];
INT i, iMax;
LPNMHDR hdr = (LPNMHDR)lParam;
switch(hdr->code){
case MCN_GETDAYSTATE:
iMax=lpnmDS->cDayState;
for(i=0;i<iMax;i++){
mds[i] = (MONTHDAYSTATE)0;
BOLDDAY(mds[i],15);
}
lpnmDS->prgDayState = mds;
break;
}
return FALSE;
}
Both the MCM_SETDAYSTATE message and MCN_GETDAYSTATE notification message require an array of MONTHDAYSTATE values to determine how dates will be displayed. Each month that the control displays must have a corresponding element within the array.
To support these messages, your application must properly prepare the array. The following is a simple macro that sets a bit in a MONTHDAYSTATE value for a given day within that month.
#define BOLDDAY(ds,iDay) if(iDay>0 && iDay<32)\
(ds)|=(0x00000001<<(iDay-1))
Using this macro, an application could simply loop through an array of important dates, setting bits within the corresponding array elements. This approach is not the most efficient, of course, but works well for many purposes. As long as your application sets MONTHDAYSTATE bits appropriately, it does not matter how those bits were set.
© 1997 Microsoft Corporation. All rights reserved. Terms of Use.