comctl32/datetime: Separate tests from each other.
[wine/testsucceed.git] / dlls / comctl32 / tests / datetime.c
blob986fc8e1af2931686d6be1defbd51073863311d7
1 /* Unit test suite for datetime control.
3 * Copyright 2007 Kanit Therdsteerasukdi
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #include <windows.h>
21 #include <commctrl.h>
23 #include "wine/test.h"
24 #include "msg.h"
26 #define expect(EXPECTED, GOT) ok((GOT)==(EXPECTED), "Expected %d, got %ld\n", (EXPECTED), (GOT))
28 #define expect_unsuccess(EXPECTED, GOT) ok((GOT)==(EXPECTED), "Expected %d(unsuccessful), got %ld(successful)\n", (EXPECTED), (GOT))
30 #define NUM_MSG_SEQUENCES 1
31 #define DATETIME_SEQ_INDEX 0
33 static struct msg_sequence *sequences[NUM_MSG_SEQUENCES];
35 static const struct message test_dtm_set_format_seq[] = {
36 { DTM_SETFORMATA, sent|wparam|lparam, 0, 0 },
37 { DTM_SETFORMATA, sent|wparam, 0 },
38 { 0 }
41 static const struct message test_dtm_set_and_get_mccolor_seq[] = {
42 { DTM_SETMCCOLOR, sent|wparam|lparam, MCSC_BACKGROUND, 0 },
43 { DTM_SETMCCOLOR, sent|wparam|lparam, MCSC_BACKGROUND, RGB(255, 255, 255) },
44 { DTM_SETMCCOLOR, sent|wparam|lparam, MCSC_BACKGROUND, RGB(100, 180, 220) },
45 { DTM_GETMCCOLOR, sent|wparam|lparam, MCSC_BACKGROUND, 0 },
46 { DTM_SETMCCOLOR, sent|wparam|lparam, MCSC_MONTHBK, 0 },
47 { DTM_SETMCCOLOR, sent|wparam|lparam, MCSC_MONTHBK, RGB(255, 255, 255) },
48 { DTM_SETMCCOLOR, sent|wparam|lparam, MCSC_MONTHBK, RGB(100, 180, 220) },
49 { DTM_GETMCCOLOR, sent|wparam|lparam, MCSC_MONTHBK, 0 },
50 { DTM_SETMCCOLOR, sent|wparam|lparam, MCSC_TEXT, 0 },
51 { DTM_SETMCCOLOR, sent|wparam|lparam, MCSC_TEXT, RGB(255, 255, 255) },
52 { DTM_SETMCCOLOR, sent|wparam|lparam, MCSC_TEXT, RGB(100, 180, 220) },
53 { DTM_GETMCCOLOR, sent|wparam|lparam, MCSC_TEXT, 0 },
54 { DTM_SETMCCOLOR, sent|wparam|lparam, MCSC_TITLEBK, 0 },
55 { DTM_SETMCCOLOR, sent|wparam|lparam, MCSC_TITLEBK, RGB(255, 255, 255) },
56 { DTM_SETMCCOLOR, sent|wparam|lparam, MCSC_TITLEBK, RGB(100, 180, 220) },
57 { DTM_GETMCCOLOR, sent|wparam|lparam, MCSC_TITLEBK, 0 },
58 { DTM_SETMCCOLOR, sent|wparam|lparam, MCSC_TITLETEXT, 0 },
59 { DTM_SETMCCOLOR, sent|wparam|lparam, MCSC_TITLETEXT, RGB(255, 255, 255) },
60 { DTM_SETMCCOLOR, sent|wparam|lparam, MCSC_TITLETEXT, RGB(100, 180, 220) },
61 { DTM_GETMCCOLOR, sent|wparam|lparam, MCSC_TITLETEXT, 0 },
62 { DTM_SETMCCOLOR, sent|wparam|lparam, MCSC_TRAILINGTEXT, 0 },
63 { DTM_SETMCCOLOR, sent|wparam|lparam, MCSC_TRAILINGTEXT, RGB(255, 255, 255) },
64 { DTM_SETMCCOLOR, sent|wparam|lparam, MCSC_TRAILINGTEXT, RGB(100, 180, 220) },
65 { DTM_GETMCCOLOR, sent|wparam|lparam, MCSC_TRAILINGTEXT, 0 },
66 { 0 }
69 static const struct message test_dtm_set_and_get_mcfont_seq[] = {
70 { DTM_SETMCFONT, sent|lparam, 0, 1 },
71 { DTM_GETMCFONT, sent|wparam|lparam, 0, 0 },
72 { 0 }
75 static const struct message test_dtm_get_monthcal_seq[] = {
76 { DTM_GETMONTHCAL, sent|wparam|lparam, 0, 0 },
77 { 0 }
80 static const struct message test_dtm_set_and_get_range_seq[] = {
81 { DTM_SETRANGE, sent|wparam, GDTR_MIN },
82 { DTM_GETRANGE, sent|wparam, 0 },
83 { DTM_SETRANGE, sent|wparam, GDTR_MAX },
84 { DTM_SETRANGE, sent|wparam, GDTR_MAX },
85 { DTM_GETRANGE, sent|wparam, 0 },
86 { DTM_SETRANGE, sent|wparam, GDTR_MIN },
87 { DTM_SETRANGE, sent|wparam, GDTR_MIN | GDTR_MAX },
88 { DTM_SETRANGE, sent|wparam, GDTR_MIN | GDTR_MAX },
89 { DTM_GETRANGE, sent|wparam, 0 },
90 { DTM_SETRANGE, sent|wparam, GDTR_MIN | GDTR_MAX },
91 { DTM_GETRANGE, sent|wparam, 0 },
92 { DTM_SETRANGE, sent|wparam, GDTR_MIN | GDTR_MAX },
93 { DTM_GETRANGE, sent|wparam, 0 },
94 { 0 }
97 static const struct message test_dtm_set_range_swap_min_max_seq[] = {
98 { DTM_SETSYSTEMTIME, sent|wparam, 0 },
99 { DTM_GETSYSTEMTIME, sent|wparam, 0 },
100 { DTM_SETRANGE, sent|wparam, GDTR_MIN | GDTR_MAX },
101 { DTM_GETRANGE, sent|wparam, 0 },
102 { DTM_SETSYSTEMTIME, sent|wparam, 0 },
103 { DTM_GETSYSTEMTIME, sent|wparam, 0 },
104 { DTM_SETRANGE, sent|wparam, GDTR_MIN | GDTR_MAX },
105 { DTM_GETRANGE, sent|wparam, 0 },
106 { DTM_SETRANGE, sent|wparam, GDTR_MIN | GDTR_MAX },
107 { DTM_GETRANGE, sent|wparam, 0 },
108 { DTM_SETRANGE, sent|wparam, GDTR_MIN | GDTR_MAX },
109 { DTM_GETRANGE, sent|wparam, 0 },
110 { 0 }
113 static const struct message test_dtm_set_and_get_system_time_seq[] = {
114 { DTM_SETSYSTEMTIME, sent|wparam, GDT_NONE },
115 { DTM_GETSYSTEMTIME, sent|wparam, 0 },
116 { DTM_SETSYSTEMTIME, sent|wparam, 0 },
117 { DTM_SETSYSTEMTIME, sent|wparam, 0 },
118 { DTM_SETSYSTEMTIME, sent|wparam, 0 },
119 { DTM_GETSYSTEMTIME, sent|wparam, 0 },
120 { DTM_SETSYSTEMTIME, sent|wparam, 0 },
121 { 0 }
124 struct subclass_info
126 WNDPROC oldproc;
129 static LRESULT WINAPI datetime_subclass_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
131 struct subclass_info *info = (struct subclass_info *)GetWindowLongPtrA(hwnd, GWLP_USERDATA);
132 static LONG defwndproc_counter = 0;
133 LRESULT ret;
134 struct message msg;
136 trace("datetime: %p, %04x, %08lx, %08lx\n", hwnd, message, wParam, lParam);
138 msg.message = message;
139 msg.flags = sent|wparam|lparam;
140 if (defwndproc_counter) msg.flags |= defwinproc;
141 msg.wParam = wParam;
142 msg.lParam = lParam;
143 add_message(sequences, DATETIME_SEQ_INDEX, &msg);
145 defwndproc_counter++;
146 ret = CallWindowProcA(info->oldproc, hwnd, message, wParam, lParam);
147 defwndproc_counter--;
149 return ret;
152 static HWND create_datetime_control(DWORD style, DWORD exstyle)
154 struct subclass_info *info;
155 HWND hWndDateTime = NULL;
157 info = HeapAlloc(GetProcessHeap(), 0, sizeof(struct subclass_info));
158 if (!info)
159 return NULL;
161 hWndDateTime = CreateWindowEx(0,
162 DATETIMEPICK_CLASS,
163 NULL,
164 style,
165 0,50,300,120,
166 NULL,
167 NULL,
168 NULL,
169 NULL);
171 if (!hWndDateTime) {
172 HeapFree(GetProcessHeap(), 0, info);
173 return NULL;
176 info->oldproc = (WNDPROC)SetWindowLongPtrA(hWndDateTime, GWLP_WNDPROC,
177 (LONG_PTR)datetime_subclass_proc);
178 SetWindowLongPtrA(hWndDateTime, GWLP_USERDATA, (LONG_PTR)info);
180 return hWndDateTime;
183 static void test_dtm_set_format(void)
185 HWND hWnd;
186 CHAR txt[256];
187 SYSTEMTIME systime;
188 LRESULT r;
190 hWnd = create_datetime_control(DTS_SHOWNONE, 0);
192 flush_sequences(sequences, NUM_MSG_SEQUENCES);
194 r = SendMessage(hWnd, DTM_SETFORMAT, 0, 0);
195 expect(1, r);
197 r = SendMessage(hWnd, DTM_SETFORMAT, 0,
198 (LPARAM)"'Today is: 'hh':'m':'s dddd MMM dd', 'yyyy");
199 expect(1, r);
201 ok_sequence(sequences, DATETIME_SEQ_INDEX, test_dtm_set_format_seq, "test_dtm_set_format", FALSE);
203 r = SendMessage(hWnd, DTM_SETFORMAT, 0,
204 (LPARAM)"'hh' hh");
205 expect(1, r);
206 ZeroMemory(&systime, sizeof(systime));
207 systime.wYear = 2000;
208 systime.wMonth = systime.wDay = 1;
209 r = SendMessage(hWnd, DTM_SETSYSTEMTIME, 0, (LPARAM)&systime);
210 expect(1, r);
211 GetWindowText(hWnd, txt, 256);
212 todo_wine ok(strcmp(txt, "hh 12") == 0, "String mismatch (\"%s\" vs \"hh 12\")\n", txt);
214 DestroyWindow(hWnd);
217 static void test_mccolor_types(HWND hWndDateTime, int mccolor_type, const char* mccolor_name)
219 LRESULT r;
220 COLORREF theColor, prevColor;
222 theColor=RGB(0,0,0);
223 r = SendMessage(hWndDateTime, DTM_SETMCCOLOR, mccolor_type, theColor);
224 ok(r != -1, "%s: Set RGB(0,0,0): Expected COLORREF of previous value, got %ld\n", mccolor_name, r);
225 prevColor=theColor;
226 theColor=RGB(255,255,255);
227 r = SendMessage(hWndDateTime, DTM_SETMCCOLOR, mccolor_type, theColor);
228 ok(r==prevColor, "%s: Set RGB(255,255,255): Expected COLORREF of previous value, got %ld\n", mccolor_name, r);
229 prevColor=theColor;
230 theColor=RGB(100,180,220);
231 r = SendMessage(hWndDateTime, DTM_SETMCCOLOR, mccolor_type, theColor);
232 ok(r==prevColor, "%s: Set RGB(100,180,220): Expected COLORREF of previous value, got %ld\n", mccolor_name, r);
233 r = SendMessage(hWndDateTime, DTM_GETMCCOLOR, mccolor_type, 0);
234 ok(r==theColor, "%s: GETMCCOLOR: Expected %d, got %ld\n", mccolor_name, theColor, r);
237 static void test_dtm_set_and_get_mccolor(void)
239 HWND hWnd;
241 hWnd = create_datetime_control(DTS_SHOWNONE, 0);
243 flush_sequences(sequences, NUM_MSG_SEQUENCES);
245 test_mccolor_types(hWnd, MCSC_BACKGROUND, "MCSC_BACKGROUND");
246 test_mccolor_types(hWnd, MCSC_MONTHBK, "MCSC_MONTHBK");
247 test_mccolor_types(hWnd, MCSC_TEXT, "MCSC_TEXT");
248 test_mccolor_types(hWnd, MCSC_TITLEBK, "MCSC_TITLEBK");
249 test_mccolor_types(hWnd, MCSC_TITLETEXT, "MCSC_TITLETEXT");
250 test_mccolor_types(hWnd, MCSC_TRAILINGTEXT, "MCSC_TRAILINGTEXT");
252 ok_sequence(sequences, DATETIME_SEQ_INDEX, test_dtm_set_and_get_mccolor_seq, "test_dtm_set_and_get_mccolor", FALSE);
254 DestroyWindow(hWnd);
257 static void test_dtm_set_and_get_mcfont(void)
259 HFONT hFontOrig, hFontNew;
260 HWND hWnd;
262 hWnd = create_datetime_control(DTS_SHOWNONE, 0);
264 flush_sequences(sequences, NUM_MSG_SEQUENCES);
266 hFontOrig = GetStockObject(DEFAULT_GUI_FONT);
267 SendMessage(hWnd, DTM_SETMCFONT, (WPARAM)hFontOrig, TRUE);
268 hFontNew = (HFONT)SendMessage(hWnd, DTM_GETMCFONT, 0, 0);
269 ok(hFontOrig == hFontNew, "Expected hFontOrig==hFontNew, hFontOrig=%p, hFontNew=%p\n", hFontOrig, hFontNew);
271 ok_sequence(sequences, DATETIME_SEQ_INDEX, test_dtm_set_and_get_mcfont_seq, "test_dtm_set_and_get_mcfont", FALSE);
272 DestroyWindow(hWnd);
275 static void test_dtm_get_monthcal(void)
277 LRESULT r;
278 HWND hWnd;
280 hWnd = create_datetime_control(DTS_SHOWNONE, 0);
282 flush_sequences(sequences, NUM_MSG_SEQUENCES);
284 todo_wine {
285 r = SendMessage(hWnd, DTM_GETMONTHCAL, 0, 0);
286 ok(r == 0, "Expected NULL(no child month calendar control), got %ld\n", r);
289 ok_sequence(sequences, DATETIME_SEQ_INDEX, test_dtm_get_monthcal_seq, "test_dtm_get_monthcal", FALSE);
290 DestroyWindow(hWnd);
293 static void fill_systime_struct(SYSTEMTIME *st, int year, int month, int dayofweek, int day, int hour, int minute, int second, int milliseconds)
295 st->wYear = year;
296 st->wMonth = month;
297 st->wDayOfWeek = dayofweek;
298 st->wDay = day;
299 st->wHour = hour;
300 st->wMinute = minute;
301 st->wSecond = second;
302 st->wMilliseconds = milliseconds;
305 static LPARAM compare_systime_date(SYSTEMTIME *st1, SYSTEMTIME *st2)
307 return (st1->wYear == st2->wYear)
308 && (st1->wMonth == st2->wMonth)
309 && (st1->wDayOfWeek == st2->wDayOfWeek)
310 && (st1->wDay == st2->wDay);
313 static LPARAM compare_systime_time(SYSTEMTIME *st1, SYSTEMTIME *st2)
315 return (st1->wHour == st2->wHour)
316 && (st1->wMinute == st2->wMinute)
317 && (st1->wSecond == st2->wSecond)
318 && (st1->wMilliseconds == st2->wMilliseconds);
321 static LPARAM compare_systime(SYSTEMTIME *st1, SYSTEMTIME *st2)
323 if(!compare_systime_date(st1, st2))
324 return 0;
326 return compare_systime_time(st1, st2);
329 #define expect_systime(ST1, ST2) ok(compare_systime((ST1), (ST2))==1, "ST1 != ST2\n")
330 #define expect_systime_date(ST1, ST2) ok(compare_systime_date((ST1), (ST2))==1, "ST1.date != ST2.date\n")
331 #define expect_systime_time(ST1, ST2) ok(compare_systime_time((ST1), (ST2))==1, "ST1.time != ST2.time\n")
333 static void test_dtm_set_and_get_range(void)
335 LRESULT r;
336 SYSTEMTIME st[2];
337 SYSTEMTIME getSt[2];
338 HWND hWnd;
340 hWnd = create_datetime_control(DTS_SHOWNONE, 0);
342 flush_sequences(sequences, NUM_MSG_SEQUENCES);
344 /* initialize st[0] to lowest possible value */
345 fill_systime_struct(&st[0], 1601, 1, 0, 1, 0, 0, 0, 0);
346 /* initialize st[1] to all invalid numbers */
347 fill_systime_struct(&st[1], 0, 0, 7, 0, 24, 60, 60, 1000);
349 r = SendMessage(hWnd, DTM_SETRANGE, GDTR_MIN, (LPARAM)st);
350 expect(1, r);
351 r = SendMessage(hWnd, DTM_GETRANGE, 0, (LPARAM)getSt);
352 ok(r == GDTR_MIN, "Expected %x, not %x(GDTR_MAX) or %x(GDTR_MIN | GDTR_MAX), got %lx\n", GDTR_MIN, GDTR_MAX, GDTR_MIN | GDTR_MAX, r);
353 expect_systime(&st[0], &getSt[0]);
355 r = SendMessage(hWnd, DTM_SETRANGE, GDTR_MAX, (LPARAM)st);
356 expect_unsuccess(0, r);
358 /* set st[0] to all invalid numbers */
359 fill_systime_struct(&st[0], 0, 0, 7, 0, 24, 60, 60, 1000);
360 /* set st[1] to highest possible value */
361 fill_systime_struct(&st[1], 30827, 12, 6, 31, 23, 59, 59, 999);
363 r = SendMessage(hWnd, DTM_SETRANGE, GDTR_MAX, (LPARAM)st);
364 expect(1, r);
365 r = SendMessage(hWnd, DTM_GETRANGE, 0, (LPARAM)getSt);
366 todo_wine {
367 ok(r == GDTR_MAX, "Expected %x, not %x(GDTR_MIN) or %x(GDTR_MIN | GDTR_MAX), got %lx\n", GDTR_MAX, GDTR_MIN, GDTR_MIN | GDTR_MAX, r);
369 expect_systime(&st[1], &getSt[1]);
371 r = SendMessage(hWnd, DTM_SETRANGE, GDTR_MIN, (LPARAM)st);
372 expect_unsuccess(0, r);
373 r = SendMessage(hWnd, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st);
374 expect_unsuccess(0, r);
376 /* set st[0] to highest possible value */
377 fill_systime_struct(&st[0], 30827, 12, 6, 31, 23, 59, 59, 999);
379 r = SendMessage(hWnd, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st);
380 expect(1, r);
381 r = SendMessage(hWnd, DTM_GETRANGE, 0, (LPARAM)getSt);
382 ok(r == (GDTR_MIN | GDTR_MAX), "Expected %x, not %x(GDTR_MIN) or %x(GDTR_MAX), got %lx\n", (GDTR_MIN | GDTR_MAX), GDTR_MIN, GDTR_MAX, r);
383 expect_systime(&st[0], &getSt[0]);
384 expect_systime(&st[1], &getSt[1]);
386 /* initialize st[0] to lowest possible value */
387 fill_systime_struct(&st[0], 1601, 1, 0, 1, 0, 0, 0, 0);
388 /* set st[1] to highest possible value */
389 fill_systime_struct(&st[1], 30827, 12, 6, 31, 23, 59, 59, 999);
391 r = SendMessage(hWnd, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st);
392 expect(1, r);
393 r = SendMessage(hWnd, DTM_GETRANGE, 0, (LPARAM)getSt);
394 ok(r == (GDTR_MIN | GDTR_MAX), "Expected %x, not %x(GDTR_MIN) or %x(GDTR_MAX), got %lx\n", (GDTR_MIN | GDTR_MAX), GDTR_MIN, GDTR_MAX, r);
395 expect_systime(&st[0], &getSt[0]);
396 expect_systime(&st[1], &getSt[1]);
398 /* set st[0] to value higher than minimum */
399 fill_systime_struct(&st[0], 1980, 1, 3, 23, 14, 34, 37, 465);
400 /* set st[1] to value lower than maximum */
401 fill_systime_struct(&st[1], 2007, 3, 2, 31, 23, 59, 59, 999);
403 r = SendMessage(hWnd, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st);
404 expect(1, r);
405 r = SendMessage(hWnd, DTM_GETRANGE, 0, (LPARAM)getSt);
406 ok(r == (GDTR_MIN | GDTR_MAX), "Expected %x, not %x(GDTR_MIN) or %x(GDTR_MAX), got %lx\n", (GDTR_MIN | GDTR_MAX), GDTR_MIN, GDTR_MAX, r);
407 expect_systime(&st[0], &getSt[0]);
408 expect_systime(&st[1], &getSt[1]);
410 ok_sequence(sequences, DATETIME_SEQ_INDEX, test_dtm_set_and_get_range_seq, "test_dtm_set_and_get_range", FALSE);
412 DestroyWindow(hWnd);
415 /* when max<min for DTM_SETRANGE, Windows seems to swap the min and max values,
416 although that's undocumented. However, it doesn't seem to be implemented
417 correctly, causing some strange side effects */
418 static void test_dtm_set_range_swap_min_max(void)
420 LRESULT r;
421 SYSTEMTIME st[2];
422 SYSTEMTIME getSt[2];
423 SYSTEMTIME origSt;
424 HWND hWnd;
426 hWnd = create_datetime_control(DTS_SHOWNONE, 0);
427 flush_sequences(sequences, NUM_MSG_SEQUENCES);
429 fill_systime_struct(&st[0], 2007, 2, 4, 15, 2, 2, 2, 2);
431 r = SendMessage(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st[0]);
432 expect(1, r);
433 r = SendMessage(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&origSt);
434 ok(r == GDT_VALID, "Expected %d, not %d(GDT_NONE) or %d(GDT_ERROR), got %ld\n", GDT_VALID, GDT_NONE, GDT_ERROR, r);
435 expect_systime(&st[0], &origSt);
437 /* set st[0] to value higher than st[1] */
438 fill_systime_struct(&st[0], 2007, 3, 2, 31, 23, 59, 59, 999);
439 fill_systime_struct(&st[1], 1980, 1, 3, 23, 14, 34, 37, 465);
441 /* since min>max, min and max values should be swapped by DTM_SETRANGE
442 automatically */
443 r = SendMessage(hWnd, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st);
444 expect(1, r);
445 r = SendMessage(hWnd, DTM_GETRANGE, 0, (LPARAM)getSt);
446 ok(r == (GDTR_MIN | GDTR_MAX), "Expected %x, not %x(GDTR_MIN) or %x(GDTR_MAX), got %lx\n", (GDTR_MIN | GDTR_MAX), GDTR_MIN, GDTR_MAX, r);
447 todo_wine {
448 ok(compare_systime(&st[0], &getSt[0]) == 1 ||
449 broken(compare_systime(&st[0], &getSt[1]) == 1), /* comctl32 version <= 5.80 */
450 "ST1 != ST2\n");
452 ok(compare_systime(&st[1], &getSt[1]) == 1 ||
453 broken(compare_systime(&st[1], &getSt[0]) == 1), /* comctl32 version <= 5.80 */
454 "ST1 != ST2\n");
457 fill_systime_struct(&st[0], 1980, 1, 3, 23, 14, 34, 37, 465);
459 r = SendMessage(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st[0]);
460 expect(1, r);
461 r = SendMessage(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt[0]);
462 ok(r == GDT_VALID, "Expected %d, not %d(GDT_NONE) or %d(GDT_ERROR), got %ld\n", GDT_VALID, GDT_NONE, GDT_ERROR, r);
463 /* the time part seems to not change after swapping the min and max values
464 and doing DTM_SETSYSTEMTIME */
465 expect_systime_date(&st[0], &getSt[0]);
466 todo_wine {
467 ok(compare_systime_time(&origSt, &getSt[0]) == 1 ||
468 broken(compare_systime_time(&st[0], &getSt[0]) == 1), /* comctl32 version <= 5.80 */
469 "ST1.time != ST2.time\n");
472 /* set st[0] to value higher than minimum */
473 fill_systime_struct(&st[0], 1980, 1, 3, 23, 14, 34, 37, 465);
474 /* set st[1] to value lower than maximum */
475 fill_systime_struct(&st[1], 2007, 3, 2, 31, 23, 59, 59, 999);
477 r = SendMessage(hWnd, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st);
478 expect(1, r);
479 /* for some reason after we swapped the min and max values before,
480 whenever we do a DTM_SETRANGE, the DTM_GETRANGE will return the values
481 swapped*/
482 r = SendMessage(hWnd, DTM_GETRANGE, 0, (LPARAM)getSt);
483 ok(r == (GDTR_MIN | GDTR_MAX), "Expected %x, not %x(GDTR_MIN) or %x(GDTR_MAX), got %lx\n", (GDTR_MIN | GDTR_MAX), GDTR_MIN, GDTR_MAX, r);
484 todo_wine {
485 ok(compare_systime(&st[0], &getSt[1]) == 1 ||
486 broken(compare_systime(&st[0], &getSt[0]) == 1), /* comctl32 version <= 5.80 */
487 "ST1 != ST2\n");
489 ok(compare_systime(&st[1], &getSt[0]) == 1 ||
490 broken(compare_systime(&st[1], &getSt[1]) == 1), /* comctl32 version <= 5.80 */
491 "ST1 != ST2\n");
494 /* set st[0] to value higher than st[1] */
495 fill_systime_struct(&st[0], 2007, 3, 2, 31, 23, 59, 59, 999);
496 fill_systime_struct(&st[1], 1980, 1, 3, 23, 14, 34, 37, 465);
498 /* set min>max again, so that the return values of DTM_GETRANGE are no
499 longer swapped the next time we do a DTM SETRANGE and DTM_GETRANGE*/
500 r = SendMessage(hWnd, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st);
501 expect(1, r);
502 r = SendMessage(hWnd, DTM_GETRANGE, 0, (LPARAM)getSt);
503 ok(r == (GDTR_MIN | GDTR_MAX), "Expected %x, not %x(GDTR_MIN) or %x(GDTR_MAX), got %lx\n", (GDTR_MIN | GDTR_MAX), GDTR_MIN, GDTR_MAX, r);
504 expect_systime(&st[0], &getSt[1]);
505 expect_systime(&st[1], &getSt[0]);
507 /* initialize st[0] to lowest possible value */
508 fill_systime_struct(&st[0], 1601, 1, 0, 1, 0, 0, 0, 0);
509 /* set st[1] to highest possible value */
510 fill_systime_struct(&st[1], 30827, 12, 6, 31, 23, 59, 59, 999);
512 r = SendMessage(hWnd, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st);
513 expect(1, r);
514 r = SendMessage(hWnd, DTM_GETRANGE, 0, (LPARAM)getSt);
515 ok(r == (GDTR_MIN | GDTR_MAX), "Expected %x, not %x(GDTR_MIN) or %x(GDTR_MAX), got %lx\n", (GDTR_MIN | GDTR_MAX), GDTR_MIN, GDTR_MAX, r);
516 expect_systime(&st[0], &getSt[0]);
517 expect_systime(&st[1], &getSt[1]);
519 ok_sequence(sequences, DATETIME_SEQ_INDEX, test_dtm_set_range_swap_min_max_seq, "test_dtm_set_range_swap_min_max", FALSE);
521 DestroyWindow(hWnd);
524 static void test_dtm_set_and_get_system_time(void)
526 LRESULT r;
527 SYSTEMTIME st, getSt;
528 HWND hWnd, hWndDateTime_test_gdt_none;
530 hWndDateTime_test_gdt_none = create_datetime_control(0, 0);
532 ok(hWndDateTime_test_gdt_none!=NULL, "Expected non NULL, got %p\n", hWndDateTime_test_gdt_none);
533 if(hWndDateTime_test_gdt_none) {
534 r = SendMessage(hWndDateTime_test_gdt_none, DTM_SETSYSTEMTIME, GDT_NONE, (LPARAM)&st);
535 expect(0, r);
537 else {
538 skip("hWndDateTime_test_gdt_none is NULL\n");
539 flush_sequences(sequences, NUM_MSG_SEQUENCES);
541 return;
544 DestroyWindow(hWndDateTime_test_gdt_none);
546 hWnd = create_datetime_control(DTS_SHOWNONE, 0);
547 flush_sequences(sequences, NUM_MSG_SEQUENCES);
549 r = SendMessage(hWnd, DTM_SETSYSTEMTIME, GDT_NONE, (LPARAM)&st);
550 expect(1, r);
551 r = SendMessage(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt);
552 ok(r == GDT_NONE, "Expected %d, not %d(GDT_VALID) or %d(GDT_ERROR), got %ld\n", GDT_NONE, GDT_VALID, GDT_ERROR, r);
554 /* set st to lowest possible value */
555 fill_systime_struct(&st, 1601, 1, 0, 1, 0, 0, 0, 0);
557 r = SendMessage(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st);
558 expect(1, r);
560 /* set st to highest possible value */
561 fill_systime_struct(&st, 30827, 12, 6, 31, 23, 59, 59, 999);
563 r = SendMessage(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st);
564 expect(1, r);
566 /* set st to value between min and max */
567 fill_systime_struct(&st, 1980, 1, 3, 23, 14, 34, 37, 465);
569 r = SendMessage(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st);
570 expect(1, r);
571 r = SendMessage(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt);
572 ok(r == GDT_VALID, "Expected %d, not %d(GDT_NONE) or %d(GDT_ERROR), got %ld\n", GDT_VALID, GDT_NONE, GDT_ERROR, r);
573 expect_systime(&st, &getSt);
575 /* set st to invalid value */
576 fill_systime_struct(&st, 0, 0, 7, 0, 24, 60, 60, 1000);
578 r = SendMessage(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st);
579 expect_unsuccess(0, r);
581 ok_sequence(sequences, DATETIME_SEQ_INDEX, test_dtm_set_and_get_system_time_seq, "test_dtm_set_and_get_system_time", FALSE);
582 DestroyWindow(hWnd);
585 START_TEST(datetime)
587 HMODULE hComctl32;
588 BOOL (WINAPI *pInitCommonControlsEx)(const INITCOMMONCONTROLSEX*);
589 INITCOMMONCONTROLSEX iccex;
591 hComctl32 = GetModuleHandleA("comctl32.dll");
592 pInitCommonControlsEx = (void*)GetProcAddress(hComctl32, "InitCommonControlsEx");
593 if (!pInitCommonControlsEx)
595 skip("InitCommonControlsEx() is missing. Skipping the tests\n");
596 return;
598 iccex.dwSize = sizeof(iccex);
599 iccex.dwICC = ICC_DATE_CLASSES;
600 pInitCommonControlsEx(&iccex);
602 init_msg_sequences(sequences, NUM_MSG_SEQUENCES);
604 test_dtm_set_format();
605 test_dtm_set_and_get_mccolor();
606 test_dtm_set_and_get_mcfont();
607 test_dtm_get_monthcal();
608 test_dtm_set_and_get_range();
609 test_dtm_set_range_swap_min_max();
610 test_dtm_set_and_get_system_time();