TESTING -- override pthreads to fix gstreamer v5
[wine/multimedia.git] / dlls / comctl32 / tests / datetime.c
blob195c7193c7fe3fcc5fa2bc5467e7d5498e6898fe
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 static const struct message test_dtm_set_and_get_systime_with_limits[] = {
125 { DTM_SETRANGE, sent|wparam, GDTR_MIN | GDTR_MAX },
126 { DTM_GETRANGE, sent|wparam, 0 },
127 { DTM_SETSYSTEMTIME, sent|wparam, 0 },
128 { DTM_GETSYSTEMTIME, sent|wparam, 0 },
129 { DTM_SETSYSTEMTIME, sent|wparam, 0 },
130 { DTM_GETSYSTEMTIME, sent|wparam, 0 },
131 { DTM_SETSYSTEMTIME, sent|wparam, 0 },
132 { DTM_GETSYSTEMTIME, sent|wparam, 0 },
133 { 0 }
136 static LRESULT WINAPI datetime_subclass_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
138 WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA);
139 static LONG defwndproc_counter = 0;
140 LRESULT ret;
141 struct message msg;
143 msg.message = message;
144 msg.flags = sent|wparam|lparam;
145 if (defwndproc_counter) msg.flags |= defwinproc;
146 msg.wParam = wParam;
147 msg.lParam = lParam;
148 msg.id = 0;
149 add_message(sequences, DATETIME_SEQ_INDEX, &msg);
151 defwndproc_counter++;
152 ret = CallWindowProcA(oldproc, hwnd, message, wParam, lParam);
153 defwndproc_counter--;
155 return ret;
158 static HWND create_datetime_control(DWORD style)
160 WNDPROC oldproc;
161 HWND hWndDateTime = NULL;
163 hWndDateTime = CreateWindowExA(0,
164 DATETIMEPICK_CLASSA,
165 NULL,
166 style,
167 0,50,300,120,
168 NULL,
169 NULL,
170 NULL,
171 NULL);
173 if (!hWndDateTime) return NULL;
175 oldproc = (WNDPROC)SetWindowLongPtrA(hWndDateTime, GWLP_WNDPROC,
176 (LONG_PTR)datetime_subclass_proc);
177 SetWindowLongPtrA(hWndDateTime, GWLP_USERDATA, (LONG_PTR)oldproc);
179 return hWndDateTime;
182 static void test_dtm_set_format(void)
184 HWND hWnd;
185 CHAR txt[256];
186 SYSTEMTIME systime;
187 LRESULT r;
189 hWnd = create_datetime_control(DTS_SHOWNONE);
191 flush_sequences(sequences, NUM_MSG_SEQUENCES);
193 r = SendMessageA(hWnd, DTM_SETFORMATA, 0, 0);
194 expect(1, r);
196 r = SendMessageA(hWnd, DTM_SETFORMATA, 0,
197 (LPARAM)"'Today is: 'hh':'m':'s dddd MMM dd', 'yyyy");
198 expect(1, r);
200 ok_sequence(sequences, DATETIME_SEQ_INDEX, test_dtm_set_format_seq, "test_dtm_set_format", FALSE);
202 r = SendMessageA(hWnd, DTM_SETFORMATA, 0, (LPARAM)"'hh' hh");
203 expect(1, r);
204 ZeroMemory(&systime, sizeof(systime));
205 systime.wYear = 2000;
206 systime.wMonth = systime.wDay = 1;
207 r = SendMessageA(hWnd, DTM_SETSYSTEMTIME, 0, (LPARAM)&systime);
208 expect(1, r);
209 GetWindowTextA(hWnd, txt, 256);
210 ok(strcmp(txt, "hh 12") == 0, "String mismatch (\"%s\" vs \"hh 12\")\n", txt);
212 DestroyWindow(hWnd);
215 static void test_mccolor_types(HWND hWndDateTime, int mccolor_type, const char* mccolor_name)
217 COLORREF theColor, prevColor, crColor;
219 theColor=RGB(0,0,0);
220 crColor = SendMessageA(hWndDateTime, DTM_SETMCCOLOR, mccolor_type, theColor);
221 ok(crColor != ~0u, "%s: Set RGB(0,0,0): Expected COLORREF of previous value, got %d\n", mccolor_name, crColor);
222 prevColor=theColor;
223 theColor=RGB(255,255,255);
224 crColor = SendMessageA(hWndDateTime, DTM_SETMCCOLOR, mccolor_type, theColor);
225 ok(crColor==prevColor, "%s: Set RGB(255,255,255): Expected COLORREF of previous value, got %d\n", mccolor_name, crColor);
226 prevColor=theColor;
227 theColor=RGB(100,180,220);
228 crColor = SendMessageA(hWndDateTime, DTM_SETMCCOLOR, mccolor_type, theColor);
229 ok(crColor==prevColor, "%s: Set RGB(100,180,220): Expected COLORREF of previous value, got %d\n", mccolor_name, crColor);
230 crColor = SendMessageA(hWndDateTime, DTM_GETMCCOLOR, mccolor_type, 0);
231 ok(crColor==theColor, "%s: GETMCCOLOR: Expected %d, got %d\n", mccolor_name, theColor, crColor);
234 static void test_dtm_set_and_get_mccolor(void)
236 HWND hWnd;
238 hWnd = create_datetime_control(DTS_SHOWNONE);
240 flush_sequences(sequences, NUM_MSG_SEQUENCES);
242 test_mccolor_types(hWnd, MCSC_BACKGROUND, "MCSC_BACKGROUND");
243 test_mccolor_types(hWnd, MCSC_MONTHBK, "MCSC_MONTHBK");
244 test_mccolor_types(hWnd, MCSC_TEXT, "MCSC_TEXT");
245 test_mccolor_types(hWnd, MCSC_TITLEBK, "MCSC_TITLEBK");
246 test_mccolor_types(hWnd, MCSC_TITLETEXT, "MCSC_TITLETEXT");
247 test_mccolor_types(hWnd, MCSC_TRAILINGTEXT, "MCSC_TRAILINGTEXT");
249 ok_sequence(sequences, DATETIME_SEQ_INDEX, test_dtm_set_and_get_mccolor_seq, "test_dtm_set_and_get_mccolor", FALSE);
251 DestroyWindow(hWnd);
254 static void test_dtm_set_and_get_mcfont(void)
256 HFONT hFontOrig, hFontNew;
257 HWND hWnd;
259 hWnd = create_datetime_control(DTS_SHOWNONE);
261 flush_sequences(sequences, NUM_MSG_SEQUENCES);
263 hFontOrig = GetStockObject(DEFAULT_GUI_FONT);
264 SendMessageA(hWnd, DTM_SETMCFONT, (WPARAM)hFontOrig, TRUE);
265 hFontNew = (HFONT)SendMessageA(hWnd, DTM_GETMCFONT, 0, 0);
266 ok(hFontOrig == hFontNew, "Expected hFontOrig==hFontNew, hFontOrig=%p, hFontNew=%p\n", hFontOrig, hFontNew);
268 ok_sequence(sequences, DATETIME_SEQ_INDEX, test_dtm_set_and_get_mcfont_seq, "test_dtm_set_and_get_mcfont", FALSE);
269 DestroyWindow(hWnd);
272 static void test_dtm_get_monthcal(void)
274 LRESULT r;
275 HWND hWnd;
277 hWnd = create_datetime_control(DTS_SHOWNONE);
279 flush_sequences(sequences, NUM_MSG_SEQUENCES);
281 todo_wine {
282 r = SendMessageA(hWnd, DTM_GETMONTHCAL, 0, 0);
283 ok(r == 0, "Expected NULL(no child month calendar control), got %ld\n", r);
286 ok_sequence(sequences, DATETIME_SEQ_INDEX, test_dtm_get_monthcal_seq, "test_dtm_get_monthcal", FALSE);
287 DestroyWindow(hWnd);
290 static void fill_systime_struct(SYSTEMTIME *st, int year, int month, int dayofweek, int day, int hour, int minute, int second, int milliseconds)
292 st->wYear = year;
293 st->wMonth = month;
294 st->wDayOfWeek = dayofweek;
295 st->wDay = day;
296 st->wHour = hour;
297 st->wMinute = minute;
298 st->wSecond = second;
299 st->wMilliseconds = milliseconds;
302 static LPARAM compare_systime_date(SYSTEMTIME *st1, SYSTEMTIME *st2)
304 return (st1->wYear == st2->wYear)
305 && (st1->wMonth == st2->wMonth)
306 && (st1->wDayOfWeek == st2->wDayOfWeek)
307 && (st1->wDay == st2->wDay);
310 static LPARAM compare_systime_time(SYSTEMTIME *st1, SYSTEMTIME *st2)
312 return (st1->wHour == st2->wHour)
313 && (st1->wMinute == st2->wMinute)
314 && (st1->wSecond == st2->wSecond)
315 && (st1->wMilliseconds == st2->wMilliseconds);
318 static LPARAM compare_systime(SYSTEMTIME *st1, SYSTEMTIME *st2)
320 if(!compare_systime_date(st1, st2))
321 return 0;
323 return compare_systime_time(st1, st2);
326 #define expect_systime(ST1, ST2) ok(compare_systime((ST1), (ST2))==1, "ST1 != ST2\n")
327 #define expect_systime_date(ST1, ST2) ok(compare_systime_date((ST1), (ST2))==1, "ST1.date != ST2.date\n")
328 #define expect_systime_time(ST1, ST2) ok(compare_systime_time((ST1), (ST2))==1, "ST1.time != ST2.time\n")
330 static void test_dtm_set_and_get_range(void)
332 LRESULT r;
333 SYSTEMTIME st[2];
334 SYSTEMTIME getSt[2];
335 HWND hWnd;
337 hWnd = create_datetime_control(DTS_SHOWNONE);
339 flush_sequences(sequences, NUM_MSG_SEQUENCES);
341 /* initialize st[0] to lowest possible value */
342 fill_systime_struct(&st[0], 1601, 1, 0, 1, 0, 0, 0, 0);
343 /* initialize st[1] to all invalid numbers */
344 fill_systime_struct(&st[1], 0, 0, 7, 0, 24, 60, 60, 1000);
346 r = SendMessageA(hWnd, DTM_SETRANGE, GDTR_MIN, (LPARAM)st);
347 expect(1, r);
348 r = SendMessageA(hWnd, DTM_GETRANGE, 0, (LPARAM)getSt);
349 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);
350 expect_systime(&st[0], &getSt[0]);
352 r = SendMessageA(hWnd, DTM_SETRANGE, GDTR_MAX, (LPARAM)st);
353 expect_unsuccess(0, r);
355 /* set st[0] to all invalid numbers */
356 fill_systime_struct(&st[0], 0, 0, 7, 0, 24, 60, 60, 1000);
357 /* set st[1] to highest possible value */
358 fill_systime_struct(&st[1], 30827, 12, 6, 31, 23, 59, 59, 999);
360 r = SendMessageA(hWnd, DTM_SETRANGE, GDTR_MAX, (LPARAM)st);
361 expect(1, r);
362 r = SendMessageA(hWnd, DTM_GETRANGE, 0, (LPARAM)getSt);
363 todo_wine {
364 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);
366 expect_systime(&st[1], &getSt[1]);
368 r = SendMessageA(hWnd, DTM_SETRANGE, GDTR_MIN, (LPARAM)st);
369 expect_unsuccess(0, r);
370 r = SendMessageA(hWnd, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st);
371 expect_unsuccess(0, r);
373 /* set st[0] to highest possible value */
374 fill_systime_struct(&st[0], 30827, 12, 6, 31, 23, 59, 59, 999);
376 r = SendMessageA(hWnd, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st);
377 expect(1, r);
378 r = SendMessageA(hWnd, DTM_GETRANGE, 0, (LPARAM)getSt);
379 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);
380 expect_systime(&st[0], &getSt[0]);
381 expect_systime(&st[1], &getSt[1]);
383 /* initialize st[0] to lowest possible value */
384 fill_systime_struct(&st[0], 1601, 1, 0, 1, 0, 0, 0, 0);
385 /* set st[1] to highest possible value */
386 fill_systime_struct(&st[1], 30827, 12, 6, 31, 23, 59, 59, 999);
388 r = SendMessageA(hWnd, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st);
389 expect(1, r);
390 r = SendMessageA(hWnd, DTM_GETRANGE, 0, (LPARAM)getSt);
391 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);
392 expect_systime(&st[0], &getSt[0]);
393 expect_systime(&st[1], &getSt[1]);
395 /* set st[0] to value higher than minimum */
396 fill_systime_struct(&st[0], 1980, 1, 3, 23, 14, 34, 37, 465);
397 /* set st[1] to value lower than maximum */
398 fill_systime_struct(&st[1], 2007, 3, 2, 31, 23, 59, 59, 999);
400 r = SendMessageA(hWnd, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st);
401 expect(1, r);
402 r = SendMessageA(hWnd, DTM_GETRANGE, 0, (LPARAM)getSt);
403 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);
404 expect_systime(&st[0], &getSt[0]);
405 expect_systime(&st[1], &getSt[1]);
407 ok_sequence(sequences, DATETIME_SEQ_INDEX, test_dtm_set_and_get_range_seq, "test_dtm_set_and_get_range", FALSE);
409 DestroyWindow(hWnd);
412 /* when max<min for DTM_SETRANGE, Windows seems to swap the min and max values,
413 although that's undocumented. However, it doesn't seem to be implemented
414 correctly, causing some strange side effects */
415 static void test_dtm_set_range_swap_min_max(void)
417 LRESULT r;
418 SYSTEMTIME st[2];
419 SYSTEMTIME getSt[2];
420 SYSTEMTIME origSt;
421 HWND hWnd;
423 hWnd = create_datetime_control(DTS_SHOWNONE);
424 flush_sequences(sequences, NUM_MSG_SEQUENCES);
426 fill_systime_struct(&st[0], 2007, 2, 4, 15, 2, 2, 2, 2);
428 r = SendMessageA(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st[0]);
429 expect(1, r);
430 r = SendMessageA(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&origSt);
431 ok(r == GDT_VALID, "Expected %d, not %d(GDT_NONE) or %d(GDT_ERROR), got %ld\n", GDT_VALID, GDT_NONE, GDT_ERROR, r);
432 expect_systime(&st[0], &origSt);
434 /* set st[0] to value higher than st[1] */
435 fill_systime_struct(&st[0], 2007, 3, 2, 31, 23, 59, 59, 999);
436 fill_systime_struct(&st[1], 1980, 1, 3, 23, 14, 34, 37, 465);
438 /* since min>max, min and max values should be swapped by DTM_SETRANGE
439 automatically */
440 r = SendMessageA(hWnd, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st);
441 expect(1, r);
442 r = SendMessageA(hWnd, DTM_GETRANGE, 0, (LPARAM)getSt);
443 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);
444 todo_wine {
445 ok(compare_systime(&st[0], &getSt[0]) == 1 ||
446 broken(compare_systime(&st[0], &getSt[1]) == 1), /* comctl32 version <= 5.80 */
447 "ST1 != ST2\n");
449 ok(compare_systime(&st[1], &getSt[1]) == 1 ||
450 broken(compare_systime(&st[1], &getSt[0]) == 1), /* comctl32 version <= 5.80 */
451 "ST1 != ST2\n");
454 fill_systime_struct(&st[0], 1980, 1, 3, 23, 14, 34, 37, 465);
456 r = SendMessageA(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st[0]);
457 expect(1, r);
458 r = SendMessageA(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt[0]);
459 ok(r == GDT_VALID, "Expected %d, not %d(GDT_NONE) or %d(GDT_ERROR), got %ld\n", GDT_VALID, GDT_NONE, GDT_ERROR, r);
460 /* the time part seems to not change after swapping the min and max values
461 and doing DTM_SETSYSTEMTIME */
462 expect_systime_date(&st[0], &getSt[0]);
463 todo_wine {
464 ok(compare_systime_time(&origSt, &getSt[0]) == 1 ||
465 broken(compare_systime_time(&st[0], &getSt[0]) == 1), /* comctl32 version <= 5.80 */
466 "ST1.time != ST2.time\n");
469 /* set st[0] to value higher than minimum */
470 fill_systime_struct(&st[0], 1980, 1, 3, 23, 14, 34, 37, 465);
471 /* set st[1] to value lower than maximum */
472 fill_systime_struct(&st[1], 2007, 3, 2, 31, 23, 59, 59, 999);
474 r = SendMessageA(hWnd, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st);
475 expect(1, r);
476 /* for some reason after we swapped the min and max values before,
477 whenever we do a DTM_SETRANGE, the DTM_GETRANGE will return the values
478 swapped*/
479 r = SendMessageA(hWnd, DTM_GETRANGE, 0, (LPARAM)getSt);
480 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);
481 todo_wine {
482 ok(compare_systime(&st[0], &getSt[1]) == 1 ||
483 broken(compare_systime(&st[0], &getSt[0]) == 1), /* comctl32 version <= 5.80 */
484 "ST1 != ST2\n");
486 ok(compare_systime(&st[1], &getSt[0]) == 1 ||
487 broken(compare_systime(&st[1], &getSt[1]) == 1), /* comctl32 version <= 5.80 */
488 "ST1 != ST2\n");
491 /* set st[0] to value higher than st[1] */
492 fill_systime_struct(&st[0], 2007, 3, 2, 31, 23, 59, 59, 999);
493 fill_systime_struct(&st[1], 1980, 1, 3, 23, 14, 34, 37, 465);
495 /* set min>max again, so that the return values of DTM_GETRANGE are no
496 longer swapped the next time we do a DTM SETRANGE and DTM_GETRANGE*/
497 r = SendMessageA(hWnd, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st);
498 expect(1, r);
499 r = SendMessageA(hWnd, DTM_GETRANGE, 0, (LPARAM)getSt);
500 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);
501 expect_systime(&st[0], &getSt[1]);
502 expect_systime(&st[1], &getSt[0]);
504 /* initialize st[0] to lowest possible value */
505 fill_systime_struct(&st[0], 1601, 1, 0, 1, 0, 0, 0, 0);
506 /* set st[1] to highest possible value */
507 fill_systime_struct(&st[1], 30827, 12, 6, 31, 23, 59, 59, 999);
509 r = SendMessageA(hWnd, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st);
510 expect(1, r);
511 r = SendMessageA(hWnd, DTM_GETRANGE, 0, (LPARAM)getSt);
512 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);
513 expect_systime(&st[0], &getSt[0]);
514 expect_systime(&st[1], &getSt[1]);
516 ok_sequence(sequences, DATETIME_SEQ_INDEX, test_dtm_set_range_swap_min_max_seq, "test_dtm_set_range_swap_min_max", FALSE);
518 DestroyWindow(hWnd);
521 static void test_dtm_set_and_get_system_time(void)
523 LRESULT r;
524 SYSTEMTIME st, getSt, ref;
525 HWND hWnd, hWndDateTime_test_gdt_none;
527 hWndDateTime_test_gdt_none = create_datetime_control(0);
529 ok(hWndDateTime_test_gdt_none!=NULL, "Expected non NULL, got %p\n", hWndDateTime_test_gdt_none);
530 if(hWndDateTime_test_gdt_none) {
531 r = SendMessageA(hWndDateTime_test_gdt_none, DTM_SETSYSTEMTIME, GDT_NONE, (LPARAM)&st);
532 expect(0, r);
534 else {
535 skip("hWndDateTime_test_gdt_none is NULL\n");
536 flush_sequences(sequences, NUM_MSG_SEQUENCES);
538 return;
541 DestroyWindow(hWndDateTime_test_gdt_none);
543 hWnd = create_datetime_control(DTS_SHOWNONE);
544 flush_sequences(sequences, NUM_MSG_SEQUENCES);
546 r = SendMessageA(hWnd, DTM_SETSYSTEMTIME, GDT_NONE, (LPARAM)&st);
547 expect(1, r);
548 r = SendMessageA(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt);
549 ok(r == GDT_NONE, "Expected %d, not %d(GDT_VALID) or %d(GDT_ERROR), got %ld\n", GDT_NONE, GDT_VALID, GDT_ERROR, r);
551 /* set st to lowest possible value */
552 fill_systime_struct(&st, 1601, 1, 0, 1, 0, 0, 0, 0);
554 r = SendMessageA(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st);
555 expect(1, r);
557 /* set st to highest possible value */
558 fill_systime_struct(&st, 30827, 12, 6, 31, 23, 59, 59, 999);
560 r = SendMessageA(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st);
561 expect(1, r);
563 /* set st to value between min and max */
564 fill_systime_struct(&st, 1980, 1, 3, 23, 14, 34, 37, 465);
566 r = SendMessageA(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st);
567 expect(1, r);
568 r = SendMessageA(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt);
569 ok(r == GDT_VALID, "Expected %d, not %d(GDT_NONE) or %d(GDT_ERROR), got %ld\n", GDT_VALID, GDT_NONE, GDT_ERROR, r);
570 expect_systime(&st, &getSt);
572 /* set st to invalid value */
573 fill_systime_struct(&st, 0, 0, 7, 0, 24, 60, 60, 1000);
575 r = SendMessageA(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st);
576 expect_unsuccess(0, r);
578 ok_sequence(sequences, DATETIME_SEQ_INDEX, test_dtm_set_and_get_system_time_seq, "test_dtm_set_and_get_system_time", FALSE);
580 /* set to some valid value */
581 GetSystemTime(&ref);
582 r = SendMessageA(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&ref);
583 expect(1, r);
584 r = SendMessageA(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt);
585 expect(GDT_VALID, r);
586 expect_systime(&ref, &getSt);
588 /* year invalid */
589 st = ref;
590 st.wYear = 0;
591 r = SendMessageA(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st);
592 todo_wine expect(1, r);
593 r = SendMessageA(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt);
594 expect(GDT_VALID, r);
595 expect_systime(&ref, &getSt);
596 /* month invalid */
597 st = ref;
598 st.wMonth = 13;
599 r = SendMessageA(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st);
600 expect(0, r);
601 r = SendMessageA(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt);
602 expect(GDT_VALID, r);
603 expect_systime(&ref, &getSt);
604 /* day invalid */
605 st = ref;
606 st.wDay = 32;
607 r = SendMessageA(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st);
608 expect(0, r);
609 r = SendMessageA(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt);
610 expect(GDT_VALID, r);
611 expect_systime(&ref, &getSt);
612 /* day invalid for current month */
613 st = ref;
614 st.wDay = 30;
615 st.wMonth = 2;
616 r = SendMessageA(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st);
617 expect(0, r);
618 r = SendMessageA(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt);
619 expect(GDT_VALID, r);
620 expect_systime(&ref, &getSt);
621 /* day of week isn't validated */
622 st = ref;
623 st.wDayOfWeek = 10;
624 r = SendMessageA(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st);
625 expect(1, r);
626 r = SendMessageA(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt);
627 expect(GDT_VALID, r);
628 expect_systime(&ref, &getSt);
629 /* hour invalid */
630 st = ref;
631 st.wHour = 25;
632 r = SendMessageA(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st);
633 expect(0, r);
634 r = SendMessageA(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt);
635 expect(GDT_VALID, r);
636 expect_systime(&ref, &getSt);
637 /* minute invalid */
638 st = ref;
639 st.wMinute = 60;
640 r = SendMessageA(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st);
641 expect(0, r);
642 r = SendMessageA(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt);
643 expect(GDT_VALID, r);
644 expect_systime(&ref, &getSt);
645 /* sec invalid */
646 st = ref;
647 st.wSecond = 60;
648 r = SendMessageA(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st);
649 expect(0, r);
650 r = SendMessageA(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt);
651 expect(GDT_VALID, r);
652 expect_systime(&ref, &getSt);
653 /* msec invalid */
654 st = ref;
655 st.wMilliseconds = 1000;
656 r = SendMessageA(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st);
657 expect(0, r);
658 r = SendMessageA(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt);
659 expect(GDT_VALID, r);
660 expect_systime(&ref, &getSt);
662 /* day of week should be calculated automatically,
663 actual day of week for this date is 4 */
664 fill_systime_struct(&st, 2009, 10, 1, 1, 0, 0, 10, 200);
665 r = SendMessageA(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st);
666 expect(1, r);
667 r = SendMessageA(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt);
668 expect(GDT_VALID, r);
669 /* 01.10.2009 is Thursday */
670 expect(4, (LRESULT)getSt.wDayOfWeek);
671 st.wDayOfWeek = 4;
672 expect_systime(&st, &getSt);
675 static void test_dtm_set_and_get_systemtime_with_limits(void)
677 LRESULT r;
678 SYSTEMTIME st[2], getSt[2], refSt;
679 HWND hWnd;
681 hWnd = create_datetime_control(DTS_SHOWNONE);
683 flush_sequences(sequences, NUM_MSG_SEQUENCES);
685 /* set range */
686 fill_systime_struct(&st[0], 1980, 1, 3, 23, 14, 34, 37, 465);
687 fill_systime_struct(&st[1], 2007, 3, 2, 31, 23, 59, 59, 999);
689 r = SendMessageA(hWnd, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st);
690 expect(1, r);
691 r = SendMessageA(hWnd, DTM_GETRANGE, 0, (LPARAM)getSt);
692 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);
693 expect_systime(&st[0], &getSt[0]);
694 expect_systime(&st[1], &getSt[1]);
696 /* Initially set a valid time */
697 fill_systime_struct(&refSt, 1999, 9, 4, 9, 19, 9, 9, 999);
698 r = SendMessageA(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&refSt);
699 expect(1, r);
700 r = SendMessageA(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt[0]);
701 ok(r == GDT_VALID, "Expected %d, not %d(GDT_NONE) or %d(GDT_ERROR), got %ld\n", GDT_VALID, GDT_NONE, GDT_ERROR, r);
702 expect_systime(&refSt, &getSt[0]);
704 /* Now set an out-of-bounds time */
705 fill_systime_struct(&st[0], 2010, 1, 0, 1, 0, 0, 0, 0);
707 r = SendMessageA(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st[0]);
708 expect(1, r);
709 r = SendMessageA(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt[0]);
710 ok(r == GDT_VALID, "Expected %d, not %d(GDT_NONE) or %d(GDT_ERROR), got %ld\n", GDT_VALID, GDT_NONE, GDT_ERROR, r);
711 expect_systime(&refSt, &getSt[0]);
713 fill_systime_struct(&st[0], 1977, 1, 0, 1, 0, 0, 0, 0);
715 r = SendMessageA(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st[0]);
716 expect(1, r);
717 r = SendMessageA(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt[0]);
718 ok(r == GDT_VALID, "Expected %d, not %d(GDT_NONE) or %d(GDT_ERROR), got %ld\n", GDT_VALID, GDT_NONE, GDT_ERROR, r);
719 expect_systime(&refSt, &getSt[0]);
721 ok_sequence(sequences, DATETIME_SEQ_INDEX, test_dtm_set_and_get_systime_with_limits, "test_dtm_set_and_get_systime_with_limits", FALSE);
723 DestroyWindow(hWnd);
726 static void test_wm_set_get_text(void)
728 static const CHAR a_str[] = "a";
729 CHAR buff[16], time[16], caltype[3];
730 HWND hWnd;
731 LRESULT ret;
733 hWnd = create_datetime_control(0);
735 ret = SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)a_str);
736 ok(CB_ERR == ret ||
737 broken(0 == ret) || /* comctl32 <= 4.72 */
738 broken(1 == ret), /* comctl32 <= 4.70 */
739 "Expected CB_ERR, got %ld\n", ret);
741 buff[0] = 0;
742 ret = SendMessageA(hWnd, WM_GETTEXT, sizeof(buff), (LPARAM)buff);
743 ok(strcmp(buff, a_str) != 0, "Expected text to change, got %s\n", buff);
744 ok(ret != 0, "Expected non-zero return value\n");
746 SetLastError(0xdeadbeef);
747 ret = GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_ICALENDARTYPE, caltype, 3);
748 if (ret == 0)
749 skip("Must know local calendar type (%x)\n", GetLastError());
750 else if (atoi(caltype) != CAL_GREGORIAN)
751 skip("DateTimePicker Control only supports Gregorian calendar (type: %s)\n", caltype);
752 else {
753 SetLastError(0xdeadbeef);
754 ret = GetDateFormatA(LOCALE_USER_DEFAULT, 0, NULL, NULL, time, sizeof(time));
755 if (ret == 0)
756 skip("GetDateFormat failed, returned %ld, error %d\n", ret, GetLastError());
757 else
758 ok(!strcmp(buff, time), "Expected %s, got %s\n", time, buff);
761 DestroyWindow(hWnd);
764 static void test_dts_shownone(void)
766 HWND hwnd;
767 DWORD style;
769 /* it isn't allowed to change DTS_SHOWNONE after creation */
770 hwnd = create_datetime_control(0);
771 style = GetWindowLongA(hwnd, GWL_STYLE);
772 SetWindowLongA(hwnd, GWL_STYLE, style | DTS_SHOWNONE);
773 style = GetWindowLongA(hwnd, GWL_STYLE);
774 ok(!(style & DTS_SHOWNONE), "Expected DTS_SHOWNONE not to be set\n");
775 DestroyWindow(hwnd);
777 hwnd = create_datetime_control(DTS_SHOWNONE);
778 style = GetWindowLongA(hwnd, GWL_STYLE);
779 SetWindowLongA(hwnd, GWL_STYLE, style & ~DTS_SHOWNONE);
780 style = GetWindowLongA(hwnd, GWL_STYLE);
781 ok(style & DTS_SHOWNONE, "Expected DTS_SHOWNONE to be set\n");
782 DestroyWindow(hwnd);
785 START_TEST(datetime)
787 HMODULE hComctl32;
788 BOOL (WINAPI *pInitCommonControlsEx)(const INITCOMMONCONTROLSEX*);
789 INITCOMMONCONTROLSEX iccex;
791 hComctl32 = GetModuleHandleA("comctl32.dll");
792 pInitCommonControlsEx = (void*)GetProcAddress(hComctl32, "InitCommonControlsEx");
793 if (!pInitCommonControlsEx)
795 skip("InitCommonControlsEx() is missing. Skipping the tests\n");
796 return;
798 iccex.dwSize = sizeof(iccex);
799 iccex.dwICC = ICC_DATE_CLASSES;
800 pInitCommonControlsEx(&iccex);
802 init_msg_sequences(sequences, NUM_MSG_SEQUENCES);
804 test_dtm_set_format();
805 test_dtm_set_and_get_mccolor();
806 test_dtm_set_and_get_mcfont();
807 test_dtm_get_monthcal();
808 test_dtm_set_and_get_range();
809 test_dtm_set_range_swap_min_max();
810 test_dtm_set_and_get_system_time();
811 test_dtm_set_and_get_systemtime_with_limits();
812 test_wm_set_get_text();
813 test_dts_shownone();