[PATCH 1/3] Simplify painting operations, split painting to several helpers
Nikolay Sivov
bunglehead at gmail.com
Mon Oct 12 19:05:31 CDT 2009
---
dlls/comctl32/monthcal.c | 519 +++++++++++++++++++++-------------------------
include/commctrl.h | 1 +
2 files changed, 241 insertions(+), 279 deletions(-)
diff --git a/dlls/comctl32/monthcal.c b/dlls/comctl32/monthcal.c
index b46bac6..dc61d01 100644
--- a/dlls/comctl32/monthcal.c
+++ b/dlls/comctl32/monthcal.c
@@ -93,7 +93,6 @@ typedef struct
int textWidth;
int height_increment;
int width_increment;
- 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 */
@@ -646,23 +645,22 @@ static void MONTHCAL_CircleDay(const MONTHCAL_INFO *infoPtr, HDC hdc,
}
static void MONTHCAL_DrawDay(const MONTHCAL_INFO *infoPtr, HDC hdc, const SYSTEMTIME *st,
- int x, int y, int bold)
+ int bold, const PAINTSTRUCT *ps)
{
static const WCHAR fmtW[] = { '%','d',0 };
WCHAR buf[10];
- RECT r;
+ RECT r, r_temp;
static BOOL haveBoldFont, haveSelectedDay = FALSE;
HBRUSH hbr;
COLORREF oldCol = 0;
COLORREF oldBk = 0;
- wsprintfW(buf, fmtW, st->wDay);
-
/* No need to check styles: when selection is not valid, it is set to zero.
* 1<day<31, so everything is OK.
*/
- MONTHCAL_CalcDayRect(infoPtr, &r, x, y);
+ MONTHCAL_CalcPosFromDay(infoPtr, st, &r);
+ if(!IntersectRect(&r_temp, &(ps->rcPaint), &r)) return;
if ((MONTHCAL_CompareDate(st, &infoPtr->minSel) >= 0) &&
(MONTHCAL_CompareDate(st, &infoPtr->maxSel) <= 0)) {
@@ -699,6 +697,7 @@ static void MONTHCAL_DrawDay(const MONTHCAL_INFO *infoPtr, HDC hdc, const SYSTEM
}
SetBkMode(hdc,TRANSPARENT);
+ wsprintfW(buf, fmtW, st->wDay);
DrawTextW(hdc, buf, -1, &r, DT_CENTER | DT_VCENTER | DT_SINGLELINE );
if(haveSelectedDay) {
@@ -708,7 +707,7 @@ static void MONTHCAL_DrawDay(const MONTHCAL_INFO *infoPtr, HDC hdc, const SYSTEM
}
-static void paint_button (MONTHCAL_INFO *infoPtr, HDC hdc, BOOL btnNext)
+static void MONTHCAL_PaintButton(MONTHCAL_INFO *infoPtr, HDC hdc, BOOL btnNext)
{
HTHEME theme = GetWindowTheme (infoPtr->hwndSelf);
RECT *r = btnNext ? &infoPtr->titlebtnnext : &infoPtr->titlebtnprev;
@@ -744,347 +743,309 @@ static void paint_button (MONTHCAL_INFO *infoPtr, HDC hdc, BOOL btnNext)
DrawFrameControl(hdc, r, DFC_SCROLL, style);
}
}
-
-
-static void MONTHCAL_Refresh(MONTHCAL_INFO *infoPtr, HDC hdc, const PAINTSTRUCT *ps)
+/* paint a title with buttons and month/year string */
+static void MONTHCAL_PaintTitle(MONTHCAL_INFO *infoPtr, HDC hdc, const PAINTSTRUCT *ps)
{
static const WCHAR fmt_monthW[] = { '%','s',' ','%','l','d',0 };
- RECT *title=&infoPtr->title;
- RECT *titlemonth=&infoPtr->titlemonth;
- RECT *titleyear=&infoPtr->titleyear;
- RECT dayrect;
- int i, j, m, mask, day, prevMonth;
- int textHeight = infoPtr->textHeight;
- SIZE size;
+ WCHAR buf_month[80], buf_fmt[80];
HBRUSH hbr;
- HFONT currentFont;
- WCHAR buf[20];
- WCHAR buf1[20];
- WCHAR buf2[32];
- COLORREF oldTextColor, oldBkColor;
- RECT rcTemp;
- RECT rcDay; /* used in MONTHCAL_CalcDayRect() */
- int startofprescal;
- SYSTEMTIME st;
-
- oldTextColor = SetTextColor(hdc, comctl32_color.clrWindowText);
+ RECT *title = &infoPtr->title;
+ SIZE sz;
- /* fill background */
- hbr = CreateSolidBrush (infoPtr->bk);
- FillRect(hdc, &ps->rcPaint, hbr);
+ /* fill header box */
+ hbr = CreateSolidBrush(infoPtr->titlebk);
+ FillRect(hdc, title, hbr);
DeleteObject(hbr);
- /* draw header */
- if(IntersectRect(&rcTemp, &(ps->rcPaint), title))
- {
- hbr = CreateSolidBrush(infoPtr->titlebk);
- FillRect(hdc, title, hbr);
- DeleteObject(hbr);
- }
+ /* navigation buttons */
+ MONTHCAL_PaintButton(infoPtr, hdc, FALSE);
+ MONTHCAL_PaintButton(infoPtr, hdc, TRUE);
+
+ /* month/year string */
+ SetBkColor(hdc, infoPtr->titlebk);
+ SetTextColor(hdc, infoPtr->titletxt);
+ SelectObject(hdc, infoPtr->hBoldFont);
- /* if the previous button is pressed draw it depressed */
- if(IntersectRect(&rcTemp, &(ps->rcPaint), &infoPtr->titlebtnprev))
- paint_button(infoPtr, hdc, FALSE);
+ GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SMONTHNAME1+infoPtr->curSel.wMonth-1,
+ buf_month, countof(buf_month));
- /* if next button is depressed draw it depressed */
- if(IntersectRect(&rcTemp, &(ps->rcPaint), &infoPtr->titlebtnnext))
- paint_button(infoPtr, hdc, TRUE);
+ wsprintfW(buf_fmt, fmt_monthW, buf_month, infoPtr->curSel.wYear);
+ DrawTextW(hdc, buf_fmt, strlenW(buf_fmt), title,
+ DT_CENTER | DT_VCENTER | DT_SINGLELINE);
- oldBkColor = SetBkColor(hdc, infoPtr->titlebk);
- SetTextColor(hdc, infoPtr->titletxt);
- currentFont = SelectObject(hdc, infoPtr->hBoldFont);
+ /* update title rectangles with current month - used while testing hits */
+ GetTextExtentPoint32W(hdc, buf_fmt, strlenW(buf_fmt), &sz);
+ infoPtr->titlemonth.left = title->right / 2 + title->left / 2 - sz.cx / 2;
+ infoPtr->titleyear.right = title->right / 2 + title->left / 2 + sz.cx / 2;
+
+ GetTextExtentPoint32W(hdc, buf_month, strlenW(buf_month), &sz);
+ infoPtr->titlemonth.right = infoPtr->titlemonth.left + sz.cx;
+ infoPtr->titleyear.left = infoPtr->titlemonth.right;
+}
+
+static void MONTHCAL_PaintWeeknumbers(MONTHCAL_INFO *infoPtr, HDC hdc, const PAINTSTRUCT *ps)
+{
+ static const WCHAR fmt_weekW[] = { '%','d',0 };
+ INT mindays, weeknum, weeknum1, startofprescal;
+ SYSTEMTIME st = infoPtr->curSel;
+ RECT r;
+ WCHAR buf[80];
+ INT i, prev_month;
- GetLocaleInfoW( LOCALE_USER_DEFAULT,LOCALE_SMONTHNAME1+infoPtr->curSel.wMonth -1,
- buf1,countof(buf1));
- wsprintfW(buf, fmt_monthW, buf1, infoPtr->curSel.wYear);
+ if (!(infoPtr->dwStyle & MCS_WEEKNUMBERS)) return;
- if(IntersectRect(&rcTemp, &(ps->rcPaint), title))
+ MONTHCAL_GetMinDate(infoPtr, &st);
+ startofprescal = st.wDay;
+ st = infoPtr->curSel;
+
+ prev_month = infoPtr->curSel.wMonth - 1;
+ if(prev_month == 0) prev_month = 12;
+
+ /*
+ Rules what week to call the first week of a new year:
+ LOCALE_IFIRSTWEEKOFYEAR == 0 (e.g US?):
+ The week containing Jan 1 is the first week of year
+ LOCALE_IFIRSTWEEKOFYEAR == 2 (e.g. Germany):
+ First week of year must contain 4 days of the new year
+ LOCALE_IFIRSTWEEKOFYEAR == 1 (what contries?)
+ The first week of the year must contain only days of the new year
+ */
+ GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_IFIRSTWEEKOFYEAR, buf, countof(buf));
+ weeknum = atoiW(buf);
+ switch (weeknum)
{
- DrawTextW(hdc, buf, strlenW(buf), title,
- DT_CENTER | DT_VCENTER | DT_SINGLELINE);
+ case 1: mindays = 6;
+ break;
+ case 2: mindays = 3;
+ break;
+ case 0: mindays = 0;
+ break;
+ default:
+ WARN("Unknown LOCALE_IFIRSTWEEKOFYEAR value %d, defaulting to 0\n", weeknum);
+ mindays = 0;
}
+ if (infoPtr->curSel.wMonth < 2)
+ {
+ /* calculate all those exceptions for january */
+ st.wDay = st.wMonth = 1;
+ weeknum1 = MONTHCAL_CalculateDayOfWeek(&st, FALSE);
+ if ((infoPtr->firstDay - weeknum1) % 7 > mindays)
+ weeknum = 1;
+ else
+ {
+ weeknum = 0;
+ for(i = 0; i < 11; i++)
+ weeknum += MONTHCAL_MonthLength(i+1, infoPtr->curSel.wYear - 1);
-/* 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)
- */
- GetTextExtentPoint32W(hdc, buf, strlenW(buf), &size);
- titlemonth->left = title->right / 2 + title->left / 2 - size.cx / 2;
- titleyear->right = title->right / 2 + title->left / 2 + size.cx / 2;
- GetTextExtentPoint32W(hdc, buf1, strlenW(buf1), &size);
- titlemonth->right = titlemonth->left + size.cx;
- titleyear->left = titlemonth->right;
-
- /* draw month area */
- rcTemp.top=infoPtr->wdays.top;
- rcTemp.left=infoPtr->wdays.left;
- rcTemp.bottom=infoPtr->todayrect.bottom;
- rcTemp.right =infoPtr->todayrect.right;
- if(IntersectRect(&rcTemp, &(ps->rcPaint), &rcTemp))
+ weeknum += startofprescal + 7;
+ weeknum /= 7;
+ st.wYear -= 1;
+ weeknum1 = MONTHCAL_CalculateDayOfWeek(&st, FALSE);
+ if ((infoPtr->firstDay - weeknum1) % 7 > mindays) weeknum++;
+ }
+ }
+ else
{
- hbr = CreateSolidBrush(infoPtr->monthbk);
- FillRect(hdc, &rcTemp, hbr);
- DeleteObject(hbr);
+ weeknum = 0;
+ for(i = 0; i < prev_month - 1; i++)
+ weeknum += MONTHCAL_MonthLength(i+1, infoPtr->curSel.wYear);
+
+ weeknum += startofprescal + 7;
+ weeknum /= 7;
+ st.wDay = st.wMonth = 1;
+ weeknum1 = MONTHCAL_CalculateDayOfWeek(&st, FALSE);
+ if ((infoPtr->firstDay - weeknum1) % 7 > mindays) weeknum++;
}
-/* draw line under day abbreviations */
+ r = infoPtr->weeknums;
+ r.bottom = r.top + infoPtr->height_increment;
+
+ for(i = 0; i < 6; i++) {
+ if((i == 0) && (weeknum > 50))
+ {
+ wsprintfW(buf, fmt_weekW, weeknum);
+ weeknum = 0;
+ }
+ else if((i == 5) && (weeknum > 47))
+ {
+ wsprintfW(buf, fmt_weekW, 1);
+ }
+ else
+ wsprintfW(buf, fmt_weekW, weeknum + i);
+
+ DrawTextW(hdc, buf, -1, &r, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
+ OffsetRect(&r, 0, infoPtr->height_increment);
+ }
+
+ /* line separator for week numbers column */
+ MoveToEx(hdc, infoPtr->weeknums.right, infoPtr->weeknums.top + 3 , NULL);
+ LineTo(hdc, infoPtr->weeknums.right, infoPtr->weeknums.bottom);
+}
+
+/* paint a calendar area */
+static void MONTHCAL_PaintCalendar(MONTHCAL_INFO *infoPtr, HDC hdc, const PAINTSTRUCT *ps)
+{
+ INT prev_month, i, j;
+ WCHAR buf[80];
+ HBRUSH hbr;
+ RECT r;
+ int mask;
+ SYSTEMTIME st;
+
+ UnionRect(&r, &infoPtr->wdays, &infoPtr->todayrect);
- MoveToEx(hdc, infoPtr->days.left + 3, title->bottom + textHeight + 1, NULL);
- LineTo(hdc, infoPtr->days.right - 3, title->bottom + textHeight + 1);
+ hbr = CreateSolidBrush(infoPtr->monthbk);
+ FillRect(hdc, &r, hbr);
+ DeleteObject(hbr);
+
+ /* draw line under day abbreviations */
+ MoveToEx(hdc, infoPtr->days.left + 3,
+ infoPtr->title.bottom + infoPtr->textHeight + 1, NULL);
+ LineTo(hdc, infoPtr->days.right - 3,
+ infoPtr->title.bottom + infoPtr->textHeight + 1);
- prevMonth = infoPtr->curSel.wMonth - 1;
- if(prevMonth == 0) /* if curSel.wMonth is january(1) prevMonth is */
- prevMonth = 12; /* december(12) of the previous year */
+ prev_month = infoPtr->curSel.wMonth - 1;
+ if(prev_month == 0) prev_month = 12;
- infoPtr->wdays.left = infoPtr->days.left = infoPtr->weeknums.right;
+ infoPtr->wdays.left = infoPtr->days.left = infoPtr->weeknums.right;
- /* draw day abbreviations */
+ /* 1. draw day abbreviations */
SelectObject(hdc, infoPtr->hFont);
SetBkColor(hdc, infoPtr->monthbk);
SetTextColor(hdc, infoPtr->trailingtxt);
-
/* rectangle to draw a single day abbreviation within */
- dayrect = infoPtr->wdays;
- dayrect.right = dayrect.left + infoPtr->width_increment;
+ r = infoPtr->wdays;
+ r.right = r.left + infoPtr->width_increment;
i = infoPtr->firstDay;
-
for(j = 0; j < 7; j++) {
GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SABBREVDAYNAME1 + (i+j+6)%7, buf, countof(buf));
- DrawTextW(hdc, buf, strlenW(buf), &dayrect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
- dayrect.left += infoPtr->width_increment;
- dayrect.right += infoPtr->width_increment;
+ DrawTextW(hdc, buf, strlenW(buf), &r, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
+ OffsetRect(&r, infoPtr->width_increment, 0);
}
- /* draw day numbers; first, the previous month */
- MONTHCAL_GetMinDate(infoPtr, &st);
- day = st.wDay;
- startofprescal = day;
- mask = 1<<(day-1);
-
- i = 0;
- m = 0;
- while(st.wDay <= MONTHCAL_MonthLength(prevMonth, infoPtr->curSel.wYear)) {
- MONTHCAL_CalcDayRect(infoPtr, &rcDay, i, 0);
- if(IntersectRect(&rcTemp, &(ps->rcPaint), &rcDay))
- {
- MONTHCAL_DrawDay(infoPtr, hdc, &st, i, 0,
- infoPtr->monthdayState[m] & mask);
- }
-
- mask <<= 1;
- st.wDay++;
- i++;
- }
+ /* 2. previous and next months */
+ if (!(infoPtr->dwStyle & MCS_NOTRAILINGDATES))
+ {
+ SYSTEMTIME st_max;
-/* draw `current' month */
+ SetTextColor(hdc, infoPtr->trailingtxt);
- day = 1; /* start at the beginning of the current month */
- st = infoPtr->curSel;
- st.wDay = 1;
- infoPtr->firstDayplace = i;
- SetTextColor(hdc, infoPtr->txt);
- m++;
- mask = 1;
+ MONTHCAL_GetMinDate(infoPtr, &st);
- /* draw the first week of the current month */
- while(i < 7) {
- MONTHCAL_CalcDayRect(infoPtr, &rcDay, i, 0);
- if(IntersectRect(&rcTemp, &(ps->rcPaint), &rcDay))
- {
- MONTHCAL_DrawDay(infoPtr, hdc, &st, i, 0,
- infoPtr->monthdayState[m] & mask);
+ /* draw prev month */
+ mask = 1 << (st.wDay-1);
+ while(st.wDay <= MONTHCAL_MonthLength(prev_month, infoPtr->curSel.wYear)) {
+ MONTHCAL_DrawDay(infoPtr, hdc, &st, infoPtr->monthdayState[0] & mask, ps);
+ mask <<= 1;
+ st.wDay++;
}
- mask<<=1;
- st.wDay++;
- i++;
- }
-
- j = 1; /* move to the 2nd week of the current month */
- i = 0; /* move back to sunday */
- while(st.wDay <= MONTHCAL_MonthLength(infoPtr->curSel.wMonth, infoPtr->curSel.wYear)) {
- MONTHCAL_CalcDayRect(infoPtr, &rcDay, i, j);
- if(IntersectRect(&rcTemp, &(ps->rcPaint), &rcDay))
- {
- MONTHCAL_DrawDay(infoPtr, hdc, &st, i, j,
- infoPtr->monthdayState[m] & mask);
- }
- mask<<=1;
- st.wDay++;
- i++;
- if(i>6) { /* past saturday, goto the next weeks sunday */
- i = 0;
- j++;
+ /* draw next month */
+ st = infoPtr->curSel;
+ st.wDay = 1;
+ MONTHCAL_GetNextMonth(&st);
+ MONTHCAL_GetMaxDate(infoPtr, &st_max);
+ mask = 1;
+ while(st.wDay <= st_max.wDay) {
+ MONTHCAL_DrawDay(infoPtr, hdc, &st, infoPtr->monthdayState[2] & mask, ps);
+ mask <<= 1;
+ st.wDay++;
}
}
-/* draw `next' month */
-
- day = 1; /* start at the first day of the next month */
+ /* 3. current month */
+ SetTextColor(hdc, infoPtr->txt);
st = infoPtr->curSel;
st.wDay = 1;
- MONTHCAL_GetNextMonth(&st);
- m++;
mask = 1;
-
- SetTextColor(hdc, infoPtr->trailingtxt);
- while((i<7) &&(j<6)) {
- MONTHCAL_CalcDayRect(infoPtr, &rcDay, i, j);
- if(IntersectRect(&rcTemp, &(ps->rcPaint), &rcDay))
- {
- MONTHCAL_DrawDay(infoPtr, hdc, &st, i, j,
- infoPtr->monthdayState[m] & mask);
- }
-
- mask<<=1;
+ while(st.wDay <= MONTHCAL_MonthLength(infoPtr->curSel.wMonth, infoPtr->curSel.wYear)) {
+ MONTHCAL_DrawDay(infoPtr, hdc, &st, infoPtr->monthdayState[1] & mask,
+ ps);
+ mask <<= 1;
st.wDay++;
- day++;
- i++;
- if(i==7) { /* past saturday, go to next week's sunday */
- i = 0;
- j++;
- }
- }
- SetTextColor(hdc, infoPtr->txt);
-
- /* draw today mark rectangle */
- if((infoPtr->curSel.wMonth == infoPtr->todaysDate.wMonth) &&
- (infoPtr->curSel.wYear == infoPtr->todaysDate.wYear) &&
- !(infoPtr->dwStyle & MCS_NOTODAYCIRCLE))
- {
- MONTHCAL_CircleDay(infoPtr, hdc, &infoPtr->todaysDate);
}
- /* draw focused day */
- if(!MONTHCAL_IsDateEqual(&infoPtr->focusedSel, &st_null))
- {
- MONTHCAL_CalcPosFromDay(infoPtr, &infoPtr->focusedSel, &rcDay);
-
- DrawFocusRect(hdc, &rcDay);
- }
-
- /* draw `today' date if style allows it, and draw a circle before today's
- * date if necessary */
+ /* 4. bottom today date */
if(!(infoPtr->dwStyle & MCS_NOTODAY)) {
static const WCHAR todayW[] = { 'T','o','d','a','y',':',0 };
static const WCHAR fmt_todayW[] = { '%','s',' ','%','s',0 };
+ WCHAR buf_todayW[30], buf_dateW[20];
RECT rtoday;
if(!(infoPtr->dwStyle & MCS_NOTODAYCIRCLE)) {
- SYSTEMTIME fake_st = infoPtr->curSel;
+ SYSTEMTIME fake_st;
- /*day is the number of days from nextmonth we put on the calendar */
- fake_st.wDay = day + MONTHCAL_MonthLength(infoPtr->curSel.wMonth, infoPtr->curSel.wYear);
+ MONTHCAL_GetMaxDate(infoPtr, &fake_st);
+ /* this is always safe cause next month will never fully fit calendar */
+ fake_st.wDay += 1;
MONTHCAL_CircleDay(infoPtr, hdc, &fake_st);
}
- if (!LoadStringW(COMCTL32_hModule, IDM_TODAY, buf1, countof(buf1)))
+ if (!LoadStringW(COMCTL32_hModule, IDM_TODAY, buf_todayW, countof(buf_todayW)))
{
WARN("Can't load resource\n");
- strcpyW(buf1, todayW);
+ strcpyW(buf_todayW, todayW);
}
MONTHCAL_CalcDayRect(infoPtr, &rtoday, 1, 6);
GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &infoPtr->todaysDate, NULL,
- buf2, countof(buf2));
- wsprintfW(buf, fmt_todayW, buf1, buf2);
+ buf_dateW, countof(buf_dateW));
SelectObject(hdc, infoPtr->hBoldFont);
+ wsprintfW(buf, fmt_todayW, buf_todayW, buf_dateW);
DrawTextW(hdc, buf, -1, &rtoday, DT_CALCRECT | DT_LEFT | DT_VCENTER | DT_SINGLELINE);
- if(IntersectRect(&rcTemp, &(ps->rcPaint), &rtoday))
- {
- DrawTextW(hdc, buf, -1, &rtoday, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
- }
+ DrawTextW(hdc, buf, -1, &rtoday, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
+
SelectObject(hdc, infoPtr->hFont);
}
- /* eventually draw week numbers */
- if(infoPtr->dwStyle & MCS_WEEKNUMBERS) {
- static const WCHAR fmt_weekW[] = { '%','d',0 }; /* week numbers format */
- int mindays, weeknum, weeknum1;
- SYSTEMTIME st = infoPtr->curSel;
-
- /* Rules what week to call the first week of a new year:
- LOCALE_IFIRSTWEEKOFYEAR == 0 (e.g US?):
- The week containing Jan 1 is the first week of year
- LOCALE_IFIRSTWEEKOFYEAR == 2 (e.g. Germany):
- First week of year must contain 4 days of the new year
- LOCALE_IFIRSTWEEKOFYEAR == 1 (what contries?)
- The first week of the year must contain only days of the new year
- */
- GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_IFIRSTWEEKOFYEAR, buf, countof(buf));
- weeknum = atoiW(buf);
- switch (weeknum)
- {
- case 1: mindays = 6;
- break;
- case 2: mindays = 3;
- break;
- case 0:
- default:
- mindays = 0;
- }
- if (infoPtr->curSel.wMonth < 2)
- {
- /* calculate all those exceptions for january */
- st.wDay = st.wMonth = 1;
- weeknum1 = MONTHCAL_CalculateDayOfWeek(&st, FALSE);
- if ((infoPtr->firstDay - weeknum1) % 7 > mindays)
- weeknum = 1;
- else
- {
- weeknum = 0;
- for(i = 0; i < 11; i++)
- weeknum += MONTHCAL_MonthLength(i+1, infoPtr->curSel.wYear - 1);
-
- weeknum += startofprescal + 7;
- weeknum /= 7;
- st.wYear -= 1;
- weeknum1 = MONTHCAL_CalculateDayOfWeek(&st, FALSE);
- if ((infoPtr->firstDay - weeknum1) % 7 > mindays) weeknum++;
- }
- }
- else
- {
- weeknum = 0;
- for(i = 0; i < prevMonth - 1; i++)
- weeknum += MONTHCAL_MonthLength(i+1, infoPtr->curSel.wYear);
+ /* 5. today mark + focus */
+ if((infoPtr->curSel.wMonth == infoPtr->todaysDate.wMonth) &&
+ (infoPtr->curSel.wYear == infoPtr->todaysDate.wYear) &&
+ !(infoPtr->dwStyle & MCS_NOTODAYCIRCLE))
+ {
+ MONTHCAL_CircleDay(infoPtr, hdc, &infoPtr->todaysDate);
+ }
- weeknum += startofprescal + 7;
- weeknum /= 7;
- st.wDay = st.wMonth = 1;
- weeknum1 = MONTHCAL_CalculateDayOfWeek(&st, FALSE);
- if ((infoPtr->firstDay - weeknum1) % 7 > mindays) weeknum++;
- }
+ if(!MONTHCAL_IsDateEqual(&infoPtr->focusedSel, &st_null))
+ {
+ MONTHCAL_CalcPosFromDay(infoPtr, &infoPtr->focusedSel, &r);
+ DrawFocusRect(hdc, &r);
+ }
+}
- dayrect = infoPtr->weeknums;
- dayrect.bottom = dayrect.top + infoPtr->height_increment;
+static void MONTHCAL_Refresh(MONTHCAL_INFO *infoPtr, HDC hdc, const PAINTSTRUCT *ps)
+{
+ RECT *title=&infoPtr->title;
+ HBRUSH hbr;
+ COLORREF old_text_clr, old_bk_clr;
+ HFONT old_font;
+ RECT r_temp;
- for(i = 0; i < 6; i++) {
- if((i == 0) && (weeknum > 50))
- {
- wsprintfW(buf, fmt_weekW, weeknum);
- weeknum = 0;
- }
- else if((i == 5) && (weeknum > 47))
- {
- wsprintfW(buf, fmt_weekW, 1);
- }
- else
- wsprintfW(buf, fmt_weekW, weeknum + i);
+ old_text_clr = SetTextColor(hdc, comctl32_color.clrWindowText);
+ old_bk_clr = GetBkColor(hdc);
+ old_font = GetCurrentObject(hdc, OBJ_FONT);
- DrawTextW(hdc, buf, -1, &dayrect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
- dayrect.top += infoPtr->height_increment;
- dayrect.bottom += infoPtr->height_increment;
- }
+ /* fill background */
+ hbr = CreateSolidBrush (infoPtr->bk);
+ FillRect(hdc, &ps->rcPaint, hbr);
+ DeleteObject(hbr);
- MoveToEx(hdc, infoPtr->weeknums.right, infoPtr->weeknums.top + 3 , NULL);
- LineTo(hdc, infoPtr->weeknums.right, infoPtr->weeknums.bottom);
- }
+ /* draw title, redraw all its elements */
+ if(IntersectRect(&r_temp, &(ps->rcPaint), title))
+ MONTHCAL_PaintTitle(infoPtr, hdc, ps);
- /* currentFont was font at entering Refresh */
- SetBkColor(hdc, oldBkColor);
- SelectObject(hdc, currentFont);
- SetTextColor(hdc, oldTextColor);
+ /* draw calendar area */
+ UnionRect(&r_temp, &infoPtr->wdays, &infoPtr->todayrect);
+ if(IntersectRect(&r_temp, &(ps->rcPaint), &r_temp))
+ MONTHCAL_PaintCalendar(infoPtr, hdc, ps);
+
+ /* week numbers */
+ MONTHCAL_PaintWeeknumbers(infoPtr, hdc, ps);
+
+ /* restore context */
+ SetBkColor(hdc, old_bk_clr);
+ SelectObject(hdc, old_font);
+ SetTextColor(hdc, old_text_clr);
}
diff --git a/include/commctrl.h b/include/commctrl.h
index 8e22e7a..2add8b8 100644
--- a/include/commctrl.h
+++ b/include/commctrl.h
@@ -4668,6 +4668,7 @@ static const WCHAR MONTHCAL_CLASSW[] = { 'S','y','s',
#define MCS_WEEKNUMBERS 0x0004
#define MCS_NOTODAY 0x0010
#define MCS_NOTODAYCIRCLE 0x0008
+#define MCS_NOTRAILINGDATES 0x0040
#define MCHT_TITLE 0x00010000
#define MCHT_CALENDAR 0x00020000
--
1.5.6.5
--=-SV8KDtzRt6i87j5tQ6wD--
More information about the wine-patches
mailing list