comctl32/monthcal: Fix column/row calculation for previous and next month.
This commit is contained in:
parent
22dddce999
commit
7d2ef4f23d
|
@ -217,6 +217,35 @@ static BOOL MONTHCAL_ValidateDate(const SYSTEMTIME *time)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Copies timestamp part only.
|
||||||
|
*
|
||||||
|
* PARAMETERS
|
||||||
|
*
|
||||||
|
* [I] from : source date
|
||||||
|
* [O] to : dest date
|
||||||
|
*/
|
||||||
|
static void MONTHCAL_CopyTime(const SYSTEMTIME *from, SYSTEMTIME *to)
|
||||||
|
{
|
||||||
|
to->wHour = from->wHour;
|
||||||
|
to->wMinute = from->wMinute;
|
||||||
|
to->wSecond = from->wSecond;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copies date part only.
|
||||||
|
*
|
||||||
|
* PARAMETERS
|
||||||
|
*
|
||||||
|
* [I] from : source date
|
||||||
|
* [O] to : dest date
|
||||||
|
*/
|
||||||
|
static void MONTHCAL_CopyDate(const SYSTEMTIME *from, SYSTEMTIME *to)
|
||||||
|
{
|
||||||
|
to->wYear = from->wYear;
|
||||||
|
to->wMonth = from->wMonth;
|
||||||
|
to->wDay = from->wDay;
|
||||||
|
to->wDayOfWeek = from->wDayOfWeek;
|
||||||
|
}
|
||||||
|
|
||||||
/* Compares two dates in SYSTEMTIME format
|
/* Compares two dates in SYSTEMTIME format
|
||||||
*
|
*
|
||||||
* PARAMETERS
|
* PARAMETERS
|
||||||
|
@ -242,6 +271,18 @@ static LONG MONTHCAL_CompareSystemTime(const SYSTEMTIME *first, const SYSTEMTIME
|
||||||
return CompareFileTime(&ft_first, &ft_second);
|
return CompareFileTime(&ft_first, &ft_second);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static LONG MONTHCAL_CompareMonths(const SYSTEMTIME *first, const SYSTEMTIME *second)
|
||||||
|
{
|
||||||
|
SYSTEMTIME st_first, st_second;
|
||||||
|
|
||||||
|
st_first = st_second = st_null;
|
||||||
|
MONTHCAL_CopyDate(first, &st_first);
|
||||||
|
MONTHCAL_CopyDate(second, &st_second);
|
||||||
|
st_first.wDay = st_second.wDay = 1;
|
||||||
|
|
||||||
|
return MONTHCAL_CompareSystemTime(&st_first, &st_second);
|
||||||
|
}
|
||||||
|
|
||||||
/* Checks largest possible date range and configured one
|
/* Checks largest possible date range and configured one
|
||||||
*
|
*
|
||||||
* PARAMETERS
|
* PARAMETERS
|
||||||
|
@ -355,35 +396,6 @@ static BOOL MONTHCAL_ValidateTime(const SYSTEMTIME *time)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copies timestamp part only.
|
|
||||||
*
|
|
||||||
* PARAMETERS
|
|
||||||
*
|
|
||||||
* [I] from : source date
|
|
||||||
* [O] to : dest date
|
|
||||||
*/
|
|
||||||
static void MONTHCAL_CopyTime(const SYSTEMTIME *from, SYSTEMTIME *to)
|
|
||||||
{
|
|
||||||
to->wHour = from->wHour;
|
|
||||||
to->wMinute = from->wMinute;
|
|
||||||
to->wSecond = from->wSecond;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Copies date part only.
|
|
||||||
*
|
|
||||||
* PARAMETERS
|
|
||||||
*
|
|
||||||
* [I] from : source date
|
|
||||||
* [O] to : dest date
|
|
||||||
*/
|
|
||||||
static void MONTHCAL_CopyDate(const SYSTEMTIME *from, SYSTEMTIME *to)
|
|
||||||
{
|
|
||||||
to->wYear = from->wYear;
|
|
||||||
to->wMonth = from->wMonth;
|
|
||||||
to->wDay = from->wDay;
|
|
||||||
to->wDayOfWeek = from->wDayOfWeek;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Note:Depending on DST, this may be offset by a day.
|
/* 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.
|
Need to find out if we're on a DST place & adjust the clock accordingly.
|
||||||
Above function assumes we have a valid data.
|
Above function assumes we have a valid data.
|
||||||
|
@ -505,39 +517,45 @@ static int MONTHCAL_CalcDayFromPos(const MONTHCAL_INFO *infoPtr, int x, int y,
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* day is the day of the month, 1 == 1st day of the month */
|
/* Sets the RECT struct r to the rectangle around the date
|
||||||
/* sets x and y to be the position of the day */
|
*
|
||||||
/* x == day, y == week where(0,0) == firstDay, 1st week */
|
* PARAMETERS
|
||||||
static void MONTHCAL_CalcDayXY(const MONTHCAL_INFO *infoPtr, int day, int month,
|
*
|
||||||
int *x, int *y)
|
* [I] infoPtr : pointer to control data
|
||||||
|
* [I] date : date value
|
||||||
|
* [O] x : day column (zero based)
|
||||||
|
* [O] y : week column (zero based)
|
||||||
|
*/
|
||||||
|
static void MONTHCAL_CalcDayXY(const MONTHCAL_INFO *infoPtr,
|
||||||
|
const SYSTEMTIME *date, int *x, int *y)
|
||||||
{
|
{
|
||||||
int firstDay, prevMonth;
|
LONG cmp;
|
||||||
|
int first;
|
||||||
|
|
||||||
firstDay = (MONTHCAL_CalculateDayOfWeek(1, infoPtr->curSel.wMonth, infoPtr->curSel.wYear) +6 - infoPtr->firstDay)%7;
|
first = (MONTHCAL_CalculateDayOfWeek(1, infoPtr->curSel.wMonth, infoPtr->curSel.wYear) +6 - infoPtr->firstDay)%7;
|
||||||
|
|
||||||
if(month==infoPtr->curSel.wMonth) {
|
cmp = MONTHCAL_CompareMonths(date, &infoPtr->curSel);
|
||||||
*x = (day + firstDay) % 7;
|
|
||||||
*y = (day + firstDay - *x) / 7;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(month < infoPtr->curSel.wMonth) {
|
|
||||||
prevMonth = month - 1;
|
|
||||||
if(prevMonth==0)
|
|
||||||
prevMonth = 12;
|
|
||||||
|
|
||||||
*x = (MONTHCAL_MonthLength(prevMonth, infoPtr->curSel.wYear) - firstDay) % 7;
|
/* previous month */
|
||||||
|
if(cmp == -1) {
|
||||||
|
*x = (first - MONTHCAL_MonthLength(date->wMonth, infoPtr->curSel.wYear) + date->wDay) % 7;
|
||||||
*y = 0;
|
*y = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
*y = MONTHCAL_MonthLength(month, infoPtr->curSel.wYear - 1) / 7;
|
/* next month calculation is same as for current,
|
||||||
*x = (day + firstDay + MONTHCAL_MonthLength(month,
|
just add current month length */
|
||||||
infoPtr->curSel.wYear)) % 7;
|
if(cmp == 1) {
|
||||||
|
first += MONTHCAL_MonthLength(infoPtr->curSel.wMonth, infoPtr->curSel.wYear);
|
||||||
|
}
|
||||||
|
|
||||||
|
*x = (date->wDay + first) % 7;
|
||||||
|
*y = (date->wDay + first - *x) / 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* x: column(day), y: row(week) */
|
/* x: column(day), y: row(week) */
|
||||||
static void MONTHCAL_CalcDayRect(const MONTHCAL_INFO *infoPtr, RECT *r, int x, int y)
|
static inline void MONTHCAL_CalcDayRect(const MONTHCAL_INFO *infoPtr, RECT *r, int x, int y)
|
||||||
{
|
{
|
||||||
r->left = infoPtr->days.left + x * infoPtr->width_increment;
|
r->left = infoPtr->days.left + x * infoPtr->width_increment;
|
||||||
r->right = r->left + infoPtr->width_increment;
|
r->right = r->left + infoPtr->width_increment;
|
||||||
|
@ -546,15 +564,13 @@ static void MONTHCAL_CalcDayRect(const MONTHCAL_INFO *infoPtr, RECT *r, int x, i
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* sets the RECT struct r to the rectangle around the day and month */
|
/* Sets the RECT struct r to the rectangle around the date */
|
||||||
/* day is the day value of the month(1 == 1st), month is the month */
|
|
||||||
/* value(january == 1, december == 12) */
|
|
||||||
static inline void MONTHCAL_CalcPosFromDay(const MONTHCAL_INFO *infoPtr,
|
static inline void MONTHCAL_CalcPosFromDay(const MONTHCAL_INFO *infoPtr,
|
||||||
int day, int month, RECT *r)
|
const SYSTEMTIME *date, RECT *r)
|
||||||
{
|
{
|
||||||
int x, y;
|
int x, y;
|
||||||
|
|
||||||
MONTHCAL_CalcDayXY(infoPtr, day, month, &x, &y);
|
MONTHCAL_CalcDayXY(infoPtr, date, &x, &y);
|
||||||
MONTHCAL_CalcDayRect(infoPtr, r, x, y);
|
MONTHCAL_CalcDayRect(infoPtr, r, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -577,15 +593,13 @@ static BOOL MONTHCAL_SetDayFocus(MONTHCAL_INFO *infoPtr, const SYSTEMTIME *st)
|
||||||
if(MONTHCAL_IsDateEqual(&infoPtr->focusedSel, st)) return FALSE;
|
if(MONTHCAL_IsDateEqual(&infoPtr->focusedSel, st)) return FALSE;
|
||||||
|
|
||||||
/* invalidate old focused day */
|
/* invalidate old focused day */
|
||||||
MONTHCAL_CalcPosFromDay(infoPtr, infoPtr->focusedSel.wDay,
|
MONTHCAL_CalcPosFromDay(infoPtr, &infoPtr->focusedSel, &r);
|
||||||
infoPtr->focusedSel.wMonth, &r);
|
|
||||||
InvalidateRect(infoPtr->hwndSelf, &r, FALSE);
|
InvalidateRect(infoPtr->hwndSelf, &r, FALSE);
|
||||||
|
|
||||||
infoPtr->focusedSel = *st;
|
infoPtr->focusedSel = *st;
|
||||||
}
|
}
|
||||||
|
|
||||||
MONTHCAL_CalcPosFromDay(infoPtr, infoPtr->focusedSel.wDay,
|
MONTHCAL_CalcPosFromDay(infoPtr, &infoPtr->focusedSel, &r);
|
||||||
infoPtr->focusedSel.wMonth, &r);
|
|
||||||
|
|
||||||
if(!st && MONTHCAL_ValidateDate(&infoPtr->focusedSel))
|
if(!st && MONTHCAL_ValidateDate(&infoPtr->focusedSel))
|
||||||
infoPtr->focusedSel = st_null;
|
infoPtr->focusedSel = st_null;
|
||||||
|
@ -596,16 +610,21 @@ static BOOL MONTHCAL_SetDayFocus(MONTHCAL_INFO *infoPtr, const SYSTEMTIME *st)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* day is the day in the month(1 == 1st of the month) */
|
/* Draw today day mark rectangle
|
||||||
/* month is the month value(1 == january, 12 == december) */
|
*
|
||||||
static void MONTHCAL_CircleDay(const MONTHCAL_INFO *infoPtr, HDC hdc, int day, int month)
|
* [I] hdc : context to draw in
|
||||||
|
* [I] day : day to mark with rectangle
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static void MONTHCAL_CircleDay(const MONTHCAL_INFO *infoPtr, HDC hdc,
|
||||||
|
const SYSTEMTIME *date)
|
||||||
{
|
{
|
||||||
HPEN hRedPen = CreatePen(PS_SOLID, 1, RGB(255, 0, 0));
|
HPEN hRedPen = CreatePen(PS_SOLID, 1, RGB(255, 0, 0));
|
||||||
HPEN hOldPen2 = SelectObject(hdc, hRedPen);
|
HPEN hOldPen2 = SelectObject(hdc, hRedPen);
|
||||||
HBRUSH hOldBrush;
|
HBRUSH hOldBrush;
|
||||||
RECT day_rect;
|
RECT day_rect;
|
||||||
|
|
||||||
MONTHCAL_CalcPosFromDay(infoPtr, day, month, &day_rect);
|
MONTHCAL_CalcPosFromDay(infoPtr, date, &day_rect);
|
||||||
|
|
||||||
hOldBrush = SelectObject(hdc, GetStockObject(NULL_BRUSH));
|
hOldBrush = SelectObject(hdc, GetStockObject(NULL_BRUSH));
|
||||||
Rectangle(hdc, day_rect.left, day_rect.top, day_rect.right, day_rect.bottom);
|
Rectangle(hdc, day_rect.left, day_rect.top, day_rect.right, day_rect.bottom);
|
||||||
|
@ -918,14 +937,13 @@ static void MONTHCAL_Refresh(MONTHCAL_INFO *infoPtr, HDC hdc, const PAINTSTRUCT
|
||||||
(infoPtr->curSel.wYear == infoPtr->todaysDate.wYear) &&
|
(infoPtr->curSel.wYear == infoPtr->todaysDate.wYear) &&
|
||||||
!(infoPtr->dwStyle & MCS_NOTODAYCIRCLE))
|
!(infoPtr->dwStyle & MCS_NOTODAYCIRCLE))
|
||||||
{
|
{
|
||||||
MONTHCAL_CircleDay(infoPtr, hdc, infoPtr->todaysDate.wDay, infoPtr->todaysDate.wMonth);
|
MONTHCAL_CircleDay(infoPtr, hdc, &infoPtr->todaysDate);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* draw focused day */
|
/* draw focused day */
|
||||||
if(!MONTHCAL_IsDateEqual(&infoPtr->focusedSel, &st_null))
|
if(!MONTHCAL_IsDateEqual(&infoPtr->focusedSel, &st_null))
|
||||||
{
|
{
|
||||||
MONTHCAL_CalcPosFromDay(infoPtr, infoPtr->focusedSel.wDay,
|
MONTHCAL_CalcPosFromDay(infoPtr, &infoPtr->focusedSel, &rcDay);
|
||||||
infoPtr->focusedSel.wMonth, &rcDay);
|
|
||||||
|
|
||||||
DrawFocusRect(hdc, &rcDay);
|
DrawFocusRect(hdc, &rcDay);
|
||||||
}
|
}
|
||||||
|
@ -937,11 +955,12 @@ static void MONTHCAL_Refresh(MONTHCAL_INFO *infoPtr, HDC hdc, const PAINTSTRUCT
|
||||||
static const WCHAR fmt_todayW[] = { '%','s',' ','%','s',0 };
|
static const WCHAR fmt_todayW[] = { '%','s',' ','%','s',0 };
|
||||||
RECT rtoday;
|
RECT rtoday;
|
||||||
|
|
||||||
if(!(infoPtr->dwStyle & MCS_NOTODAYCIRCLE)) {
|
if(!(infoPtr->dwStyle & MCS_NOTODAYCIRCLE)) {
|
||||||
|
SYSTEMTIME fake_st = infoPtr->curSel;
|
||||||
|
|
||||||
/*day is the number of days from nextmonth we put on the calendar */
|
/*day is the number of days from nextmonth we put on the calendar */
|
||||||
MONTHCAL_CircleDay(infoPtr, hdc,
|
fake_st.wDay = day + MONTHCAL_MonthLength(infoPtr->curSel.wMonth, infoPtr->curSel.wYear);
|
||||||
day+MONTHCAL_MonthLength(infoPtr->curSel.wMonth, infoPtr->curSel.wYear),
|
MONTHCAL_CircleDay(infoPtr, hdc, &fake_st);
|
||||||
infoPtr->curSel.wMonth);
|
|
||||||
}
|
}
|
||||||
if (!LoadStringW(COMCTL32_hModule, IDM_TODAY, buf1, countof(buf1)))
|
if (!LoadStringW(COMCTL32_hModule, IDM_TODAY, buf1, countof(buf1)))
|
||||||
{
|
{
|
||||||
|
@ -1531,9 +1550,8 @@ MONTHCAL_UpdateToday(MONTHCAL_INFO *infoPtr, const SYSTEMTIME *today)
|
||||||
|
|
||||||
if(MONTHCAL_IsDateEqual(today, &infoPtr->todaysDate)) return FALSE;
|
if(MONTHCAL_IsDateEqual(today, &infoPtr->todaysDate)) return FALSE;
|
||||||
|
|
||||||
MONTHCAL_CalcPosFromDay(infoPtr, infoPtr->todaysDate.wDay,
|
MONTHCAL_CalcPosFromDay(infoPtr, &infoPtr->todaysDate, &old_r);
|
||||||
infoPtr->todaysDate.wMonth, &old_r);
|
MONTHCAL_CalcPosFromDay(infoPtr, today, &new_r);
|
||||||
MONTHCAL_CalcPosFromDay(infoPtr, today->wDay, today->wMonth, &new_r);
|
|
||||||
|
|
||||||
infoPtr->todaysDate = *today;
|
infoPtr->todaysDate = *today;
|
||||||
|
|
||||||
|
@ -2069,7 +2087,7 @@ MONTHCAL_MouseMove(MONTHCAL_INFO *infoPtr, LPARAM lParam)
|
||||||
/* if pointer is over focused day still there's nothing to do */
|
/* if pointer is over focused day still there's nothing to do */
|
||||||
if(!MONTHCAL_SetDayFocus(infoPtr, &ht.st)) return 0;
|
if(!MONTHCAL_SetDayFocus(infoPtr, &ht.st)) return 0;
|
||||||
|
|
||||||
MONTHCAL_CalcPosFromDay(infoPtr, ht.st.wDay, ht.st.wMonth, &r);
|
MONTHCAL_CalcPosFromDay(infoPtr, &ht.st, &r);
|
||||||
|
|
||||||
if(infoPtr->dwStyle & MCS_MULTISELECT) {
|
if(infoPtr->dwStyle & MCS_MULTISELECT) {
|
||||||
SYSTEMTIME st[2];
|
SYSTEMTIME st[2];
|
||||||
|
|
Loading…
Reference in New Issue