diff --git a/dlls/comctl32/monthcal.c b/dlls/comctl32/monthcal.c index be9d7056f00..7c02f0a080a 100644 --- a/dlls/comctl32/monthcal.c +++ b/dlls/comctl32/monthcal.c @@ -934,6 +934,7 @@ static LRESULT MONTHCAL_SetRange(MONTHCAL_INFO *infoPtr, WPARAM wParam, LPARAM lParam) { SYSTEMTIME *lprgSysTimeArray=(SYSTEMTIME *)lParam; + FILETIME ft_min, ft_max; TRACE("%x %lx\n", wParam, lParam); @@ -952,6 +953,30 @@ MONTHCAL_SetRange(MONTHCAL_INFO *infoPtr, WPARAM wParam, LPARAM lParam) infoPtr->rangeValid |= GDTR_MAX; } + /* 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); + + if (CompareFileTime(&ft_min, &ft_max) > 0) + { + if ((wParam & (GDTR_MIN | GDTR_MAX)) == (GDTR_MIN | GDTR_MAX)) + { + /* Native swaps limits only when both limits are being set. */ + 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? */ + infoPtr->rangeValid &= wParam & GDTR_MIN ? ~GDTR_MAX : ~GDTR_MIN ; + } + } + return TRUE; } diff --git a/dlls/comctl32/tests/monthcal.c b/dlls/comctl32/tests/monthcal.c index 52103f03fec..89d3bc66092 100644 --- a/dlls/comctl32/tests/monthcal.c +++ b/dlls/comctl32/tests/monthcal.c @@ -67,6 +67,7 @@ void test_monthcal(void) 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"); st[1].wMonth += 2; ok(SendMessage(hwnd, MCM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st), "Failed to set both min and max limits\n"); @@ -80,13 +81,14 @@ void test_monthcal(void) 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"); 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"); } START_TEST(monthcal)