[PATCH 12/15] Fix timestamp storing on MCM_SETRANGE/MCM_SETSELRANGE

Nikolay Sivov bunglehead at gmail.com
Sat Sep 26 11:06:48 CDT 2009


---
 dlls/comctl32/monthcal.c       |   49 ++++++++++++++++++++++++++++++++-------
 dlls/comctl32/tests/monthcal.c |   30 +++++++++++++++++++++++-
 2 files changed, 69 insertions(+), 10 deletions(-)

diff --git a/dlls/comctl32/monthcal.c b/dlls/comctl32/monthcal.c
index 270e72b..0d5ac3c 100644
--- a/dlls/comctl32/monthcal.c
+++ b/dlls/comctl32/monthcal.c
@@ -160,17 +160,35 @@ static inline BOOL MONTHCAL_IsDateEqual(const SYSTEMTIME *first, const SYSTEMTIM
          (first->wDay  == second->wDay);
 }
 
-/* make sure that time is valid */
-static BOOL MONTHCAL_ValidateTime(SYSTEMTIME time)
+/* make sure that date fields are valid */
+static BOOL MONTHCAL_ValidateDate(const SYSTEMTIME *time)
 {
-  if(time.wMonth < 1 || time.wMonth > 12 ) return FALSE;
-  if(time.wDayOfWeek > 6) return FALSE;
-  if(time.wDay > MONTHCAL_MonthLength(time.wMonth, time.wYear))
+  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;
 
   return TRUE;
 }
 
+/* Used in MCM_SETRANGE/MCM_SETSELRANGE to determine resulting time part.
+   Milliseconds are intentionaly not validated. */
+static BOOL MONTHCAL_ValidateTime(const SYSTEMTIME *time)
+{
+  if((time->wHour > 24) || (time->wMinute > 59) || (time->wSecond > 59))
+    return FALSE;
+  else
+    return TRUE;
+}
+
+/* Copies timestamp part only. Milliseconds are intentionaly not copied
+   cause it matches required behaviour for current use of this helper */
+static void MONTHCAL_CopyTime(const SYSTEMTIME *from, SYSTEMTIME *to)
+{
+  to->wHour   = from->wHour;
+  to->wMinute = from->wMinute;
+  to->wSecond = from->wSecond;
+}
 
 /* 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.
@@ -908,17 +926,23 @@ MONTHCAL_SetRange(MONTHCAL_INFO *infoPtr, SHORT limits, SYSTEMTIME *range)
 
     TRACE("%x %p\n", limits, range);
 
-    if ((limits & GDTR_MIN && !MONTHCAL_ValidateTime(range[0])) ||
-        (limits & GDTR_MAX && !MONTHCAL_ValidateTime(range[1])))
+    if ((limits & GDTR_MIN && !MONTHCAL_ValidateDate(&range[0])) ||
+        (limits & GDTR_MAX && !MONTHCAL_ValidateDate(&range[1])))
         return FALSE;
 
     if (limits & GDTR_MIN)
     {
+        if (!MONTHCAL_ValidateTime(&range[0]))
+            MONTHCAL_CopyTime(&infoPtr->todaysDate, &range[0]);
+
         infoPtr->minDate = range[0];
         infoPtr->rangeValid |= GDTR_MIN;
     }
     if (limits & GDTR_MAX)
     {
+        if (!MONTHCAL_ValidateTime(&range[1]))
+            MONTHCAL_CopyTime(&infoPtr->todaysDate, &range[1]);
+
         infoPtr->maxDate = range[1];
         infoPtr->rangeValid |= GDTR_MAX;
     }
@@ -1003,7 +1027,7 @@ MONTHCAL_SetCurSel(MONTHCAL_INFO *infoPtr, SYSTEMTIME *curSel)
   if(!curSel) return FALSE;
   if(infoPtr->dwStyle & MCS_MULTISELECT) return FALSE;
 
-  if(!MONTHCAL_ValidateTime(*curSel)) return FALSE;
+  if(!MONTHCAL_ValidateDate(curSel)) return FALSE;
 
   infoPtr->minSel = *curSel;
   infoPtr->maxSel = *curSel;
@@ -1067,8 +1091,15 @@ MONTHCAL_SetSelRange(MONTHCAL_INFO *infoPtr, SYSTEMTIME *range)
 
   if(infoPtr->dwStyle & MCS_MULTISELECT)
   {
-    infoPtr->maxSel = range[1];
+    /* adjust timestamps */
+    if(!MONTHCAL_ValidateTime(&range[0]))
+      MONTHCAL_CopyTime(&infoPtr->todaysDate, &range[0]);
+    if(!MONTHCAL_ValidateTime(&range[1]))
+      MONTHCAL_CopyTime(&infoPtr->todaysDate, &range[1]);
+
     infoPtr->minSel = range[0];
+    infoPtr->maxSel = range[1];
+
     TRACE("[min,max]=[%d %d]\n", infoPtr->minSel.wDay, infoPtr->maxSel.wDay);
     return TRUE;
   }
diff --git a/dlls/comctl32/tests/monthcal.c b/dlls/comctl32/tests/monthcal.c
index cc4f403..cefe8b9 100644
--- a/dlls/comctl32/tests/monthcal.c
+++ b/dlls/comctl32/tests/monthcal.c
@@ -322,7 +322,7 @@ static const struct message destroy_parent_seq[] = {
 static void test_monthcal(void)
 {
     HWND hwnd;
-    SYSTEMTIME st[2], st1[2];
+    SYSTEMTIME st[2], st1[2], today;
     int res, month_range;
 
     hwnd = CreateWindowA(MONTHCAL_CLASSA, "MonthCal", WS_POPUP | WS_VISIBLE, CW_USEDEFAULT,
@@ -354,13 +354,41 @@ static void test_monthcal(void)
     GetSystemTime(&st[0]);
     st[1] = st[0];
 
+    SendMessage(hwnd, MCM_GETTODAY, 0, (LPARAM)&today);
+
     /* Invalid date/time */
     st[0].wYear  = 2000;
     /* Time should not matter */
     st[1].wHour = st[1].wMinute = st[1].wSecond = 70;
+    st[1].wMilliseconds = 1200;
     ok(SendMessage(hwnd, MCM_SETRANGE, GDTR_MAX, (LPARAM)st), "Failed to set MAX limit\n");
+    /* invalid timestamp is written back with today data and msecs untouched */
+    expect(today.wHour, st[1].wHour);
+    expect(today.wMinute, st[1].wMinute);
+    expect(today.wSecond, st[1].wSecond);
+    expect(1200, st[1].wMilliseconds);
+
     ok(SendMessage(hwnd, MCM_GETRANGE, 0, (LPARAM)st1) == GDTR_MAX, "No limits should be set\n");
     ok(st1[0].wYear != 2000, "Lover limit changed\n");
+    /* invalid timestamp should be replaced with today data, except msecs */
+    expect(today.wHour, st1[1].wHour);
+    expect(today.wMinute, st1[1].wMinute);
+    expect(today.wSecond, st1[1].wSecond);
+    expect(1200, st1[1].wMilliseconds);
+
+    /* Invalid date/time with invalid milliseconds only */
+    GetSystemTime(&st[0]);
+    st[1] = st[0];
+    /* Time should not matter */
+    st[1].wMilliseconds = 1200;
+    ok(SendMessage(hwnd, MCM_SETRANGE, GDTR_MAX, (LPARAM)st), "Failed to set MAX limit\n");
+    /* invalid milliseconds field doesn't lead to invalid timestamp */
+    expect(st[0].wHour,   st[1].wHour);
+    expect(st[0].wMinute, st[1].wMinute);
+    expect(st[0].wSecond, st[1].wSecond);
+    expect(1200, st[1].wMilliseconds);
+
+    GetSystemTime(&st[0]);
 
     st[1].wMonth = 0;
     ok(!SendMessage(hwnd, MCM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st), "Should have failed to set limits\n");
-- 
1.5.6.5


--=-rHnpt3soyCFw+iWtZhp9--




More information about the wine-patches mailing list