Commit 0bb2e5ab authored by Alexandre Julliard's avatar Alexandre Julliard

Authors: Chris Morgan <cmorgan@wpi.edu>, James Abbatiello <abbeyj@wpi.edu>

Implemented current day circling. Fixed many bugs in the month calender control including control spacing and alignment. Fixed defines monthcal.h. Optimized control drawing and removed many extranious redraws. Improved control behavior. Fixed inconsistent formatting in both .c and .h files.
parent 87bff28c
/* Month calendar control
*
* Copyright 1998, 1999 Eric Kohl (ekohl@abo.rhein-zeitung.de)
* Copyright 1999 Alex Priem (alexp@sci.kun.nl)
* Copyright 1999 Chris Morgan<cmorgan@wpi.edu> and
* James Abbatiello<abbeyj@wpi.edu>
*
* TODO:
* - Notifications.
......@@ -17,6 +17,8 @@
* FIXME: keyboard handling.
*/
#include <math.h>
#include "winbase.h"
#include "winuser.h"
#include "wingdi.h"
......@@ -38,117 +40,142 @@ char *monthtxt[] = {"January", "February", "March", "April", "May",
"June", "July", "August", "September", "October",
"November", "December"};
char *daytxt[] = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };
char *daytxt[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
int DayOfWeekTable[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};
#define MONTHCAL_GetInfoPtr(hwnd) ((MONTHCAL_INFO *)GetWindowLongA (hwnd, 0))
/* helper functions
* MONTHCAL_ValidateTime: is time a valid date/time combo?
*/
/* helper functions */
/* returns the number of days in any given month */
/* january is 1, december is 12 */
static int MONTHCAL_MonthLength(int month, int year)
{
/* if we have a leap year add 1 day to February */
/* a leap year is a year either divisible by 400 */
/* or divisible by 4 and not by 100 */
if(month == 2) { /* February */
return mdays[month - 1] + ((year%400 == 0) ? 1 : ((year%100 != 0) &&
(year%4 == 0)) ? 1 : 0);
}
else {
return mdays[month - 1];
}
}
/* CHECKME: all these validations OK? */
/* make sure that time is valid */
static int MONTHCAL_ValidateTime (SYSTEMTIME time)
{
if (time.wMonth > 12) return FALSE;
if (time.wDayOfWeek > 6) return FALSE;
if (time.wDay > mdays[time.wMonth]) return FALSE;
if (time.wMonth > 23) return FALSE;
if (time.wMinute > 60) return FALSE;
if (time.wSecond > 60) return FALSE;
if (time.wMilliseconds > 100) return FALSE;
return TRUE;
if (time.wMonth > 12) return FALSE;
if (time.wDayOfWeek > 6) return FALSE;
if (time.wDay > MONTHCAL_MonthLength(time.wMonth, time.wYear ))
return FALSE;
if (time.wHour > 23) return FALSE;
if (time.wMinute > 59) return FALSE;
if (time.wSecond > 59) return FALSE;
if (time.wMilliseconds > 999) return FALSE;
return TRUE;
}
void MONTHCAL_CopyTime (const SYSTEMTIME *from, SYSTEMTIME *to)
void MONTHCAL_CopyTime (const SYSTEMTIME *from, SYSTEMTIME *to)
{
to->wYear=from->wYear;
to->wMonth=from->wMonth;
to->wDayOfWeek=from->wDayOfWeek;
to->wDay=from->wDay;
to->wHour=from->wHour;
to->wMinute=from->wMinute;
to->wSecond=from->wSecond;
to->wMilliseconds=from->wMilliseconds;
to->wYear=from->wYear;
to->wMonth=from->wMonth;
to->wDayOfWeek=from->wDayOfWeek;
to->wDay=from->wDay;
to->wHour=from->wHour;
to->wMinute=from->wMinute;
to->wSecond=from->wSecond;
to->wMilliseconds=from->wMilliseconds;
}
/* Note:Depending on DST, this may be offset by a day.
Need to find out if we're on a DST place & adjust the clock accordingly.
Above function assumes we have a valid data.
Valid for year>1752; d <= 1 <= 31, 1 <= m <= 12.
0=Monday.
Valid for year>1752; 1 <= d <= 31, 1 <= m <= 12.
0 = Monday.
*/
/* returns the day in the week(0 == sunday, 6 == saturday) */
/* day(1 == 1st, 2 == 2nd... etc), year is the year value */
int MONTHCAL_CalculateDayOfWeek (DWORD day, DWORD month, DWORD year)
{
year -= month < 3;
return (year + year/4 - year/100 + year/400 +
DayOfWeekTable[month-1] + day - 1 ) % 7;
year -= (month < 3);
return((year + year/4 - year/100 + year/400 +
DayOfWeekTable[month-1] + day - 1 ) % 7);
}
static int MONTHCAL_CalcDayFromPos (MONTHCAL_INFO *infoPtr, int x, int y)
{
int daypos,weekpos,retval,firstDay;
daypos=(x - infoPtr->prevmonth.left) / infoPtr->textWidth ;
weekpos=(y - infoPtr->days.bottom - infoPtr->rcClient.top) /
(infoPtr->textHeight*1.25);
firstDay=MONTHCAL_CalculateDayOfWeek (1,infoPtr->currentMonth,infoPtr->currentYear);
retval=daypos + 7*weekpos - firstDay;
TRACE ("%d %d %d\n",daypos,weekpos,retval);
return retval;
}
int daypos,weekpos,retval,firstDay;
/* if the point is outside the x bounds of the window put
it at the boundry */
if(x > (infoPtr->width_increment * 7.0)) {
x = infoPtr->rcClient.right - infoPtr->rcClient.left - infoPtr->left_offset;
}
daypos = (x - (infoPtr->prevmonth.left + infoPtr->left_offset)) / infoPtr->width_increment;
weekpos = (y - infoPtr->days.bottom - infoPtr->rcClient.top) / infoPtr->height_increment;
firstDay = MONTHCAL_CalculateDayOfWeek (1, infoPtr->currentMonth, infoPtr->currentYear);
retval = daypos + (7 * weekpos) - firstDay;
TRACE ("%d %d %d\n",daypos,weekpos,retval);
return retval;
}
/* day is the day of the month, 1 == 1st day of the month */
/* sets x and y to be the position of the day */
/* x == day, y == week where (0,0) == sunday, 1st week */
static void MONTHCAL_CalcDayXY (MONTHCAL_INFO *infoPtr, int day, int month,
int *x, int *y)
{
int firstDay,prevMonth;
firstDay=MONTHCAL_CalculateDayOfWeek (1,infoPtr->currentMonth,infoPtr->currentYear);
firstDay = MONTHCAL_CalculateDayOfWeek (1, infoPtr->currentMonth, infoPtr->currentYear);
if (month==infoPtr->currentMonth) {
*x=(day+firstDay) & 7;
*y=(day+firstDay-*x) / 7;
return;
}
*x = (day + firstDay) % 7;
*y = (day + firstDay - *x) / 7;
return;
}
if (month < infoPtr->currentMonth) {
prevMonth=month - 1;
if (prevMonth==0) prevMonth=11;
*x=(mdays[prevMonth]-firstDay) & 7;
*y=0;
}
*y=mdays[month] / 7;
*x=(day+firstDay+mdays[month]) & 7;
prevMonth = month - 1;
if (prevMonth==0)
prevMonth = 12;
*x = (MONTHCAL_MonthLength(prevMonth, infoPtr->currentYear) - firstDay) % 7;
*y = 0;
return;
}
*y = MONTHCAL_MonthLength(month, infoPtr->currentYear - 1) / 7;
*x = (day + firstDay + MONTHCAL_MonthLength(month,
infoPtr->currentYear)) % 7;
}
/* x: column(day), y: row(week) */
static void MONTHCAL_CalcDayRect (MONTHCAL_INFO *infoPtr, RECT *r, int x, int y)
{
r->left = infoPtr->prevmonth.left + x * infoPtr->textWidth;
r->right = r->left + infoPtr->textWidth;
r->top = infoPtr->rcClient.top + y * 1.25 * infoPtr->textHeight
+ infoPtr->days.bottom;
r->left = infoPtr->prevmonth.left + x * infoPtr->width_increment + infoPtr->left_offset;
r->right = r->left + infoPtr->width_increment;
r->top = infoPtr->height_increment * y + infoPtr->days.bottom + infoPtr->top_offset;
r->bottom = r->top + infoPtr->textHeight;
}
/* sets the RECT struct r to the rectangle around the day and month */
/* day is the day value of the month(1 == 1st), month is the month */
/* value(january == 1, december == 12) */
static inline void MONTHCAL_CalcPosFromDay (MONTHCAL_INFO *infoPtr,
int day, int month, RECT *r)
{
int x,y;
......@@ -157,339 +184,375 @@ static inline void MONTHCAL_CalcPosFromDay (MONTHCAL_INFO *infoPtr,
}
static void MONTHCAL_CircleDay (HDC hdc, MONTHCAL_INFO *infoPtr, int i, int j)
/* day is the day in the month(1 == 1st of the month) */
/* month is the month value(1 == january, 12 == december) */
static void MONTHCAL_CircleDay (HDC hdc, MONTHCAL_INFO *infoPtr, int day,
int month)
{
HPEN hRedPen = CreatePen(PS_SOLID, 2, RGB (255,0,0) );
HPEN hOldPen2 = SelectObject( hdc, hRedPen );
POINT points[7];
int x,y;
HPEN hRedPen = CreatePen(PS_SOLID, 2, RGB (255,0,0) );
HPEN hOldPen2 = SelectObject( hdc, hRedPen );
POINT points[13];
int x,y;
RECT day_rect;
/* use prevmonth to calculate position because it contains the extra width
* from MCS_WEEKNUMBERS
*/
x=infoPtr->prevmonth.left + (i+0.5)*infoPtr->textWidth;
y=infoPtr->rcClient.top + 1.25*(j+0.5)*infoPtr->textHeight + infoPtr->days.bottom;
points[0].x = x;
points[0].y = y-0.25*infoPtr->textHeight;
points[1].x = x-1.0*infoPtr->textWidth;
points[1].y = y;
points[2].x = x;
points[2].y = y+0.6*infoPtr->textHeight;
points[3].x = x+0.5*infoPtr->textWidth;
points[3].y = y;
points[4].x = x+0.3*infoPtr->textWidth;
points[4].y = y-0.5*infoPtr->textHeight;
points[5].x = x-0.25*infoPtr->textWidth;
points[5].y = y-0.5*infoPtr->textHeight;
points[6].x = x-0.5*infoPtr->textWidth;
points[6].y = y-0.45*infoPtr->textHeight;
PolyBezier (hdc,points,4);
PolyBezier (hdc,points+3,4);
DeleteObject (hRedPen);
SelectObject (hdc, hOldPen2);
}
MONTHCAL_CalcPosFromDay (infoPtr, day, month, &day_rect);
x = day_rect.left;
y = day_rect.top;
points[0].x = x;
points[0].y = y - 1;
points[1].x = x + 0.8 * infoPtr->width_increment;
points[1].y = y - 1;
points[2].x = x + 0.9 * infoPtr->width_increment;
points[2].y = y;
points[3].x = x + infoPtr->width_increment;
points[3].y = y + 0.5 * infoPtr->textHeight;
points[4].x = x + infoPtr->width_increment;
points[4].y = y + 0.9 * infoPtr->textHeight;
points[5].x = x + 0.6 * infoPtr->width_increment;
points[5].y = y + 0.9 * infoPtr->textHeight;
points[6].x = x + 0.5 * infoPtr->width_increment;
points[6].y = y + 0.9 * infoPtr->textHeight; /* bring the bottom up just
a hair to fit inside the day rectangle */
points[7].x = x + 0.2 * infoPtr->width_increment;
points[7].y = y + 0.8 * infoPtr->textHeight;
points[8].x = x + 0.1 * infoPtr->width_increment;
points[8].y = y + 0.8 * infoPtr->textHeight;
points[9].x = x;
points[9].y = y + 0.5 * infoPtr->textHeight;
points[10].x = x + 0.1 * infoPtr->width_increment;
points[10].y = y + 0.2 * infoPtr->textHeight;
points[11].x = x + 0.2 * infoPtr->width_increment;
points[11].y = y + 0.3 * infoPtr->textHeight;
points[12].x = x + 0.5 * infoPtr->width_increment;
points[12].y = y + 0.3 * infoPtr->textHeight;
PolyBezier (hdc, points, 13);
DeleteObject (hRedPen);
SelectObject (hdc, hOldPen2);
}
static void MONTHCAL_DrawDay (HDC hdc, MONTHCAL_INFO *infoPtr,
int day, int month, int x, int y, int bold)
{
char buf[10];
RECT r;
static int haveBoldFont,haveSelectedDay=FALSE;
HBRUSH hbr;
COLORREF oldCol,oldBk;
HBRUSH hbr;
HPEN hNewPen, hOldPen = 0;
COLORREF oldCol = 0;
COLORREF oldBk = 0;
sprintf (buf,"%d",day);
/* No need to check styles: when selection is not valid, it is set to zero.
* 1<day<31, so evertyhing's OK.
*/
MONTHCAL_CalcDayRect (infoPtr, &r, x, y);
if ((day>=infoPtr->minSel.wDay) && (day<=infoPtr->maxSel.wDay)
&& (month==infoPtr->currentMonth)) {
HRGN hrgn;
RECT r2;
TRACE ("%d %d %d\n",day,infoPtr->minSel.wDay,infoPtr->maxSel.wDay);
TRACE ("%d %d %d %d\n", r.left, r.top, r.right, r.bottom);
oldCol=SetTextColor (hdc, infoPtr->monthbk);
oldBk=SetBkColor (hdc,infoPtr->trailingtxt);
hbr= GetSysColorBrush (COLOR_GRAYTEXT);
hrgn=CreateEllipticRgn (r.left,r.top, r.right,r.bottom);
FillRgn (hdc,hrgn,hbr);
r2.left = r.left-0.25*infoPtr->textWidth;
r2.top = r.top;
r2.right = r.left+0.5*infoPtr->textWidth;
r2.bottom = r.bottom;
if (haveSelectedDay) FillRect (hdc,&r2,hbr);
haveSelectedDay=TRUE;
} else {
haveSelectedDay=FALSE;
}
if ((day>=infoPtr->minSel.wDay) && (day<=infoPtr->maxSel.wDay)
&& (month==infoPtr->currentMonth)) {
HRGN hrgn;
RECT r2;
TRACE ("%d %d %d\n",day,infoPtr->minSel.wDay,infoPtr->maxSel.wDay);
TRACE ("%d %d %d %d\n", r.left, r.top, r.right, r.bottom);
oldCol = SetTextColor (hdc, infoPtr->monthbk);
oldBk = SetBkColor (hdc,infoPtr->trailingtxt);
hbr = GetSysColorBrush (COLOR_GRAYTEXT);
hrgn = CreateEllipticRgn (r.left, r.top, r.right, r.bottom);
FillRgn (hdc,hrgn,hbr);
/* FIXME: this may need to be changed now b/c of the other
drawing changes 11/3/99 CMM */
r2.left = r.left - 0.25 * infoPtr->textWidth;
r2.top = r.top;
r2.right = r.left + 0.5 * infoPtr->textWidth;
r2.bottom = r.bottom;
if (haveSelectedDay) FillRect (hdc, &r2, hbr);
haveSelectedDay = TRUE;
} else {
haveSelectedDay = FALSE;
}
/* need to add some code for multiple selections */
/* need to add some code for multiple selections */
if ((bold) && (!haveBoldFont)) {
SelectObject (hdc, infoPtr->hBoldFont);
haveBoldFont=TRUE;
}
SelectObject (hdc, infoPtr->hBoldFont);
haveBoldFont = TRUE;
}
if ((!bold) && (haveBoldFont)) {
SelectObject (hdc, infoPtr->hFont);
haveBoldFont=FALSE;
}
SelectObject (hdc, infoPtr->hFont);
haveBoldFont = FALSE;
}
if (haveSelectedDay) {
SetTextColor(hdc, oldCol);
SetBkColor(hdc, oldBk);
}
DrawTextA ( hdc, buf, lstrlenA(buf), &r,
DT_CENTER | DT_VCENTER | DT_SINGLELINE );
if (haveSelectedDay) {
SetTextColor(hdc, oldCol);
SetBkColor (hdc, oldBk);
}
/* draw a rectangle around the currently selected days text */
if ((day==infoPtr->curSelDay) && (month==infoPtr->currentMonth)) {
HPEN hNewPen, hOldPen;
hNewPen = CreatePen(PS_DOT, 0, GetSysColor(COLOR_WINDOWTEXT) );
hbr= GetSysColorBrush (COLOR_WINDOWTEXT);
hOldPen = SelectObject( hdc, hNewPen );
r.left+=2;
r.right-=2;
r.top-=1;
r.bottom+=1;
FrameRect (hdc, &r, hbr);
SelectObject( hdc, hOldPen );
hNewPen = CreatePen(PS_DOT, 0, GetSysColor(COLOR_WINDOWTEXT) );
hbr = GetSysColorBrush (COLOR_WINDOWTEXT);
FrameRect (hdc, &r, hbr);
SelectObject( hdc, hOldPen );
}
}
/* CHECKME: For `todays date', do we need to check the locale?*/
/* CHECKME: For `todays date', how do is Y2K handled?*/
/* FIXME: todays date circle */
static void MONTHCAL_Refresh (HWND hwnd, HDC hdc)
{
MONTHCAL_INFO *infoPtr=MONTHCAL_GetInfoPtr(hwnd);
RECT *rcClient=&infoPtr->rcClient;
RECT *title=&infoPtr->title;
RECT *prev=&infoPtr->titlebtnprev;
RECT *next=&infoPtr->titlebtnnext;
RECT *titlemonth=&infoPtr->titlemonth;
RECT *titleyear=&infoPtr->titleyear;
RECT *prevmonth=&infoPtr->prevmonth;
RECT *nextmonth=&infoPtr->nextmonth;
RECT *days=&infoPtr->days;
RECT *weeknums=&infoPtr->weeknums;
RECT *rtoday=&infoPtr->today;
int i,j,m,mask,day,firstDay, weeknum,prevMonth;
int textHeight,textWidth;
SIZE size;
HBRUSH hbr;
HFONT currentFont;
TEXTMETRICA tm;
/* LOGFONTA logFont; */
char buf[20],*thisMonthtxt;
COLORREF oldTextColor,oldBkColor;
DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
BOOL prssed;
oldTextColor = SetTextColor(hdc, GetSysColor( COLOR_WINDOWTEXT));
currentFont = SelectObject (hdc, infoPtr->hFont);
/* FIXME: need a way to determine current font, without setting it */
MONTHCAL_INFO *infoPtr=MONTHCAL_GetInfoPtr(hwnd);
RECT *rcClient=&infoPtr->rcClient;
RECT *title=&infoPtr->title;
RECT *prev=&infoPtr->titlebtnprev;
RECT *next=&infoPtr->titlebtnnext;
RECT *titlemonth=&infoPtr->titlemonth;
RECT *titleyear=&infoPtr->titleyear;
RECT *prevmonth=&infoPtr->prevmonth;
RECT *nextmonth=&infoPtr->nextmonth;
RECT *days=&infoPtr->days;
RECT *weeknums=&infoPtr->weeknums;
RECT *rtoday=&infoPtr->today;
int i, j, m, mask, day, firstDay, weeknum, prevMonth;
int textHeight, textWidth;
SIZE size;
HBRUSH hbr;
HFONT currentFont;
TEXTMETRICA tm;
/* LOGFONTA logFont; */
char buf[20],*thisMonthtxt;
COLORREF oldTextColor,oldBkColor;
DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
BOOL prssed;
oldTextColor = SetTextColor(hdc, GetSysColor( COLOR_WINDOWTEXT));
currentFont = SelectObject (hdc, infoPtr->hFont);
/* FIXME: need a way to determine current font, without setting it */
/*
if (infoPtr->hFont!=currentFont) {
SelectObject (hdc, currentFont);
infoPtr->hFont=currentFont;
GetObjectA (currentFont, sizeof (LOGFONTA), &logFont);
logFont.lfWeight=FW_BOLD;
infoPtr->hBoldFont = CreateFontIndirectA (&logFont);
}
if (infoPtr->hFont!=currentFont) {
SelectObject (hdc, currentFont);
infoPtr->hFont=currentFont;
GetObjectA (currentFont, sizeof (LOGFONTA), &logFont);
logFont.lfWeight=FW_BOLD;
infoPtr->hBoldFont = CreateFontIndirectA (&logFont);
}
*/
GetTextMetricsA (hdc, &tm);
infoPtr->textHeight=textHeight=tm.tmHeight + tm.tmExternalLeading;
GetTextExtentPoint32A (hdc, "Sun",3, &size);
infoPtr->textWidth=textWidth=size.cx+2;
GetTextMetricsA (hdc, &tm);
infoPtr->textHeight=textHeight=tm.tmHeight + tm.tmExternalLeading;
GetTextExtentPoint32A (hdc, "Sun",3, &size);
infoPtr->textWidth=textWidth=size.cx+2;
GetClientRect (hwnd, rcClient);
hbr = CreateSolidBrush (RGB(255,255,255));
DrawEdge (hdc, rcClient, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
FillRect (hdc, rcClient, hbr);
DeleteObject (hbr);
/* retrieve the controls client rectangle info infoPtr->rcClient */
GetClientRect (hwnd, rcClient);
/* calculate whole client area & title area */
hbr = CreateSolidBrush (RGB(255,255,255));
DrawEdge (hdc, rcClient, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
FillRect (hdc, rcClient, hbr);
DeleteObject (hbr);
infoPtr->rcClient.right=7*infoPtr->textWidth;
if (dwStyle & MCS_WEEKNUMBERS)
infoPtr->rcClient.right+=infoPtr->textWidth;
/* calculate whole client area & title area */
if (dwStyle & MCS_WEEKNUMBERS)
infoPtr->rcClient.right+=infoPtr->textWidth;
title->top = rcClient->top + 1;
title->bottom = title->top + 2*textHeight + 4;
title->left = rcClient->left + 1;
title->right = rcClient->right - 1;
infoPtr->rcClient.bottom=title->bottom + 6*textHeight;
title->top = rcClient->top + 1;
title->bottom = title->top + 2*textHeight + 4;
title->left = rcClient->left + 1;
title->right = rcClient->right - 1;
/* this is correct, the control does NOT expand vertically like it
does horizontally */
infoPtr->rcClient.bottom = title->bottom + (6 * textHeight);
/* draw header */
/* recalculate the height and width increments and offsets */
infoPtr->width_increment = (infoPtr->rcClient.right - infoPtr->rcClient.left) / 7.0;
infoPtr->height_increment = (infoPtr->rcClient.bottom - infoPtr->rcClient.top) / 7.0;
infoPtr->left_offset = (infoPtr->rcClient.right - infoPtr->rcClient.left) - (infoPtr->width_increment * 7.0);
infoPtr->top_offset = (infoPtr->rcClient.bottom - infoPtr->rcClient.top) - (infoPtr->height_increment * 7.0);
hbr = CreateSolidBrush (infoPtr->titlebk);
FillRect (hdc, title, hbr);
prev->top = next->top = title->top + 6;
prev->bottom = next->bottom = title->top + 2*textHeight - 3;
prev->right = title->left + 28;
prev->left = title->left + 4;
next->left = title->right - 28;
next->right = title->right - 4;
titlemonth->bottom= titleyear->bottom = prev->top + 2*textHeight - 3;
titlemonth->top = titleyear->top = title->top + 6;
titlemonth->left = title->left;
titlemonth->right = title->right;
prssed=FALSE;
if (!(infoPtr->status & MC_PREVPRESSED))
DrawFrameControl(hdc, prev, DFC_SCROLL,
DFCS_SCROLLLEFT | (dwStyle & WS_DISABLED ? DFCS_INACTIVE : 0) );
if (!(infoPtr->status & MC_NEXTPRESSED))
DrawFrameControl(hdc, next, DFC_SCROLL,
DFCS_SCROLLRIGHT | (dwStyle & WS_DISABLED ? DFCS_INACTIVE : 0) );
oldBkColor=SetBkColor (hdc,infoPtr->titlebk);
SetTextColor(hdc, infoPtr->titletxt);
SelectObject (hdc, infoPtr->hBoldFont);
/* draw header */
thisMonthtxt=monthtxt[infoPtr->currentMonth - 1];
sprintf (buf,"%s %ld",thisMonthtxt,infoPtr->currentYear);
DrawTextA ( hdc, buf, strlen(buf), titlemonth,
hbr = CreateSolidBrush (infoPtr->titlebk);
FillRect (hdc, title, hbr);
prev->top = next->top = title->top + 6;
prev->bottom = next->bottom = title->top + 2*textHeight - 3;
prev->right = title->left + 28;
prev->left = title->left + 4;
next->left = title->right - 28;
next->right = title->right - 4;
titlemonth->bottom= titleyear->bottom = prev->top + 2*textHeight - 3;
titlemonth->top = titleyear->top = title->top;
titlemonth->left = title->left;
titlemonth->right = title->right;
prssed = FALSE;
/* if the previous button is pressed draw it depressed */
if ((infoPtr->status & MC_PREVPRESSED))
DrawFrameControl(hdc, prev, DFC_SCROLL,
DFCS_SCROLLLEFT | DFCS_PUSHED |
(dwStyle & WS_DISABLED ? DFCS_INACTIVE : 0));
else /* if the previous button is pressed draw it depressed */
DrawFrameControl(hdc, prev, DFC_SCROLL,
DFCS_SCROLLLEFT | (dwStyle & WS_DISABLED ? DFCS_INACTIVE : 0));
/* if next button is depressed draw it depressed */
if ((infoPtr->status & MC_NEXTPRESSED))
DrawFrameControl(hdc, next, DFC_SCROLL,
DFCS_SCROLLRIGHT | DFCS_PUSHED |
(dwStyle & WS_DISABLED ? DFCS_INACTIVE : 0) );
else /* if the next button is pressed draw it depressed */
DrawFrameControl(hdc, next, DFC_SCROLL,
DFCS_SCROLLRIGHT | (dwStyle & WS_DISABLED ? DFCS_INACTIVE : 0));
oldBkColor = SetBkColor (hdc,infoPtr->titlebk);
SetTextColor(hdc, infoPtr->titletxt);
SelectObject(hdc, infoPtr->hBoldFont);
thisMonthtxt = monthtxt[infoPtr->currentMonth - 1];
sprintf (buf,"%s %ld",thisMonthtxt,infoPtr->currentYear);
DrawTextA ( hdc, buf, strlen(buf), titlemonth,
DT_CENTER | DT_VCENTER | DT_SINGLELINE );
SelectObject (hdc, infoPtr->hFont);
SelectObject (hdc, infoPtr->hFont);
/* titlemonth left/right contained rect for whole titletxt ('June 1999')
* MCM_HitTestInfo wants month & year rects, so prepare these now.
* (no, we can't draw them separately; the whole text is centered)
*/
GetTextExtentPoint32A (hdc, buf,lstrlenA (buf), &size);
titlemonth->left = title->right/2 - size.cx/2;
titleyear->right = title->right/2 + size.cx/2;
GetTextExtentPoint32A (hdc, thisMonthtxt,lstrlenA (thisMonthtxt), &size);
titlemonth->right= titlemonth->left+size.cx;
titleyear->right = titlemonth->right;
GetTextExtentPoint32A (hdc, buf, lstrlenA (buf), &size);
titlemonth->left = title->right/2 - size.cx/2;
titleyear->right = title->right/2 + size.cx/2;
GetTextExtentPoint32A(hdc, thisMonthtxt, lstrlenA (thisMonthtxt), &size);
titlemonth->right= titlemonth->left+size.cx;
titleyear->right = titlemonth->right;
/* draw line under day abbreviatons */
if (dwStyle & MCS_WEEKNUMBERS)
MoveToEx (hdc, rcClient->left+textWidth+3,
title->bottom + textHeight + 2, NULL);
else
MoveToEx (hdc, rcClient->left+3, title->bottom + textHeight + 2, NULL);
LineTo (hdc, rcClient->right-3, title->bottom + textHeight + 2);
if (dwStyle & MCS_WEEKNUMBERS)
MoveToEx (hdc, rcClient->left+textWidth+3, title->bottom + textHeight + 2, NULL);
else
MoveToEx (hdc, rcClient->left+3, title->bottom + textHeight + 2, NULL);
LineTo (hdc, rcClient->right-3, title->bottom + textHeight + 2);
/* draw day abbreviations */
/* draw day abbreviations */
SetBkColor (hdc, infoPtr->monthbk);
SetTextColor(hdc, infoPtr->trailingtxt);
SetBkColor (hdc, infoPtr->monthbk);
SetTextColor(hdc, infoPtr->trailingtxt);
days->left = rcClient->left;
if (dwStyle & MCS_WEEKNUMBERS) days->left+=textWidth;
days->right = days->left + textWidth;
days->top = title->bottom + 2;
days->bottom = title->bottom + textHeight + 2;
i=infoPtr->firstDay;
days->left = infoPtr->left_offset;
if (dwStyle & MCS_WEEKNUMBERS) days->left+=textWidth;
days->right = days->left + infoPtr->width_increment;
days->top = title->bottom + 2;
days->bottom = title->bottom + textHeight + 2;
i = infoPtr->firstDay;
for (j=0; j<7; j++) {
DrawTextA ( hdc, daytxt[i], strlen(daytxt[i]), days,
for (j=0; j<7; j++) {
DrawTextA ( hdc, daytxt[i], strlen(daytxt[i]), days,
DT_CENTER | DT_VCENTER | DT_SINGLELINE );
i++;
if (i>7) i-=7;
days->left+=textWidth;
days->right+=textWidth;
}
i = (i + 1) % 7;
days->left+=infoPtr->width_increment;
days->right+=infoPtr->width_increment;
}
days->left = rcClient->left + j;
if (dwStyle & MCS_WEEKNUMBERS) days->left+=textWidth;
days->right = rcClient->left + (j+1)*textWidth-2;
days->left = rcClient->left + j;
if (dwStyle & MCS_WEEKNUMBERS) days->left+=textWidth;
/* FIXME: this may need to be changed now 11/10/99 CMM */
days->right = rcClient->left + (j+1)*textWidth-2;
/* draw day numbers; first, the previous month */
prevmonth->left=0;
if (dwStyle & MCS_WEEKNUMBERS) prevmonth->left=textWidth;
firstDay=MONTHCAL_CalculateDayOfWeek (1,infoPtr->currentMonth,infoPtr->currentYear);
prevMonth=infoPtr->currentMonth-1;
if (prevMonth==0) prevMonth=11;
day=mdays[prevMonth]-firstDay;
mask=1<<(day-1);
i=0;
m=0;
while (day<=mdays[prevMonth]) {
MONTHCAL_DrawDay (hdc, infoPtr, day, prevMonth, i, 0,
infoPtr->monthdayState[m] & mask);
mask<<=1;
day++;
i++;
}
prevmonth->right = prevmonth->left+i*textWidth;
prevmonth->top = days->bottom;
prevmonth->bottom= prevmonth->top + textHeight;
prevmonth->left = 0;
if (dwStyle & MCS_WEEKNUMBERS) prevmonth->left=textWidth;
firstDay = MONTHCAL_CalculateDayOfWeek (1, infoPtr->currentMonth, infoPtr->currentYear);
prevMonth = infoPtr->currentMonth-1;
if (prevMonth == 0) /* if currentMonth is january(1) prevMonth is */
prevMonth = 12; /* december(12) of the previous year */
day = MONTHCAL_MonthLength(prevMonth, infoPtr->currentYear) - firstDay;
mask = 1<<(day-1);
i = 0;
m = 0;
while (day <= MONTHCAL_MonthLength(prevMonth, infoPtr->currentYear)) {
MONTHCAL_DrawDay (hdc, infoPtr, day, prevMonth, i, 0,
infoPtr->monthdayState[m] & mask);
mask<<=1;
day++;
i++;
}
prevmonth->right = prevmonth->left+i*textWidth;
prevmonth->top = days->bottom;
prevmonth->bottom= prevmonth->top + textHeight;
/* draw `current' month */
day=1;
infoPtr->firstDayplace=i;
SetTextColor(hdc, infoPtr->txt);
m++;
mask=1;
while (i<7) {
MONTHCAL_DrawDay (hdc, infoPtr, day, infoPtr->currentMonth, i, 0,
infoPtr->monthdayState[m] & mask);
if ((infoPtr->currentMonth==infoPtr->todaysDate.wMonth) &&
(day==infoPtr->todaysDate.wDay))
MONTHCAL_CircleDay (hdc, infoPtr, i,j);
mask<<=1;
day++;
i++;
}
j=1;
i=0;
while (day<=mdays[infoPtr->currentMonth]) {
MONTHCAL_DrawDay (hdc, infoPtr, day, infoPtr->currentMonth, i, j,
infoPtr->monthdayState[m] & mask);
if ((infoPtr->currentMonth==infoPtr->todaysDate.wMonth) &&
(day==infoPtr->todaysDate.wDay))
MONTHCAL_CircleDay (hdc, infoPtr, i,j);
mask<<=1;
day++;
i++;
if (i>6) {
i=0;
j++;
}
}
day = 1; /* start at the beginning of the current month */
infoPtr->firstDayplace = i;
SetTextColor(hdc, infoPtr->txt);
m++;
mask = 1;
/* draw the first week of the current month */
while (i<7) {
MONTHCAL_DrawDay (hdc, infoPtr, day, infoPtr->currentMonth, i, 0,
infoPtr->monthdayState[m] & mask);
if ((infoPtr->currentMonth==infoPtr->todaysDate.wMonth) &&
(day==infoPtr->todaysDate.wDay) &&
(infoPtr->currentYear == infoPtr->todaysDate.wYear)) {
MONTHCAL_CircleDay (hdc, infoPtr, day, infoPtr->currentMonth);
}
mask<<=1;
day++;
i++;
}
j = 1; /* move to the 2nd week of the current month */
i = 0; /* move back to sunday */
while (day <= MONTHCAL_MonthLength(infoPtr->currentMonth, infoPtr->currentYear)) {
MONTHCAL_DrawDay (hdc, infoPtr, day, infoPtr->currentMonth, i, j,
infoPtr->monthdayState[m] & mask);
if ((infoPtr->currentMonth==infoPtr->todaysDate.wMonth) &&
(day==infoPtr->todaysDate.wDay) &&
(infoPtr->currentYear == infoPtr->todaysDate.wYear))
MONTHCAL_CircleDay (hdc, infoPtr, day, infoPtr->currentMonth);
mask<<=1;
day++;
i++;
if (i>6) { /* past saturday, goto the next weeks sunday */
i = 0;
j++;
}
}
/* draw `next' month */
......@@ -498,253 +561,247 @@ static void MONTHCAL_Refresh (HWND hwnd, HDC hdc)
* be drawn to complete the month calendar is not taken into account in
* this rect -- HitTest knows about this.*/
nextmonth->left = prevmonth->left+i*textWidth;
nextmonth->right = rcClient->right;
nextmonth->top = days->bottom+(j+1)*textHeight;
nextmonth->bottom = nextmonth->top + textHeight;
day=1;
m++;
mask=1;
SetTextColor(hdc, infoPtr->trailingtxt);
while ((i<7) && (j<6)) {
MONTHCAL_DrawDay (hdc, infoPtr, day, infoPtr->currentMonth+1, i, j,
infoPtr->monthdayState[m] & mask);
mask<<=1;
day++;
i++;
if (i==7) {
i=0;
j++;
}
}
SetTextColor(hdc, infoPtr->txt);
nextmonth->left = prevmonth->left+i*textWidth;
nextmonth->right = rcClient->right;
nextmonth->top = days->bottom+(j+1)*textHeight;
nextmonth->bottom = nextmonth->top + textHeight;
day = 1; /* start at the first day of the next month */
m++;
mask = 1;
SetTextColor(hdc, infoPtr->trailingtxt);
while ((i<7) && (j<6)) {
MONTHCAL_DrawDay (hdc, infoPtr, day, infoPtr->currentMonth + 1, i, j,
infoPtr->monthdayState[m] & mask);
mask<<=1;
day++;
i++;
if (i==7) { /* past saturday, go to next week's sunday */
i = 0;
j++;
}
}
SetTextColor(hdc, infoPtr->txt);
/* draw `today' date if style allows it, and draw a circle before today's
* date if necessairy */
if (!( dwStyle & MCS_NOTODAY)) {
int offset=0;
if (!( dwStyle & MCS_NOTODAYCIRCLE)) {
MONTHCAL_CircleDay (hdc, infoPtr, 0, 6);
offset+=textWidth;
}
MONTHCAL_CalcDayRect (infoPtr, rtoday, offset==textWidth, 6);
sprintf (buf,"Today: %d/%d/%d",infoPtr->todaysDate.wMonth,
infoPtr->todaysDate.wDay, infoPtr->todaysDate.wYear-1900);
rtoday->right = rcClient->right;
SelectObject (hdc, infoPtr->hBoldFont);
DrawTextA ( hdc, buf, lstrlenA(buf), rtoday,
DT_LEFT | DT_VCENTER | DT_SINGLELINE );
SelectObject (hdc, infoPtr->hFont);
}
* date if necessary */
if (dwStyle & MCS_WEEKNUMBERS) {
/* display weeknumbers*/
if (!( dwStyle & MCS_NOTODAY)) {
int offset = 0;
if (!( dwStyle & MCS_NOTODAYCIRCLE)) {
MONTHCAL_CircleDay (hdc, infoPtr, day, infoPtr->currentMonth + 1);
offset+=textWidth;
}
MONTHCAL_CalcDayRect (infoPtr, rtoday, offset==textWidth, 6);
sprintf (buf,"Today: %d/%d/%d",infoPtr->todaysDate.wMonth,
infoPtr->todaysDate.wDay, infoPtr->todaysDate.wYear % 100);
rtoday->right = rcClient->right;
SelectObject (hdc, infoPtr->hBoldFont);
DrawTextA ( hdc, buf, lstrlenA(buf), rtoday,
DT_LEFT | DT_VCENTER | DT_SINGLELINE );
SelectObject (hdc, infoPtr->hFont);
}
weeknums->left = 0;
weeknums->right = textWidth;
weeknums->top = days->bottom + 2;
weeknums->bottom = days->bottom + 2 + textHeight;
if (dwStyle & MCS_WEEKNUMBERS) {
/* display weeknumbers*/
weeknums->left = 0;
weeknums->right = textWidth;
weeknums->top = days->bottom + 2;
weeknums->bottom = days->bottom + 2 + textHeight;
weeknum=0;
for (i=0; i<infoPtr->currentMonth-1; i++)
weeknum+=mdays[i];
weeknum/=7;
for (i=0; i<6; i++) {
sprintf (buf,"%d",weeknum+i);
DrawTextA ( hdc, buf, lstrlenA(buf), weeknums,
weeknum=0;
for (i=0; i<infoPtr->currentMonth-1; i++)
weeknum+=MONTHCAL_MonthLength(i, infoPtr->currentYear);
weeknum/=7;
for (i=0; i<6; i++) {
sprintf (buf,"%d",weeknum+i);
DrawTextA ( hdc, buf, lstrlenA(buf), weeknums,
DT_CENTER | DT_BOTTOM | DT_SINGLELINE );
weeknums->top+=textHeight*1.25;
weeknums->bottom+=textHeight*1.25;
}
weeknums->top+=textHeight*1.25;
weeknums->bottom+=textHeight*1.25;
}
MoveToEx (hdc, weeknums->right, days->bottom+5 , NULL);
LineTo (hdc, weeknums->right, weeknums->bottom-1.25*textHeight-5);
MoveToEx (hdc, weeknums->right, days->bottom+5 , NULL);
LineTo (hdc, weeknums->right, weeknums->bottom-1.25*textHeight-5);
}
}
/* currentFont was font at entering Refresh */
/* currentFont was font at entering Refresh */
SetBkColor (hdc, oldBkColor);
SelectObject (hdc, currentFont);
SetTextColor (hdc, oldTextColor);
SetBkColor (hdc, oldBkColor);
SelectObject (hdc, currentFont);
SetTextColor (hdc, oldTextColor);
}
static LRESULT
MONTHCAL_GetMinReqRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
MONTHCAL_INFO *infoPtr=MONTHCAL_GetInfoPtr(hwnd);
LPRECT lpRect=(LPRECT) lParam;
TRACE ("%x %lx\n",wParam,lParam);
MONTHCAL_INFO *infoPtr=MONTHCAL_GetInfoPtr(hwnd);
LPRECT lpRect=(LPRECT) lParam;
TRACE ("%x %lx\n",wParam,lParam);
/* validate parameters */
if ( (infoPtr==NULL) || (lpRect == NULL) ) return FALSE;
if ( (infoPtr==NULL) || (lpRect == NULL) ) return FALSE;
lpRect->left=infoPtr->rcClient.left;
lpRect->right=infoPtr->rcClient.right;
lpRect->top=infoPtr->rcClient.top;
lpRect->bottom=infoPtr->rcClient.bottom;
return TRUE;
lpRect->left = infoPtr->rcClient.left;
lpRect->right = infoPtr->rcClient.right;
lpRect->top = infoPtr->rcClient.top;
lpRect->bottom = infoPtr->rcClient.bottom;
return TRUE;
}
static LRESULT
MONTHCAL_GetColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
MONTHCAL_INFO *infoPtr=MONTHCAL_GetInfoPtr(hwnd);
TRACE ("%x %lx\n",wParam,lParam);
switch ((int)wParam) {
case MCSC_BACKGROUND:
return infoPtr->bk;
case MCSC_TEXT:
return infoPtr->txt;
case MCSC_TITLEBK:
return infoPtr->titlebk;
case MCSC_TITLETEXT:
return infoPtr->titletxt;
case MCSC_MONTHBK:
return infoPtr->monthbk;
case MCSC_TRAILINGTEXT:
return infoPtr->trailingtxt;
}
return -1;
MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
TRACE ("%x %lx\n",wParam,lParam);
switch ((int)wParam) {
case MCSC_BACKGROUND:
return infoPtr->bk;
case MCSC_TEXT:
return infoPtr->txt;
case MCSC_TITLEBK:
return infoPtr->titlebk;
case MCSC_TITLETEXT:
return infoPtr->titletxt;
case MCSC_MONTHBK:
return infoPtr->monthbk;
case MCSC_TRAILINGTEXT:
return infoPtr->trailingtxt;
}
return -1;
}
static LRESULT
MONTHCAL_SetColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
MONTHCAL_INFO *infoPtr=MONTHCAL_GetInfoPtr(hwnd);
int prev=-1;
TRACE ("%x %lx\n",wParam,lParam);
switch ((int)wParam) {
case MCSC_BACKGROUND:
prev=infoPtr->bk;
infoPtr->bk=(COLORREF) lParam;
break;
case MCSC_TEXT:
prev=infoPtr->txt;
infoPtr->txt=(COLORREF) lParam;
break;
case MCSC_TITLEBK:
prev=infoPtr->titlebk;
infoPtr->titlebk=(COLORREF) lParam;
break;
case MCSC_TITLETEXT:
prev=infoPtr->titletxt;
infoPtr->titletxt=(COLORREF) lParam;
break;
case MCSC_MONTHBK:
prev=infoPtr->monthbk;
infoPtr->monthbk=(COLORREF) lParam;
break;
case MCSC_TRAILINGTEXT:
prev=infoPtr->trailingtxt;
infoPtr->trailingtxt=(COLORREF) lParam;
break;
}
return prev;
MONTHCAL_INFO *infoPtr=MONTHCAL_GetInfoPtr(hwnd);
int prev=-1;
TRACE ("%x %lx\n", wParam, lParam);
switch ((int)wParam) {
case MCSC_BACKGROUND:
prev = infoPtr->bk;
infoPtr->bk = (COLORREF)lParam;
break;
case MCSC_TEXT:
prev = infoPtr->txt;
infoPtr->txt = (COLORREF)lParam;
break;
case MCSC_TITLEBK:
prev = infoPtr->titlebk;
infoPtr->titlebk = (COLORREF)lParam;
break;
case MCSC_TITLETEXT:
prev=infoPtr->titletxt;
infoPtr->titletxt = (COLORREF)lParam;
break;
case MCSC_MONTHBK:
prev = infoPtr->monthbk;
infoPtr->monthbk = (COLORREF)lParam;
break;
case MCSC_TRAILINGTEXT:
prev = infoPtr->trailingtxt;
infoPtr->trailingtxt = (COLORREF)lParam;
break;
}
return prev;
}
static LRESULT
MONTHCAL_GetMonthDelta (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
MONTHCAL_INFO *infoPtr=MONTHCAL_GetInfoPtr(hwnd);
MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
TRACE ("%x %lx\n",wParam,lParam);
if (infoPtr->delta) return infoPtr->delta;
else return infoPtr->visible;
TRACE ("%x %lx\n", wParam, lParam);
if (infoPtr->delta)
return infoPtr->delta;
else
return infoPtr->visible;
}
static LRESULT
MONTHCAL_SetMonthDelta (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
MONTHCAL_INFO *infoPtr=MONTHCAL_GetInfoPtr(hwnd);
int prev=infoPtr->delta;
MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
int prev = infoPtr->delta;
TRACE ("%x %lx\n",wParam,lParam);
TRACE ("%x %lx\n", wParam, lParam);
infoPtr->delta=(int) wParam;
return prev;
infoPtr->delta = (int)wParam;
return prev;
}
static LRESULT
MONTHCAL_GetFirstDayOfWeek (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
MONTHCAL_INFO *infoPtr=MONTHCAL_GetInfoPtr(hwnd);
MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
return infoPtr->firstDay;
return infoPtr->firstDay;
}
/* FIXME: we need more error checking here */
/* sets the first day of the week that will appear in the control */
/* 0 == Monday, 6 == Sunday */
/* FIXME: this needs to be implemented properly in MONTHCAL_Refresh() */
/* FIXME: we need more error checking here */
static LRESULT
MONTHCAL_SetFirstDayOfWeek (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
MONTHCAL_INFO *infoPtr=MONTHCAL_GetInfoPtr(hwnd);
int prev=infoPtr->firstDay;
char buf[40];
int day;
TRACE ("%x %lx\n",wParam,lParam);
if ((lParam>=0) && (lParam<7)) {
infoPtr->firstDay=(int) lParam;
GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_IFIRSTDAYOFWEEK,
buf, sizeof(buf));
TRACE ("%s %d\n",buf,strlen(buf));
if ((sscanf(buf,"%d",&day)==1) && (infoPtr->firstDay!=day))
infoPtr->firstDay|=HIWORD(TRUE);
}
return prev;
MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
int prev = infoPtr->firstDay;
char buf[40];
int day;
TRACE ("%x %lx\n", wParam, lParam);
if ((lParam >= 0) && (lParam < 7)) {
infoPtr->firstDay = (int)lParam;
GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_IFIRSTDAYOFWEEK,
buf, sizeof(buf));
TRACE ("%s %d\n", buf, strlen(buf));
if ((sscanf(buf, "%d", &day) == 1) && (infoPtr->firstDay != day))
infoPtr->firstDay = day;
}
return prev;
}
/* FIXME: fill this in */
static LRESULT
MONTHCAL_GetMonthRange (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
MONTHCAL_INFO *infoPtr=MONTHCAL_GetInfoPtr(hwnd);
MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
TRACE ("%x %lx\n",wParam,lParam);
FIXME("stub\n");
return infoPtr->monthRange;
}
static LRESULT
MONTHCAL_GetMaxTodayWidth (HWND hwnd)
{
MONTHCAL_INFO *infoPtr=MONTHCAL_GetInfoPtr(hwnd);
MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
return (infoPtr->today.right-infoPtr->today.left);
return (infoPtr->today.right-infoPtr->today.left);
}
/* FIXME: are validated times taken from current date/time or simply
* copied?
* FIXME: check whether MCM_GETMONTHRANGE shows correct result after
......@@ -754,36 +811,38 @@ MONTHCAL_GetMaxTodayWidth (HWND hwnd)
static LRESULT
MONTHCAL_SetRange (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
MONTHCAL_INFO *infoPtr=MONTHCAL_GetInfoPtr(hwnd);
MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
SYSTEMTIME lprgSysTimeArray[1];
int prev;
TRACE ("%x %lx\n",wParam,lParam);
if (wParam & GDTR_MAX) {
if (MONTHCAL_ValidateTime(lprgSysTimeArray[1])){
MONTHCAL_CopyTime (&lprgSysTimeArray[1],&infoPtr->maxDate);
infoPtr->rangeValid|=GDTR_MAX;
} else {
GetSystemTime (&infoPtr->todaysDate);
MONTHCAL_CopyTime (&infoPtr->todaysDate,&infoPtr->maxDate);
}
}
if (MONTHCAL_ValidateTime(lprgSysTimeArray[1])){
MONTHCAL_CopyTime (&lprgSysTimeArray[1],&infoPtr->maxDate);
infoPtr->rangeValid|=GDTR_MAX;
} else {
GetSystemTime (&infoPtr->todaysDate);
MONTHCAL_CopyTime (&infoPtr->todaysDate,&infoPtr->maxDate);
}
}
if (wParam & GDTR_MIN) {
if (MONTHCAL_ValidateTime(lprgSysTimeArray[0])) {
MONTHCAL_CopyTime (&lprgSysTimeArray[0],&infoPtr->maxDate);
infoPtr->rangeValid|=GDTR_MIN;
} else {
GetSystemTime (&infoPtr->todaysDate);
MONTHCAL_CopyTime (&infoPtr->todaysDate,&infoPtr->maxDate);
}
}
prev=infoPtr->monthRange;
infoPtr->monthRange=infoPtr->maxDate.wMonth-infoPtr->minDate.wMonth;
if (infoPtr->monthRange!=prev)
if (MONTHCAL_ValidateTime(lprgSysTimeArray[0])) {
MONTHCAL_CopyTime (&lprgSysTimeArray[0],&infoPtr->maxDate);
infoPtr->rangeValid|=GDTR_MIN;
} else {
GetSystemTime (&infoPtr->todaysDate);
MONTHCAL_CopyTime (&infoPtr->todaysDate,&infoPtr->maxDate);
}
}
prev = infoPtr->monthRange;
infoPtr->monthRange = infoPtr->maxDate.wMonth-infoPtr->minDate.wMonth;
if (infoPtr->monthRange!=prev) {
COMCTL32_ReAlloc (infoPtr->monthdayState,
infoPtr->monthRange*sizeof(MONTHDAYSTATE));
}
return 1;
}
......@@ -797,40 +856,42 @@ MONTHCAL_SetRange (HWND hwnd, WPARAM wParam, LPARAM lParam)
static LRESULT
MONTHCAL_GetRange (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
MONTHCAL_INFO *infoPtr=MONTHCAL_GetInfoPtr(hwnd);
SYSTEMTIME *lprgSysTimeArray=(SYSTEMTIME *) lParam;
MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
SYSTEMTIME *lprgSysTimeArray = (SYSTEMTIME *)lParam;
/* validate parameters */
if ( (infoPtr==NULL) || (lprgSysTimeArray==NULL) ) return FALSE;
MONTHCAL_CopyTime (&infoPtr->maxDate,&lprgSysTimeArray[1]);
MONTHCAL_CopyTime (&infoPtr->minDate,&lprgSysTimeArray[0]);
MONTHCAL_CopyTime(&infoPtr->maxDate,&lprgSysTimeArray[1]);
MONTHCAL_CopyTime(&infoPtr->minDate,&lprgSysTimeArray[0]);
return infoPtr->rangeValid;
}
static LRESULT
MONTHCAL_SetDayState (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
MONTHCAL_INFO *infoPtr=MONTHCAL_GetInfoPtr(hwnd);
int i,iMonths=(int) wParam;
MONTHDAYSTATE *dayStates=(LPMONTHDAYSTATE) lParam;
MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
int i, iMonths = (int)wParam;
MONTHDAYSTATE *dayStates = (LPMONTHDAYSTATE)lParam;
TRACE ("%x %lx\n",wParam,lParam);
if (iMonths!=infoPtr->monthRange) return 0;
for (i=0; i<iMonths; i++)
infoPtr->monthdayState[i]=dayStates[i];
infoPtr->monthdayState[i]=dayStates[i];
return 1;
}
static LRESULT
MONTHCAL_GetCurSel (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
MONTHCAL_INFO *infoPtr=MONTHCAL_GetInfoPtr(hwnd);
SYSTEMTIME *lpSel=(SYSTEMTIME *) lParam;
MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
SYSTEMTIME *lpSel = (SYSTEMTIME *) lParam;
TRACE ("%x %lx\n",wParam,lParam);
if ( (infoPtr==NULL) || (lpSel==NULL) ) return FALSE;
......@@ -843,12 +904,11 @@ MONTHCAL_GetCurSel (HWND hwnd, WPARAM wParam, LPARAM lParam)
/* FIXME: if the specified date is not visible, make it visible */
/* FIXME: redraw? */
static LRESULT
MONTHCAL_SetCurSel (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
MONTHCAL_INFO *infoPtr=MONTHCAL_GetInfoPtr(hwnd);
SYSTEMTIME *lpSel=(SYSTEMTIME *) lParam;
MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
SYSTEMTIME *lpSel = (SYSTEMTIME *) lParam;
TRACE ("%x %lx\n",wParam,lParam);
if ( (infoPtr==NULL) || (lpSel==NULL) ) return FALSE;
......@@ -862,23 +922,25 @@ MONTHCAL_SetCurSel (HWND hwnd, WPARAM wParam, LPARAM lParam)
return TRUE;
}
static LRESULT
MONTHCAL_GetMaxSelCount (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
MONTHCAL_INFO *infoPtr=MONTHCAL_GetInfoPtr(hwnd);
MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
TRACE ("%x %lx\n",wParam,lParam);
TRACE ("%x %lx\n", wParam, lParam);
return infoPtr->maxSelCount;
}
static LRESULT
MONTHCAL_SetMaxSelCount (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
MONTHCAL_INFO *infoPtr=MONTHCAL_GetInfoPtr(hwnd);
MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
TRACE ("%x %lx\n",wParam,lParam);
TRACE ("%x %lx\n", wParam, lParam);
if ( GetWindowLongA( hwnd, GWL_STYLE) & MCS_MULTISELECT) {
infoPtr->maxSelCount=wParam;
infoPtr->maxSelCount = wParam;
}
return TRUE;
......@@ -888,8 +950,8 @@ MONTHCAL_SetMaxSelCount (HWND hwnd, WPARAM wParam, LPARAM lParam)
static LRESULT
MONTHCAL_GetSelRange (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
MONTHCAL_INFO *infoPtr=MONTHCAL_GetInfoPtr(hwnd);
SYSTEMTIME *lprgSysTimeArray=(SYSTEMTIME *) lParam;
MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
SYSTEMTIME *lprgSysTimeArray = (SYSTEMTIME *) lParam;
TRACE ("%x %lx\n",wParam,lParam);
......@@ -898,20 +960,21 @@ MONTHCAL_GetSelRange (HWND hwnd, WPARAM wParam, LPARAM lParam)
if ( (infoPtr==NULL) || (lprgSysTimeArray==NULL) ) return FALSE;
if ( GetWindowLongA( hwnd, GWL_STYLE) & MCS_MULTISELECT) {
MONTHCAL_CopyTime (&infoPtr->maxSel,&lprgSysTimeArray[1]);
MONTHCAL_CopyTime (&infoPtr->minSel,&lprgSysTimeArray[0]);
TRACE ("[min,max]=[%d %d]\n",infoPtr->minSel.wDay,infoPtr->maxSel.wDay);
return TRUE;
MONTHCAL_CopyTime (&infoPtr->maxSel,&lprgSysTimeArray[1]);
MONTHCAL_CopyTime (&infoPtr->minSel,&lprgSysTimeArray[0]);
TRACE ("[min,max]=[%d %d]\n", infoPtr->minSel.wDay, infoPtr->maxSel.wDay);
return TRUE;
}
return FALSE;
}
static LRESULT
MONTHCAL_SetSelRange (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
MONTHCAL_INFO *infoPtr=MONTHCAL_GetInfoPtr(hwnd);
SYSTEMTIME *lprgSysTimeArray=(SYSTEMTIME *) lParam;
MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
SYSTEMTIME *lprgSysTimeArray = (SYSTEMTIME *) lParam;
TRACE ("%x %lx\n",wParam,lParam);
......@@ -920,25 +983,23 @@ MONTHCAL_SetSelRange (HWND hwnd, WPARAM wParam, LPARAM lParam)
if ( (infoPtr==NULL) || (lprgSysTimeArray==NULL) ) return FALSE;
if ( GetWindowLongA( hwnd, GWL_STYLE) & MCS_MULTISELECT) {
MONTHCAL_CopyTime (&lprgSysTimeArray[1],&infoPtr->maxSel);
MONTHCAL_CopyTime (&lprgSysTimeArray[0],&infoPtr->minSel);
TRACE ("[min,max]=[%d %d]\n",infoPtr->minSel.wDay,infoPtr->maxSel.wDay);
return TRUE;
MONTHCAL_CopyTime (&lprgSysTimeArray[1],&infoPtr->maxSel);
MONTHCAL_CopyTime (&lprgSysTimeArray[0],&infoPtr->minSel);
TRACE ("[min,max]=[%d %d]\n", infoPtr->minSel.wDay, infoPtr->maxSel.wDay);
return TRUE;
}
return FALSE;
}
static LRESULT
MONTHCAL_GetToday (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
MONTHCAL_INFO *infoPtr=MONTHCAL_GetInfoPtr(hwnd);
SYSTEMTIME *lpToday=(SYSTEMTIME *) lParam;
MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
SYSTEMTIME *lpToday = (SYSTEMTIME *) lParam;
TRACE ("%x %lx\n",wParam,lParam);
TRACE ("%x %lx\n", wParam, lParam);
/* validate parameters */
......@@ -951,10 +1012,10 @@ MONTHCAL_GetToday (HWND hwnd, WPARAM wParam, LPARAM lParam)
static LRESULT
MONTHCAL_SetToday (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
MONTHCAL_INFO *infoPtr=MONTHCAL_GetInfoPtr(hwnd);
SYSTEMTIME *lpToday=(SYSTEMTIME *) lParam;
MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
SYSTEMTIME *lpToday = (SYSTEMTIME *) lParam;
TRACE ("%x %lx\n",wParam,lParam);
TRACE ("%x %lx\n", wParam, lParam);
/* validate parameters */
......@@ -964,69 +1025,67 @@ MONTHCAL_SetToday (HWND hwnd, WPARAM wParam, LPARAM lParam)
}
static LRESULT
MONTHCAL_HitTest (HWND hwnd, LPARAM lParam)
{
MONTHCAL_INFO *infoPtr=MONTHCAL_GetInfoPtr(hwnd);
PMCHITTESTINFO lpht=(PMCHITTESTINFO) lParam;
MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
PMCHITTESTINFO lpht = (PMCHITTESTINFO) lParam;
UINT x,y;
DWORD retval;
x=lpht->pt.x;
y=lpht->pt.y;
retval=MCHT_NOWHERE;
x = lpht->pt.x;
y = lpht->pt.y;
retval = MCHT_NOWHERE;
/* are we in the header? */
/* are we in the header? */
if (PtInRect (&infoPtr->title, lpht->pt)) {
if (PtInRect (&infoPtr->titlebtnprev, lpht->pt)) {
retval=MCHT_TITLEBTNPREV;
goto done;
}
if (PtInRect (&infoPtr->titlebtnnext, lpht->pt)) {
retval=MCHT_TITLEBTNNEXT;
goto done;
}
if (PtInRect (&infoPtr->titlemonth, lpht->pt)) {
retval=MCHT_TITLEMONTH;
goto done;
}
if (PtInRect (&infoPtr->titleyear, lpht->pt)) {
retval=MCHT_TITLEYEAR;
goto done;
}
retval=MCHT_TITLE;
goto done;
}
if (PtInRect (&infoPtr->days, lpht->pt)) {
retval=MCHT_CALENDARDAY; /* FIXME: find out which day we're on */
goto done;
}
if (PtInRect (&infoPtr->weeknums, lpht->pt)) {
retval=MCHT_CALENDARWEEKNUM;/* FIXME: find out which day we're on */
goto done;
}
if (PtInRect (&infoPtr->prevmonth, lpht->pt)) {
retval=MCHT_CALENDARDATEPREV;
goto done;
}
if (PtInRect (&infoPtr->nextmonth, lpht->pt) ||
if (PtInRect (&infoPtr->title, lpht->pt)) {
if (PtInRect (&infoPtr->titlebtnprev, lpht->pt)) {
retval = MCHT_TITLEBTNPREV;
goto done;
}
if (PtInRect (&infoPtr->titlebtnnext, lpht->pt)) {
retval = MCHT_TITLEBTNNEXT;
goto done;
}
if (PtInRect (&infoPtr->titlemonth, lpht->pt)) {
retval = MCHT_TITLEMONTH;
goto done;
}
if (PtInRect (&infoPtr->titleyear, lpht->pt)) {
retval = MCHT_TITLEYEAR;
goto done;
}
retval = MCHT_TITLE;
goto done;
}
if (PtInRect (&infoPtr->days, lpht->pt)) {
retval = MCHT_CALENDARDAY; /* FIXME: find out which day we're on */
goto done;
}
if (PtInRect (&infoPtr->weeknums, lpht->pt)) {
retval = MCHT_CALENDARWEEKNUM; /* FIXME: find out which day we're on */
goto done;
}
if (PtInRect (&infoPtr->prevmonth, lpht->pt)) {
retval = MCHT_CALENDARDATEPREV;
goto done;
}
if (PtInRect (&infoPtr->nextmonth, lpht->pt) ||
((x>infoPtr->nextmonth.left) && (x<infoPtr->nextmonth.right) &&
(y>infoPtr->nextmonth.bottom) && (y<infoPtr->today.top ))) {
retval=MCHT_CALENDARDATENEXT;
goto done;
}
retval = MCHT_CALENDARDATENEXT;
goto done;
}
if (PtInRect (&infoPtr->today, lpht->pt)) {
retval=MCHT_TODAYLINK;
goto done;
}
if (PtInRect (&infoPtr->today, lpht->pt)) {
retval = MCHT_TODAYLINK;
goto done;
}
/* MCHT_CALENDARDATE determination: since the next & previous month have
* been handled already (MCHT_CALENDARDATEPREV/NEXT), we only have to check
......@@ -1040,571 +1099,560 @@ MONTHCAL_HitTest (HWND hwnd, LPARAM lParam)
infoPtr->prevmonth.top, infoPtr->prevmonth.bottom,
infoPtr->nextmonth.left, infoPtr->nextmonth.right,
infoPtr->nextmonth.top, infoPtr->nextmonth.bottom);
if ((x>infoPtr->prevmonth.left) && (x<infoPtr->nextmonth.right) &&
(y>infoPtr->prevmonth.top) && (y<infoPtr->nextmonth.bottom)) {
lpht->st.wYear=infoPtr->currentYear;
lpht->st.wMonth=infoPtr->currentMonth;
if ((x>infoPtr->prevmonth.left) && (x<infoPtr->nextmonth.right) &&
(y>infoPtr->prevmonth.top) && (y<infoPtr->nextmonth.bottom)) {
lpht->st.wYear = infoPtr->currentYear;
lpht->st.wMonth = infoPtr->currentMonth;
lpht->st.wDay=MONTHCAL_CalcDayFromPos (infoPtr,x,y);
lpht->st.wDay = MONTHCAL_CalcDayFromPos (infoPtr,x,y);
TRACE ("day hit: %d\n",lpht->st.wDay);
retval=MCHT_CALENDARDATE;
goto done;
TRACE ("day hit: %d\n",lpht->st.wDay);
retval = MCHT_CALENDARDATE;
goto done;
}
}
/* Hit nothing special? What's left must be background :-) */
/* Hit nothing special? What's left must be background :-) */
retval=MCHT_CALENDARBK;
retval = MCHT_CALENDARBK;
done:
lpht->uHit=retval;
lpht->uHit = retval;
return retval;
}
static void MONTHCAL_GoToNextMonth (HWND hwnd, MONTHCAL_INFO *infoPtr)
{
DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
TRACE ("\n");
DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
infoPtr->currentMonth++;
if (infoPtr->currentMonth>12) {
infoPtr->currentYear++;
infoPtr->currentMonth=1;
}
TRACE ("\n");
if (dwStyle & MCS_DAYSTATE) {
NMDAYSTATE nmds;
int i;
infoPtr->currentMonth++;
if (infoPtr->currentMonth > 12) {
infoPtr->currentYear++;
infoPtr->currentMonth = 1;
}
nmds.nmhdr.hwndFrom = hwnd;
nmds.nmhdr.idFrom = GetWindowLongA( hwnd, GWL_ID);
nmds.nmhdr.code = MCN_GETDAYSTATE;
nmds.cDayState = infoPtr->monthRange;
nmds.prgDayState = COMCTL32_Alloc
(infoPtr->monthRange*sizeof(MONTHDAYSTATE));
if (dwStyle & MCS_DAYSTATE) {
NMDAYSTATE nmds;
int i;
SendMessageA (GetParent (hwnd), WM_NOTIFY,
(WPARAM)nmds.nmhdr.idFrom, (LPARAM)&nmds);
for (i=0; i<infoPtr->monthRange; i++)
infoPtr->monthdayState[i]=nmds.prgDayState[i];
}
nmds.nmhdr.hwndFrom = hwnd;
nmds.nmhdr.idFrom = GetWindowLongA( hwnd, GWL_ID);
nmds.nmhdr.code = MCN_GETDAYSTATE;
nmds.cDayState = infoPtr->monthRange;
nmds.prgDayState = COMCTL32_Alloc(infoPtr->monthRange*sizeof(MONTHDAYSTATE));
SendMessageA (GetParent (hwnd), WM_NOTIFY,
(WPARAM)nmds.nmhdr.idFrom, (LPARAM)&nmds);
for (i=0; i<infoPtr->monthRange; i++)
infoPtr->monthdayState[i] = nmds.prgDayState[i];
}
}
static void MONTHCAL_GoToPrevMonth (HWND hwnd, MONTHCAL_INFO *infoPtr)
{
DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
TRACE ("\n");
infoPtr->currentMonth--;
if (infoPtr->currentMonth<1) {
infoPtr->currentYear--;
infoPtr->currentMonth=12;
}
if (dwStyle & MCS_DAYSTATE) {
NMDAYSTATE nmds;
int i;
nmds.nmhdr.hwndFrom = hwnd;
nmds.nmhdr.idFrom = GetWindowLongA( hwnd, GWL_ID);
nmds.nmhdr.code = MCN_GETDAYSTATE;
nmds.cDayState = infoPtr->monthRange;
nmds.prgDayState = COMCTL32_Alloc
(infoPtr->monthRange*sizeof(MONTHDAYSTATE));
SendMessageA (GetParent (hwnd), WM_NOTIFY,
(WPARAM)nmds.nmhdr.idFrom, (LPARAM)&nmds);
for (i=0; i<infoPtr->monthRange; i++)
infoPtr->monthdayState[i]=nmds.prgDayState[i];
}
DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
TRACE ("\n");
infoPtr->currentMonth--;
if (infoPtr->currentMonth < 1) {
infoPtr->currentYear--;
infoPtr->currentMonth = 12;
}
if (dwStyle & MCS_DAYSTATE) {
NMDAYSTATE nmds;
int i;
nmds.nmhdr.hwndFrom = hwnd;
nmds.nmhdr.idFrom = GetWindowLongA( hwnd, GWL_ID);
nmds.nmhdr.code = MCN_GETDAYSTATE;
nmds.cDayState = infoPtr->monthRange;
nmds.prgDayState = COMCTL32_Alloc
(infoPtr->monthRange*sizeof(MONTHDAYSTATE));
SendMessageA (GetParent (hwnd), WM_NOTIFY,
(WPARAM)nmds.nmhdr.idFrom, (LPARAM)&nmds);
for (i=0; i<infoPtr->monthRange; i++)
infoPtr->monthdayState[i]=nmds.prgDayState[i];
}
}
static LRESULT
MONTHCAL_LButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr (hwnd);
MCHITTESTINFO ht;
HDC hdc;
DWORD hit;
HMENU hMenu;
HWND retval;
MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr (hwnd);
MCHITTESTINFO ht;
HDC hdc;
DWORD hit;
HMENU hMenu;
HWND retval;
TRACE ("%x %lx\n",wParam,lParam);
TRACE ("%x %lx\n",wParam,lParam);
ht.pt.x = (INT)LOWORD(lParam);
ht.pt.y = (INT)HIWORD(lParam);
hit=MONTHCAL_HitTest (hwnd, (LPARAM) &ht);
hdc=GetDC (hwnd);
if (hit & MCHT_NEXT){
MONTHCAL_GoToNextMonth (hwnd, infoPtr);
infoPtr->status=MC_NEXTPRESSED;
SetTimer (hwnd, MC_NEXTMONTHTIMER, MC_NEXTMONTHDELAY,0);
}
if (hit & MCHT_PREV) {
MONTHCAL_GoToPrevMonth (hwnd, infoPtr);
infoPtr->status=MC_PREVPRESSED;
SetTimer (hwnd, MC_PREVMONTHTIMER, MC_NEXTMONTHDELAY,0);
}
if (hit == MCHT_TITLEMONTH) {
ht.pt.x = (INT)LOWORD(lParam);
ht.pt.y = (INT)HIWORD(lParam);
hit = MONTHCAL_HitTest (hwnd, (LPARAM) &ht);
/* FIXME: these flags should be checked by */
/* ((hit & MCHT_XXX) == MCHT_XXX) b/c some of the flags are */
/* multi-bit */
if (hit & MCHT_NEXT){
MONTHCAL_GoToNextMonth (hwnd, infoPtr);
infoPtr->status = MC_NEXTPRESSED;
SetTimer (hwnd, MC_NEXTMONTHTIMER, MC_NEXTMONTHDELAY,0);
}
if (hit & MCHT_PREV) {
MONTHCAL_GoToPrevMonth (hwnd, infoPtr);
infoPtr->status = MC_PREVPRESSED;
SetTimer (hwnd, MC_PREVMONTHTIMER, MC_NEXTMONTHDELAY,0);
}
if (hit == MCHT_TITLEMONTH) {
/*
HRSRC hrsrc = FindResourceA( COMCTL32_hModule, MAKEINTRESOURCEA(IDD_MCMONTHMENU), RT_MENUA );
if (!hrsrc) {
TRACE ("returning zero\n");
return 0;
}
TRACE ("resource is:%x\n",hrsrc);
hMenu=LoadMenuIndirectA( (LPCVOID)LoadResource( COMCTL32_hModule, hrsrc ));
HRSRC hrsrc = FindResourceA( COMCTL32_hModule, MAKEINTRESOURCEA(IDD_MCMONTHMENU), RT_MENUA );
if (!hrsrc) {
TRACE ("returning zero\n");
return 0;
}
TRACE ("resource is:%x\n",hrsrc);
hMenu = LoadMenuIndirectA( (LPCVOID)LoadResource( COMCTL32_hModule, hrsrc ));
TRACE ("menu is:%x\n",hMenu);
TRACE ("menu is:%x\n",hMenu);
*/
hMenu=CreateMenu ();
AppendMenuA (hMenu,MF_STRING,IDM_JAN,"January");
AppendMenuA (hMenu,MF_STRING,IDM_FEB,"February");
AppendMenuA (hMenu,MF_STRING,IDM_MAR,"March");
hMenu = CreateMenu ();
AppendMenuA (hMenu,MF_STRING,IDM_JAN,"January");
AppendMenuA (hMenu,MF_STRING,IDM_FEB,"February");
AppendMenuA (hMenu,MF_STRING,IDM_MAR,"March");
retval=CreateWindowA (POPUPMENU_CLASS_ATOM, NULL,
WS_CHILD | WS_VISIBLE,
0,0,100,220,
hwnd, hMenu, GetWindowLongA (hwnd, GWL_HINSTANCE), NULL);
TRACE ("hwnd returned:%x\n",retval);
}
if (hit == MCHT_TITLEYEAR) {
FIXME ("create updown for yearselection\n");
}
if (hit == MCHT_TODAYLINK) {
FIXME ("set currentday\n");
}
if (hit == MCHT_CALENDARDATE) {
SYSTEMTIME selArray[2];
NMSELCHANGE nmsc;
TRACE ("\n");
nmsc.nmhdr.hwndFrom = hwnd;
nmsc.nmhdr.idFrom = GetWindowLongA( hwnd, GWL_ID);
nmsc.nmhdr.code = MCN_SELCHANGE;
MONTHCAL_CopyTime (&nmsc.stSelStart, &infoPtr->minSel);
MONTHCAL_CopyTime (&nmsc.stSelEnd, &infoPtr->maxSel);
retval = CreateWindowA (POPUPMENU_CLASS_ATOM, NULL,
WS_CHILD | WS_VISIBLE, 0, 0 ,100 , 220,
hwnd, hMenu, GetWindowLongA (hwnd, GWL_HINSTANCE), NULL);
TRACE ("hwnd returned:%x\n",retval);
}
if (hit == MCHT_TITLEYEAR) {
FIXME ("create updown for yearselection\n");
}
if (hit == MCHT_TODAYLINK) {
FIXME ("set currentday\n");
}
if (hit == MCHT_CALENDARDATE) {
SYSTEMTIME selArray[2];
NMSELCHANGE nmsc;
TRACE ("\n");
nmsc.nmhdr.hwndFrom = hwnd;
nmsc.nmhdr.idFrom = GetWindowLongA( hwnd, GWL_ID);
nmsc.nmhdr.code = MCN_SELCHANGE;
MONTHCAL_CopyTime (&nmsc.stSelStart, &infoPtr->minSel);
MONTHCAL_CopyTime (&nmsc.stSelEnd, &infoPtr->maxSel);
SendMessageA (GetParent (hwnd), WM_NOTIFY,
(WPARAM)nmsc.nmhdr.idFrom, (LPARAM)&nmsc);
SendMessageA (GetParent (hwnd), WM_NOTIFY,
(WPARAM)nmsc.nmhdr.idFrom, (LPARAM)&nmsc);
MONTHCAL_CopyTime (&ht.st, &selArray[0]);
MONTHCAL_CopyTime (&ht.st, &selArray[1]);
MONTHCAL_SetSelRange (hwnd,0,(LPARAM) &selArray);
MONTHCAL_CopyTime (&ht.st, &selArray[0]);
MONTHCAL_CopyTime (&ht.st, &selArray[1]);
MONTHCAL_SetSelRange (hwnd,0,(LPARAM) &selArray);
infoPtr->firstSelDay=ht.st.wDay;
infoPtr->curSelDay=ht.st.wDay;
infoPtr->status=MC_SEL_LBUTDOWN;
}
infoPtr->firstSelDay = ht.st.wDay;
infoPtr->curSelDay = ht.st.wDay;
infoPtr->status = MC_SEL_LBUTDOWN;
}
hdc = GetDC (hwnd);
MONTHCAL_Refresh (hwnd,hdc);
ReleaseDC (hwnd,hdc);
return 0;
MONTHCAL_Refresh (hwnd,hdc);
ReleaseDC (hwnd,hdc);
return 0;
}
static LRESULT
MONTHCAL_LButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr (hwnd);
NMSELCHANGE nmsc;
NMHDR nmhdr;
HDC hdc;
MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr (hwnd);
NMSELCHANGE nmsc;
NMHDR nmhdr;
HDC hdc;
TRACE ("\n");
TRACE ("\n");
if (infoPtr->status & MC_NEXTPRESSED)
KillTimer (hwnd, MC_NEXTMONTHTIMER);
if (infoPtr->status & MC_PREVPRESSED)
KillTimer (hwnd, MC_PREVMONTHTIMER);
infoPtr->status=MC_SEL_LBUTUP;
infoPtr->curSelDay=0;
if (infoPtr->status & MC_NEXTPRESSED)
KillTimer (hwnd, MC_NEXTMONTHTIMER);
if (infoPtr->status & MC_PREVPRESSED)
KillTimer (hwnd, MC_PREVMONTHTIMER);
infoPtr->status = MC_SEL_LBUTUP;
nmhdr.hwndFrom = hwnd;
nmhdr.idFrom = GetWindowLongA( hwnd, GWL_ID);
nmhdr.code = NM_RELEASEDCAPTURE;
TRACE ("Sent notification from %x to %x\n", hwnd, GetParent (hwnd));
nmhdr.hwndFrom = hwnd;
nmhdr.idFrom = GetWindowLongA( hwnd, GWL_ID);
nmhdr.code = NM_RELEASEDCAPTURE;
TRACE ("Sent notification from %x to %x\n", hwnd, GetParent (hwnd));
SendMessageA (GetParent (hwnd), WM_NOTIFY,
SendMessageA (GetParent (hwnd), WM_NOTIFY,
(WPARAM)nmhdr.idFrom, (LPARAM)&nmhdr);
nmsc.nmhdr.hwndFrom = hwnd;
nmsc.nmhdr.idFrom = GetWindowLongA( hwnd, GWL_ID);
nmsc.nmhdr.code = MCN_SELECT;
MONTHCAL_CopyTime (&nmsc.stSelStart, &infoPtr->minSel);
MONTHCAL_CopyTime (&nmsc.stSelEnd, &infoPtr->maxSel);
nmsc.nmhdr.hwndFrom = hwnd;
nmsc.nmhdr.idFrom = GetWindowLongA( hwnd, GWL_ID);
nmsc.nmhdr.code = MCN_SELECT;
MONTHCAL_CopyTime (&nmsc.stSelStart, &infoPtr->minSel);
MONTHCAL_CopyTime (&nmsc.stSelEnd, &infoPtr->maxSel);
SendMessageA (GetParent (hwnd), WM_NOTIFY,
(WPARAM)nmsc.nmhdr.idFrom, (LPARAM)&nmsc);
SendMessageA (GetParent (hwnd), WM_NOTIFY,
(WPARAM)nmsc.nmhdr.idFrom, (LPARAM)&nmsc);
hdc=GetDC (hwnd);
MONTHCAL_Refresh (hwnd,hdc);
ReleaseDC (hwnd,hdc);
hdc = GetDC (hwnd);
MONTHCAL_Refresh (hwnd,hdc);
ReleaseDC (hwnd,hdc);
return 0;
return 0;
}
static LRESULT
MONTHCAL_Timer (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr (hwnd);
HDC hdc;
TRACE(" %d\n",wParam);
if (!infoPtr) return FALSE;
hdc=GetDC (hwnd);
switch (wParam) {
case MC_NEXTMONTHTIMER:
MONTHCAL_GoToNextMonth (hwnd, infoPtr);
break;
case MC_PREVMONTHTIMER:
MONTHCAL_GoToPrevMonth (hwnd, infoPtr);
break;
default:
ERR("got unknown timer\n");
}
MONTHCAL_Refresh (hwnd,hdc);
ReleaseDC (hwnd,hdc);
return 0;
}
MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr (hwnd);
HDC hdc;
TRACE(" %d\n",wParam);
if (!infoPtr) return 0;
switch (wParam) {
case MC_NEXTMONTHTIMER:
MONTHCAL_GoToNextMonth (hwnd, infoPtr);
break;
case MC_PREVMONTHTIMER:
MONTHCAL_GoToPrevMonth (hwnd, infoPtr);
break;
default:
ERR("got unknown timer\n");
}
hdc = GetDC (hwnd);
MONTHCAL_Refresh (hwnd,hdc);
ReleaseDC (hwnd,hdc);
return 0;
}
static LRESULT
MONTHCAL_MouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr (hwnd);
MCHITTESTINFO ht;
HDC hdc;
int selday,hit;
RECT r;
MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr (hwnd);
MCHITTESTINFO ht;
HDC hdc;
int oldselday, selday, hit;
RECT r;
if (!(infoPtr->status & MC_SEL_LBUTDOWN)) return 0;
if (!(infoPtr->status & MC_SEL_LBUTDOWN)) return 0;
ht.pt.x=LOWORD(lParam);
ht.pt.y=HIWORD(lParam);
ht.pt.x = LOWORD(lParam);
ht.pt.y = HIWORD(lParam);
hit=MONTHCAL_HitTest (hwnd, (LPARAM) &ht);
/* not on the calendar date numbers? bail out */
TRACE ("hit:%x\n",hit);
if ((hit & MCHT_CALENDARDATE) !=MCHT_CALENDARDATE) return 0;
selday=ht.st.wDay;
infoPtr->curSelDay=selday;
MONTHCAL_CalcPosFromDay (infoPtr,selday,ht.st.wMonth,&r);
if ( GetWindowLongA( hwnd, GWL_STYLE) & MCS_MULTISELECT) {
SYSTEMTIME selArray[2];
int i;
MONTHCAL_GetSelRange (hwnd,0,(LPARAM) &selArray);
i=0;
if (infoPtr->firstSelDay==selArray[0].wDay) i=1;
TRACE ("oldRange:%d %d %d %d\n",infoPtr->firstSelDay,selArray[0].wDay,selArray[1].wDay,i);
if (infoPtr->firstSelDay==selArray[1].wDay) {
/* 1st time we get here: selArray[0]=selArray[1]) */
/* if we're still at the first selected date, return */
if (infoPtr->firstSelDay==selday) goto done;
if (selday<infoPtr->firstSelDay) i=0;
}
hit = MONTHCAL_HitTest (hwnd, (LPARAM) &ht);
/* not on the calendar date numbers? bail out */
TRACE ("hit:%x\n",hit);
if ((hit & MCHT_CALENDARDATE) != MCHT_CALENDARDATE) return 0;
selday = ht.st.wDay;
oldselday = infoPtr->curSelDay;
infoPtr->curSelDay = selday;
MONTHCAL_CalcPosFromDay (infoPtr,selday,ht.st.wMonth,&r);
if ( GetWindowLongA( hwnd, GWL_STYLE) & MCS_MULTISELECT) {
SYSTEMTIME selArray[2];
int i;
MONTHCAL_GetSelRange (hwnd,0,(LPARAM) &selArray);
i = 0;
if (infoPtr->firstSelDay==selArray[0].wDay) i=1;
TRACE ("oldRange:%d %d %d %d\n",infoPtr->firstSelDay,selArray[0].wDay,selArray[1].wDay,i);
if (infoPtr->firstSelDay==selArray[1].wDay) {
/* 1st time we get here: selArray[0]=selArray[1]) */
/* if we're still at the first selected date, return */
if (infoPtr->firstSelDay==selday) goto done;
if (selday<infoPtr->firstSelDay) i = 0;
}
if (abs(infoPtr->firstSelDay - selday) >= infoPtr->maxSelCount) {
if (selday>infoPtr->firstSelDay)
selday=infoPtr->firstSelDay+infoPtr->maxSelCount;
else
selday=infoPtr->firstSelDay-infoPtr->maxSelCount;
}
if (abs(infoPtr->firstSelDay - selday) >= infoPtr->maxSelCount) {
if (selday>infoPtr->firstSelDay)
selday = infoPtr->firstSelDay + infoPtr->maxSelCount;
else
selday = infoPtr->firstSelDay - infoPtr->maxSelCount;
}
if (selArray[i].wDay!=selday) {
TRACE ("newRange:%d %d %d %d\n",infoPtr->firstSelDay,selArray[0].wDay,selArray[1].wDay,i);
if (selArray[i].wDay!=selday) {
TRACE ("newRange:%d %d %d %d\n",infoPtr->firstSelDay,selArray[0].wDay,selArray[1].wDay,i);
selArray[i].wDay=selday;
selArray[i].wDay = selday;
if (selArray[0].wDay>selArray[1].wDay) {
DWORD tempday;
tempday = selArray[1].wDay;
selArray[1].wDay = selArray[0].wDay;
selArray[0].wDay = tempday;
}
if (selArray[0].wDay>selArray[1].wDay) {
DWORD tempday;
tempday=selArray[1].wDay;
selArray[1].wDay=selArray[0].wDay;
selArray[0].wDay=tempday;
}
MONTHCAL_SetSelRange (hwnd,0,(LPARAM) &selArray);
}
}
MONTHCAL_SetSelRange (hwnd, 0, (LPARAM) &selArray);
}
}
done:
hdc=GetDC (hwnd);
MONTHCAL_Refresh (hwnd, hdc);
ReleaseDC (hwnd, hdc);
/* only redraw if the currently selected day changed */
if(oldselday != infoPtr->curSelDay) {
hdc = GetDC (hwnd);
MONTHCAL_Refresh (hwnd, hdc);
ReleaseDC (hwnd, hdc);
}
return 0;
return 0;
}
static LRESULT
MONTHCAL_Paint (HWND hwnd, WPARAM wParam)
{
HDC hdc;
PAINTSTRUCT ps;
HDC hdc;
PAINTSTRUCT ps;
hdc = wParam==0 ? BeginPaint (hwnd, &ps) : (HDC)wParam;
MONTHCAL_Refresh (hwnd, hdc);
if(!wParam)
EndPaint (hwnd, &ps);
return 0;
hdc = (wParam==0 ? BeginPaint (hwnd, &ps) : (HDC)wParam);
MONTHCAL_Refresh (hwnd, hdc);
if(!wParam) EndPaint (hwnd, &ps);
return 0;
}
static LRESULT
MONTHCAL_KillFocus (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
HDC hdc;
TRACE ("\n");
TRACE ("\n");
hdc = GetDC (hwnd);
MONTHCAL_Refresh (hwnd, hdc);
ReleaseDC (hwnd, hdc);
InvalidateRect (hwnd, NULL, TRUE);
hdc = GetDC (hwnd);
MONTHCAL_Refresh (hwnd, hdc);
ReleaseDC (hwnd, hdc);
InvalidateRect (hwnd, NULL, TRUE);
return 0;
return 0;
}
static LRESULT
MONTHCAL_SetFocus (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
HDC hdc;
TRACE ("\n");
TRACE ("\n");
hdc = GetDC (hwnd);
MONTHCAL_Refresh (hwnd, hdc);
ReleaseDC (hwnd, hdc);
hdc = GetDC (hwnd);
MONTHCAL_Refresh (hwnd, hdc);
ReleaseDC (hwnd, hdc);
return 0;
return 0;
}
/* FIXME: check whether dateMin/dateMax need to be adjusted. */
static LRESULT
MONTHCAL_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
MONTHCAL_INFO *infoPtr;
LOGFONTA logFont;
/* allocate memory for info structure */
infoPtr = (MONTHCAL_INFO *)COMCTL32_Alloc (sizeof(MONTHCAL_INFO));
SetWindowLongA (hwnd, 0, (DWORD)infoPtr);
if (infoPtr == NULL) {
ERR ( "could not allocate info memory!\n");
return 0;
}
if ((MONTHCAL_INFO*) GetWindowLongA( hwnd, 0) != infoPtr) {
ERR ( "pointer assignment error!\n");
return 0;
}
MONTHCAL_INFO *infoPtr;
LOGFONTA logFont;
infoPtr->hFont=GetStockObject(DEFAULT_GUI_FONT);
GetObjectA (infoPtr->hFont, sizeof (LOGFONTA), &logFont);
logFont.lfWeight=FW_BOLD;
infoPtr->hBoldFont = CreateFontIndirectA (&logFont);
/* allocate memory for info structure */
infoPtr = (MONTHCAL_INFO *)COMCTL32_Alloc (sizeof(MONTHCAL_INFO));
SetWindowLongA (hwnd, 0, (DWORD)infoPtr);
/* initialize info structure */
/* FIXME: calculate systemtime ->> localtime (substract timezoneinfo) */
if (infoPtr == NULL) {
ERR ( "could not allocate info memory!\n");
return 0;
}
if ((MONTHCAL_INFO*) GetWindowLongA( hwnd, 0) != infoPtr) {
ERR ( "pointer assignment error!\n");
return 0;
}
GetSystemTime (&infoPtr->todaysDate);
infoPtr->firstDay = 0;
infoPtr->currentMonth = infoPtr->todaysDate.wMonth;
infoPtr->currentYear= infoPtr->todaysDate.wYear;
MONTHCAL_CopyTime (&infoPtr->todaysDate,&infoPtr->minDate);
MONTHCAL_CopyTime (&infoPtr->todaysDate,&infoPtr->maxDate);
infoPtr->maxSelCount=6;
infoPtr->monthRange=3;
infoPtr->monthdayState=COMCTL32_Alloc
infoPtr->hFont=GetStockObject(DEFAULT_GUI_FONT);
GetObjectA (infoPtr->hFont, sizeof (LOGFONTA), &logFont);
logFont.lfWeight = FW_BOLD;
infoPtr->hBoldFont = CreateFontIndirectA (&logFont);
/* initialize info structure */
/* FIXME: calculate systemtime ->> localtime (substract timezoneinfo) */
GetSystemTime(&infoPtr->todaysDate);
infoPtr->firstDay = 0;
infoPtr->currentMonth = infoPtr->todaysDate.wMonth;
infoPtr->currentYear = infoPtr->todaysDate.wYear;
MONTHCAL_CopyTime(&infoPtr->todaysDate,&infoPtr->minDate);
MONTHCAL_CopyTime(&infoPtr->todaysDate,&infoPtr->maxDate);
infoPtr->maxSelCount = 6;
infoPtr->monthRange = 3;
infoPtr->monthdayState=COMCTL32_Alloc
(infoPtr->monthRange*sizeof(MONTHDAYSTATE));
infoPtr->titlebk = GetSysColor (COLOR_GRAYTEXT);
infoPtr->titletxt = GetSysColor (COLOR_WINDOW);
infoPtr->monthbk = GetSysColor (COLOR_WINDOW);
infoPtr->trailingtxt = GetSysColor (COLOR_GRAYTEXT);
infoPtr->bk = GetSysColor (COLOR_WINDOW);
infoPtr->txt = GetSysColor (COLOR_WINDOWTEXT);
return 0;
infoPtr->titlebk = GetSysColor (COLOR_ACTIVECAPTION);
infoPtr->titletxt = GetSysColor (COLOR_WINDOW);
infoPtr->monthbk = GetSysColor (COLOR_WINDOW);
infoPtr->trailingtxt = GetSysColor (COLOR_GRAYTEXT);
infoPtr->bk = GetSysColor (COLOR_WINDOW);
infoPtr->txt = GetSysColor (COLOR_WINDOWTEXT);
return 0;
}
static LRESULT
MONTHCAL_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr (hwnd);
MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr (hwnd);
/* free month calendar info data */
COMCTL32_Free (infoPtr);
/* free month calendar info data */
COMCTL32_Free (infoPtr);
return 0;
return 0;
}
static LRESULT WINAPI
MONTHCAL_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case MCM_GETCURSEL:
return MONTHCAL_GetCurSel (hwnd, wParam, lParam);
switch (uMsg)
{
case MCM_GETCURSEL:
return MONTHCAL_GetCurSel (hwnd, wParam, lParam);
case MCM_SETCURSEL:
return MONTHCAL_SetCurSel (hwnd, wParam, lParam);
case MCM_SETCURSEL:
return MONTHCAL_SetCurSel (hwnd, wParam, lParam);
case MCM_GETMAXSELCOUNT:
return MONTHCAL_GetMaxSelCount (hwnd, wParam, lParam);
case MCM_GETMAXSELCOUNT:
return MONTHCAL_GetMaxSelCount (hwnd, wParam, lParam);
case MCM_SETMAXSELCOUNT:
return MONTHCAL_SetMaxSelCount (hwnd, wParam, lParam);
case MCM_SETMAXSELCOUNT:
return MONTHCAL_SetMaxSelCount (hwnd, wParam, lParam);
case MCM_GETSELRANGE:
return MONTHCAL_GetSelRange (hwnd, wParam, lParam);
case MCM_GETSELRANGE:
return MONTHCAL_GetSelRange (hwnd, wParam, lParam);
case MCM_SETSELRANGE:
return MONTHCAL_SetSelRange (hwnd, wParam, lParam);
case MCM_SETSELRANGE:
return MONTHCAL_SetSelRange (hwnd, wParam, lParam);
case MCM_GETMONTHRANGE:
return MONTHCAL_GetMonthRange (hwnd, wParam, lParam);
case MCM_GETMONTHRANGE:
return MONTHCAL_GetMonthRange (hwnd, wParam, lParam);
case MCM_SETDAYSTATE:
return MONTHCAL_SetDayState (hwnd, wParam, lParam);
case MCM_SETDAYSTATE:
return MONTHCAL_SetDayState (hwnd, wParam, lParam);
case MCM_GETMINREQRECT:
return MONTHCAL_GetMinReqRect (hwnd, wParam, lParam);
case MCM_GETMINREQRECT:
return MONTHCAL_GetMinReqRect (hwnd, wParam, lParam);
case MCM_GETCOLOR:
return MONTHCAL_GetColor (hwnd, wParam, lParam);
case MCM_GETCOLOR:
return MONTHCAL_GetColor (hwnd, wParam, lParam);
case MCM_SETCOLOR:
return MONTHCAL_SetColor (hwnd, wParam, lParam);
case MCM_SETCOLOR:
return MONTHCAL_SetColor (hwnd, wParam, lParam);
case MCM_GETTODAY:
return MONTHCAL_GetToday (hwnd, wParam, lParam);
case MCM_GETTODAY:
return MONTHCAL_GetToday (hwnd, wParam, lParam);
case MCM_SETTODAY:
return MONTHCAL_SetToday (hwnd, wParam, lParam);
case MCM_SETTODAY:
return MONTHCAL_SetToday (hwnd, wParam, lParam);
case MCM_HITTEST:
return MONTHCAL_HitTest (hwnd,lParam);
case MCM_HITTEST:
return MONTHCAL_HitTest (hwnd,lParam);
case MCM_GETFIRSTDAYOFWEEK:
return MONTHCAL_GetFirstDayOfWeek (hwnd, wParam, lParam);
case MCM_GETFIRSTDAYOFWEEK:
return MONTHCAL_GetFirstDayOfWeek (hwnd, wParam, lParam);
case MCM_SETFIRSTDAYOFWEEK:
return MONTHCAL_SetFirstDayOfWeek (hwnd, wParam, lParam);
case MCM_SETFIRSTDAYOFWEEK:
return MONTHCAL_SetFirstDayOfWeek (hwnd, wParam, lParam);
case MCM_GETRANGE:
return MONTHCAL_GetRange (hwnd, wParam, lParam);
case MCM_GETRANGE:
return MONTHCAL_GetRange (hwnd, wParam, lParam);
case MCM_SETRANGE:
return MONTHCAL_SetRange (hwnd, wParam, lParam);
case MCM_SETRANGE:
return MONTHCAL_SetRange (hwnd, wParam, lParam);
case MCM_GETMONTHDELTA:
return MONTHCAL_GetMonthDelta (hwnd, wParam, lParam);
case MCM_GETMONTHDELTA:
return MONTHCAL_GetMonthDelta (hwnd, wParam, lParam);
case MCM_SETMONTHDELTA:
return MONTHCAL_SetMonthDelta (hwnd, wParam, lParam);
case MCM_SETMONTHDELTA:
return MONTHCAL_SetMonthDelta (hwnd, wParam, lParam);
case MCM_GETMAXTODAYWIDTH:
return MONTHCAL_GetMaxTodayWidth (hwnd);
case MCM_GETMAXTODAYWIDTH:
return MONTHCAL_GetMaxTodayWidth (hwnd);
case WM_GETDLGCODE:
return DLGC_WANTARROWS | DLGC_WANTCHARS;
case WM_GETDLGCODE:
return DLGC_WANTARROWS | DLGC_WANTCHARS;
case WM_KILLFOCUS:
return MONTHCAL_KillFocus (hwnd, wParam, lParam);
case WM_KILLFOCUS:
return MONTHCAL_KillFocus (hwnd, wParam, lParam);
case WM_LBUTTONDOWN:
return MONTHCAL_LButtonDown (hwnd, wParam, lParam);
case WM_LBUTTONDOWN:
return MONTHCAL_LButtonDown (hwnd, wParam, lParam);
case WM_MOUSEMOVE:
return MONTHCAL_MouseMove (hwnd, wParam, lParam);
case WM_MOUSEMOVE:
return MONTHCAL_MouseMove (hwnd, wParam, lParam);
case WM_LBUTTONUP:
return MONTHCAL_LButtonUp (hwnd, wParam, lParam);
case WM_LBUTTONUP:
return MONTHCAL_LButtonUp (hwnd, wParam, lParam);
case WM_PAINT:
return MONTHCAL_Paint (hwnd, wParam);
case WM_PAINT:
return MONTHCAL_Paint (hwnd, wParam);
case WM_SETFOCUS:
return MONTHCAL_SetFocus (hwnd, wParam, lParam);
case WM_SETFOCUS:
return MONTHCAL_SetFocus (hwnd, wParam, lParam);
case WM_CREATE:
return MONTHCAL_Create (hwnd, wParam, lParam);
case WM_CREATE:
return MONTHCAL_Create (hwnd, wParam, lParam);
case WM_TIMER:
return MONTHCAL_Timer (hwnd, wParam, lParam);
case WM_TIMER:
return MONTHCAL_Timer (hwnd, wParam, lParam);
case WM_DESTROY:
return MONTHCAL_Destroy (hwnd, wParam, lParam);
case WM_DESTROY:
return MONTHCAL_Destroy (hwnd, wParam, lParam);
default:
if (uMsg >= WM_USER)
ERR ( "unknown msg %04x wp=%08x lp=%08lx\n",
uMsg, wParam, lParam);
return DefWindowProcA (hwnd, uMsg, wParam, lParam);
}
return 0;
default:
if (uMsg >= WM_USER)
ERR ( "unknown msg %04x wp=%08x lp=%08lx\n", uMsg, wParam, lParam);
return DefWindowProcA (hwnd, uMsg, wParam, lParam);
}
return 0;
}
void
MONTHCAL_Register (void)
{
WNDCLASSA wndClass;
if (GlobalFindAtomA (MONTHCAL_CLASSA)) return;
ZeroMemory (&wndClass, sizeof(WNDCLASSA));
wndClass.style = CS_GLOBALCLASS;
wndClass.lpfnWndProc = (WNDPROC)MONTHCAL_WindowProc;
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = sizeof(MONTHCAL_INFO *);
wndClass.hCursor = LoadCursorA (0, IDC_ARROWA);
wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wndClass.lpszClassName = MONTHCAL_CLASSA;
WNDCLASSA wndClass;
if (GlobalFindAtomA (MONTHCAL_CLASSA)) return;
ZeroMemory (&wndClass, sizeof(WNDCLASSA));
wndClass.style = CS_GLOBALCLASS;
wndClass.lpfnWndProc = (WNDPROC)MONTHCAL_WindowProc;
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = sizeof(MONTHCAL_INFO *);
wndClass.hCursor = LoadCursorA (0, IDC_ARROWA);
wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wndClass.lpszClassName = MONTHCAL_CLASSA;
RegisterClassA (&wndClass);
RegisterClassA (&wndClass);
}
void
MONTHCAL_Unregister (void)
{
if (GlobalFindAtomA (MONTHCAL_CLASSA))
UnregisterClassA (MONTHCAL_CLASSA, (HINSTANCE)NULL);
if (GlobalFindAtomA (MONTHCAL_CLASSA))
UnregisterClassA (MONTHCAL_CLASSA, (HINSTANCE)NULL);
}
......@@ -12,11 +12,12 @@
#include "windef.h"
#include "wingdi.h"
#define MC_SEL_LBUTUP 0 /* Left button released */
#define MC_SEL_LBUTDOWN 1 /* Left button pressed in calendar */
#define MC_PREVPRESSED 1 /* Prev month button pressed */
#define MC_NEXTPRESSED 2 /* Next month button pressed */
#define MC_NEXTMONTHDELAY 500 /* when continuously pressing `next */
#define MC_SEL_LBUTUP 1 /* Left button released */
#define MC_SEL_LBUTDOWN 2 /* Left button pressed in calendar */
#define MC_PREVPRESSED 4 /* Prev month button pressed */
#define MC_NEXTPRESSED 8 /* Next month button pressed */
#define MC_NEXTMONTHDELAY 350 /* when continuously pressing `next */
/* month', wait 500 ms before going */
/* to the next month */
#define MC_NEXTMONTHTIMER 1 /* Timer ID's */
......@@ -24,47 +25,51 @@
typedef struct tagMONTHCAL_INFO
{
COLORREF bk;
COLORREF txt;
COLORREF titlebk;
COLORREF titletxt;
COLORREF monthbk;
COLORREF trailingtxt;
HFONT hFont;
HFONT hBoldFont;
int textHeight;
int textWidth;
int firstDayplace; /* place of the first day of the current month */
int delta; /* scroll rate; # of months that the */
/* control moves when user clicks a scroll button */
int visible; /* # of months visible */
int firstDay; /* Start month calendar with firstDay's day */
int monthRange;
MONTHDAYSTATE *monthdayState;
SYSTEMTIME todaysDate;
DWORD currentMonth;
DWORD currentYear;
int status; /* See MC_SEL flags */
int curSelDay; /* current selected day */
int firstSelDay; /* first selected day */
int maxSelCount;
SYSTEMTIME minSel;
SYSTEMTIME maxSel;
DWORD rangeValid;
SYSTEMTIME minDate;
SYSTEMTIME maxDate;
COLORREF bk;
COLORREF txt;
COLORREF titlebk;
COLORREF titletxt;
COLORREF monthbk;
COLORREF trailingtxt;
HFONT hFont;
HFONT hBoldFont;
int textHeight;
int textWidth;
int height_increment;
int width_increment;
int left_offset;
int top_offset;
int firstDayplace; /* place of the first day of the current month */
int delta; /* scroll rate; # of months that the */
/* control moves when user clicks a scroll button */
int visible; /* # of months visible */
int firstDay; /* Start month calendar with firstDay's day */
int monthRange;
MONTHDAYSTATE *monthdayState;
SYSTEMTIME todaysDate;
DWORD currentMonth;
DWORD currentYear;
int status; /* See MC_SEL flags */
int curSelDay; /* current selected day */
int firstSelDay; /* first selected day */
int maxSelCount;
SYSTEMTIME minSel;
SYSTEMTIME maxSel;
DWORD rangeValid;
SYSTEMTIME minDate;
SYSTEMTIME maxDate;
RECT rcClient; /* rect for whole client area */
RECT title; /* rect for the header above the calendar */
RECT titlebtnnext; /* the `next month' button in the header */
RECT titlebtnprev; /* the `prev month' button in the header */
RECT titlemonth; /* the `month name' txt in the header */
RECT titleyear; /* the `year number' txt in the header */
RECT prevmonth; /* day numbers of the previous month */
RECT nextmonth; /* day numbers of the next month */
RECT days; /* week numbers at left side */
RECT weeknums; /* week numbers at left side */
RECT today; /* `today: xx/xx/xx' text rect */
RECT rcClient; /* rect for whole client area */
RECT title; /* rect for the header above the calendar */
RECT titlebtnnext; /* the `next month' button in the header */
RECT titlebtnprev; /* the `prev month' button in the header */
RECT titlemonth; /* the `month name' txt in the header */
RECT titleyear; /* the `year number' txt in the header */
RECT prevmonth; /* day numbers of the previous month */
RECT nextmonth; /* day numbers of the next month */
RECT days; /* week numbers at left side */
RECT weeknums; /* week numbers at left side */
RECT today; /* `today: xx/xx/xx' text rect */
} MONTHCAL_INFO, *LPMONTHCAL_INFO;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment