comctl32: Fix number of bugs with MONTHCAL_SetRange. Add more tests.

Vitaliy Margolen wine-patch at kievinfo.com
Tue Feb 7 09:08:26 CST 2006


ChangeLog:
comctl32: Fix number of bugs with MONTHCAL_SetRange. Add more tests.

 dlls/comctl32/monthcal.c       |   79 ++++++++++++++++++++++------------------
 dlls/comctl32/tests/monthcal.c |   26 ++++++++++++-
 2 files changed, 67 insertions(+), 38 deletions(-)
-------------- next part --------------
0ab6d606f970b15a126c0e65160d2d5e29081849
diff --git a/dlls/comctl32/monthcal.c b/dlls/comctl32/monthcal.c
index 340b681..03f6ef4 100644
--- a/dlls/comctl32/monthcal.c
+++ b/dlls/comctl32/monthcal.c
@@ -160,7 +160,7 @@ int MONTHCAL_MonthLength(int month, int 
 /* make sure that time is valid */
 static int MONTHCAL_ValidateTime(SYSTEMTIME time)
 {
-  if(time.wMonth > 12) return FALSE;
+  if(time.wMonth < 1 || time.wMonth > 12 ) return FALSE;
   if(time.wDayOfWeek > 6) return FALSE;
   if(time.wDay > MONTHCAL_MonthLength(time.wMonth, time.wYear))
 	  return FALSE;
@@ -934,48 +934,57 @@ MONTHCAL_GetMaxTodayWidth(MONTHCAL_INFO 
 }
 
 
-/* FIXME: are validated times taken from current date/time or simply
- * copied?
- * FIXME:    check whether MCM_GETMONTHRANGE shows correct result after
- *            adjusting range with MCM_SETRANGE
- */
-
 static LRESULT
 MONTHCAL_SetRange(MONTHCAL_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
 {
-  SYSTEMTIME *lprgSysTimeArray=(SYSTEMTIME *)lParam;
-  int prev;
+    SYSTEMTIME *lprgSysTimeArray=(SYSTEMTIME *)lParam;
+    FILETIME ft_min, ft_max;
 
-  TRACE("%x %lx\n", wParam, lParam);
+    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(wParam & GDTR_MIN) {
-    if(MONTHCAL_ValidateTime(lprgSysTimeArray[0])) {
-      MONTHCAL_CopyTime(&lprgSysTimeArray[0], &infoPtr->minDate);
-      infoPtr->rangeValid|=GDTR_MIN;
-    } else {
-      GetSystemTime(&infoPtr->todaysDate);
-      MONTHCAL_CopyTime(&infoPtr->todaysDate, &infoPtr->minDate);
+    if ((wParam & GDTR_MIN && !MONTHCAL_ValidateTime(lprgSysTimeArray[0])) ||
+        (wParam & GDTR_MAX && !MONTHCAL_ValidateTime(lprgSysTimeArray[1])))
+        return FALSE;
+
+    if (wParam & GDTR_MIN)
+    {
+        MONTHCAL_CopyTime(&lprgSysTimeArray[0], &infoPtr->minDate);
+        infoPtr->rangeValid |= GDTR_MIN;
+    }
+    if (wParam & GDTR_MAX)
+    {
+        MONTHCAL_CopyTime(&lprgSysTimeArray[1], &infoPtr->maxDate);
+        infoPtr->rangeValid |= GDTR_MAX;
     }
-  }
 
-  prev = infoPtr->monthRange;
-  infoPtr->monthRange = infoPtr->maxDate.wMonth - infoPtr->minDate.wMonth;
-
-  if(infoPtr->monthRange!=prev) {
-	infoPtr->monthdayState = ReAlloc(infoPtr->monthdayState,
-                                                  infoPtr->monthRange * sizeof(MONTHDAYSTATE));
-  }
+    /* Only one limit set - we are done */
+    if ((infoPtr->rangeValid & (GDTR_MIN | GDTR_MAX)) != (GDTR_MIN | GDTR_MAX))
+        return TRUE;
+    
+    SystemTimeToFileTime(&infoPtr->maxDate, &ft_max);
+    SystemTimeToFileTime(&infoPtr->minDate, &ft_min);
 
-  return 1;
+    if (CompareFileTime(&ft_min, &ft_max) > 0)
+    {
+        if ((wParam & (GDTR_MIN | GDTR_MAX)) == (GDTR_MIN | GDTR_MAX))
+        {
+            /* Native swaps limits only when both are specified. */
+            SYSTEMTIME st_tmp = infoPtr->minDate;
+            infoPtr->minDate  = infoPtr->maxDate;
+            infoPtr->maxDate  = st_tmp;
+        }
+        else
+        {
+            /* Reset the other limit. */
+            /* FIXME: native sets date&time to 0. Should we do this too? */
+            if (wParam & GDTR_MIN)
+                infoPtr->rangeValid &= ~GDTR_MAX;
+            else
+                infoPtr->rangeValid &= ~GDTR_MIN;
+        }
+    }
+
+    return TRUE;
 }
 
 
diff --git a/dlls/comctl32/tests/monthcal.c b/dlls/comctl32/tests/monthcal.c
index 82b41b3..162749f 100644
--- a/dlls/comctl32/tests/monthcal.c
+++ b/dlls/comctl32/tests/monthcal.c
@@ -31,8 +31,9 @@
 void test_monthcal(void)
 {
     HWND hwnd;
-    SYSTEMTIME st[2];
+    SYSTEMTIME st[2], st1[2];
     INITCOMMONCONTROLSEX ic = {sizeof(INITCOMMONCONTROLSEX), ICC_DATE_CLASSES};
+    int res, month_range;
 
     InitCommonControlsEx(&ic);
     hwnd = CreateWindowA(MONTHCAL_CLASSA, "MonthCal", WS_POPUP | WS_VISIBLE, CW_USEDEFAULT,
@@ -40,27 +41,46 @@ void test_monthcal(void)
     ok(hwnd != NULL, "Failed to create MonthCal\n");
     GetSystemTime(&st[0]);
     st[0].wMonth = 5;
+    st[0].wHour  = 1;
     st[1] = st[0];
 
+    month_range = SendMessage(hwnd, MCM_GETMONTHRANGE, GMR_VISIBLE, (LPARAM)st1);
     st[1].wMonth--;
     ok(SendMessage(hwnd, MCM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st), "Failed to set both min and max limits\n");
+    res = SendMessage(hwnd, MCM_GETMONTHRANGE, GMR_VISIBLE, (LPARAM)st1);
+    ok(res == month_range, "Invalid month range (%d)\n", res);
+    ok(SendMessage(hwnd, MCM_GETRANGE, 0, (LPARAM)st1) == (GDTR_MIN|GDTR_MAX), "Limits should be set\n");
+    trace("%01d %02d/%02d/%04d %02d:%02d:%02d.%04d\n", st1[0].wDayOfWeek, st1[0].wYear, st1[0].wMonth, st1[0].wDay,
+    st1[0].wHour, st1[0].wMinute, st1[0].wSecond, st1[0].wMilliseconds);
+
     st[1].wMonth += 2;
     ok(SendMessage(hwnd, MCM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st), "Failed to set both min and max limits\n");
+    res = SendMessage(hwnd, MCM_GETMONTHRANGE, GMR_VISIBLE, (LPARAM)st1);
+    ok(res == month_range, "Invalid month range (%d)\n", res);
     st[1].wYear --;
     ok(SendMessage(hwnd, MCM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st), "Failed to set both min and max limits\n");
     st[1].wYear += 1;
     ok(SendMessage(hwnd, MCM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st), "Failed to set both min and max limits\n");
+    ok(SendMessage(hwnd, MCM_GETRANGE, 0, (LPARAM)st1) == (GDTR_MIN|GDTR_MAX), "Limits should be set\n");
 
-/* This crashing Wine so commented untill fixed.
     st[1].wMonth -= 3;
     ok(SendMessage(hwnd, MCM_SETRANGE, GDTR_MAX, (LPARAM)st), "Failed to set max limit\n");
-*/
+    ok(SendMessage(hwnd, MCM_GETRANGE, 0, (LPARAM)st1) == GDTR_MAX, "Only MAX limit should be set\n");
+    trace("%01d %02d/%02d/%04d %02d:%02d:%02d.%04d\n", st1[0].wDayOfWeek, st1[0].wYear, st1[0].wMonth, st1[0].wDay,
+    st1[0].wHour, st1[0].wMinute, st1[0].wSecond, st1[0].wMilliseconds);
     st[1].wMonth += 4;
     ok(SendMessage(hwnd, MCM_SETRANGE, GDTR_MAX, (LPARAM)st), "Failed to set max limit\n");
     st[1].wYear -= 3;
     ok(SendMessage(hwnd, MCM_SETRANGE, GDTR_MAX, (LPARAM)st), "Failed to set max limit\n");
     st[1].wYear += 4;
     ok(SendMessage(hwnd, MCM_SETRANGE, GDTR_MAX, (LPARAM)st), "Failed to set max limit\n");
+    ok(SendMessage(hwnd, MCM_GETRANGE, 0, (LPARAM)st1) == GDTR_MAX, "Only MAX limit should be set\n");
+
+    /* Invalid date */
+    st[0].wYear  = 2000;
+    st[1].wMonth = 0;
+    ok(!SendMessage(hwnd, MCM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st), "Should have failed to set limits\n");
+    ok(st1[0].wYear != 2000, "Lover limit changed\n");
 }
 
 START_TEST(monthcal)


More information about the wine-patches mailing list