[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