push 5b1efc32b5a8acb1d5b5e60584746392dd0c436e
[wine/hacks.git] / dlls / comctl32 / tests / datetime.c
bloba97ab342daec2ab9e776d5dac4ad0b8207556a7c
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 LRESULT WINAPI datetime_subclass_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
126 WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA);
127 static LONG defwndproc_counter = 0;
128 LRESULT ret;
129 struct message msg;
131 trace("datetime: %p, %04x, %08lx, %08lx\n", hwnd, message, wParam, lParam);
133 msg.message = message;
134 msg.flags = sent|wparam|lparam;
135 if (defwndproc_counter) msg.flags |= defwinproc;
136 msg.wParam = wParam;
137 msg.lParam = lParam;
138 add_message(sequences, DATETIME_SEQ_INDEX, &msg);
140 defwndproc_counter++;
141 ret = CallWindowProcA(oldproc, hwnd, message, wParam, lParam);
142 defwndproc_counter--;
144 return ret;
147 static HWND create_datetime_control(DWORD style)
149 WNDPROC oldproc;
150 HWND hWndDateTime = NULL;
152 hWndDateTime = CreateWindowEx(0,
153 DATETIMEPICK_CLASS,
154 NULL,
155 style,
156 0,50,300,120,
157 NULL,
158 NULL,
159 NULL,
160 NULL);
162 if (!hWndDateTime) return NULL;
164 oldproc = (WNDPROC)SetWindowLongPtrA(hWndDateTime, GWLP_WNDPROC,
165 (LONG_PTR)datetime_subclass_proc);
166 SetWindowLongPtrA(hWndDateTime, GWLP_USERDATA, (LONG_PTR)oldproc);
168 return hWndDateTime;
171 static void test_dtm_set_format(void)
173 HWND hWnd;
174 CHAR txt[256];
175 SYSTEMTIME systime;
176 LRESULT r;
178 hWnd = create_datetime_control(DTS_SHOWNONE);
180 flush_sequences(sequences, NUM_MSG_SEQUENCES);
182 r = SendMessage(hWnd, DTM_SETFORMAT, 0, 0);
183 expect(1, r);
185 r = SendMessage(hWnd, DTM_SETFORMAT, 0,
186 (LPARAM)"'Today is: 'hh':'m':'s dddd MMM dd', 'yyyy");
187 expect(1, r);
189 ok_sequence(sequences, DATETIME_SEQ_INDEX, test_dtm_set_format_seq, "test_dtm_set_format", FALSE);
191 r = SendMessage(hWnd, DTM_SETFORMAT, 0,
192 (LPARAM)"'hh' hh");
193 expect(1, r);
194 ZeroMemory(&systime, sizeof(systime));
195 systime.wYear = 2000;
196 systime.wMonth = systime.wDay = 1;
197 r = SendMessage(hWnd, DTM_SETSYSTEMTIME, 0, (LPARAM)&systime);
198 expect(1, r);
199 GetWindowText(hWnd, txt, 256);
200 ok(strcmp(txt, "hh 12") == 0, "String mismatch (\"%s\" vs \"hh 12\")\n", txt);
202 DestroyWindow(hWnd);
205 static void test_mccolor_types(HWND hWndDateTime, int mccolor_type, const char* mccolor_name)
207 LRESULT r;
208 COLORREF theColor, prevColor;
210 theColor=RGB(0,0,0);
211 r = SendMessage(hWndDateTime, DTM_SETMCCOLOR, mccolor_type, theColor);
212 ok(r != -1, "%s: Set RGB(0,0,0): Expected COLORREF of previous value, got %ld\n", mccolor_name, r);
213 prevColor=theColor;
214 theColor=RGB(255,255,255);
215 r = SendMessage(hWndDateTime, DTM_SETMCCOLOR, mccolor_type, theColor);
216 ok(r==prevColor, "%s: Set RGB(255,255,255): Expected COLORREF of previous value, got %ld\n", mccolor_name, r);
217 prevColor=theColor;
218 theColor=RGB(100,180,220);
219 r = SendMessage(hWndDateTime, DTM_SETMCCOLOR, mccolor_type, theColor);
220 ok(r==prevColor, "%s: Set RGB(100,180,220): Expected COLORREF of previous value, got %ld\n", mccolor_name, r);
221 r = SendMessage(hWndDateTime, DTM_GETMCCOLOR, mccolor_type, 0);
222 ok(r==theColor, "%s: GETMCCOLOR: Expected %d, got %ld\n", mccolor_name, theColor, r);
225 static void test_dtm_set_and_get_mccolor(void)
227 HWND hWnd;
229 hWnd = create_datetime_control(DTS_SHOWNONE);
231 flush_sequences(sequences, NUM_MSG_SEQUENCES);
233 test_mccolor_types(hWnd, MCSC_BACKGROUND, "MCSC_BACKGROUND");
234 test_mccolor_types(hWnd, MCSC_MONTHBK, "MCSC_MONTHBK");
235 test_mccolor_types(hWnd, MCSC_TEXT, "MCSC_TEXT");
236 test_mccolor_types(hWnd, MCSC_TITLEBK, "MCSC_TITLEBK");
237 test_mccolor_types(hWnd, MCSC_TITLETEXT, "MCSC_TITLETEXT");
238 test_mccolor_types(hWnd, MCSC_TRAILINGTEXT, "MCSC_TRAILINGTEXT");
240 ok_sequence(sequences, DATETIME_SEQ_INDEX, test_dtm_set_and_get_mccolor_seq, "test_dtm_set_and_get_mccolor", FALSE);
242 DestroyWindow(hWnd);
245 static void test_dtm_set_and_get_mcfont(void)
247 HFONT hFontOrig, hFontNew;
248 HWND hWnd;
250 hWnd = create_datetime_control(DTS_SHOWNONE);
252 flush_sequences(sequences, NUM_MSG_SEQUENCES);
254 hFontOrig = GetStockObject(DEFAULT_GUI_FONT);
255 SendMessage(hWnd, DTM_SETMCFONT, (WPARAM)hFontOrig, TRUE);
256 hFontNew = (HFONT)SendMessage(hWnd, DTM_GETMCFONT, 0, 0);
257 ok(hFontOrig == hFontNew, "Expected hFontOrig==hFontNew, hFontOrig=%p, hFontNew=%p\n", hFontOrig, hFontNew);
259 ok_sequence(sequences, DATETIME_SEQ_INDEX, test_dtm_set_and_get_mcfont_seq, "test_dtm_set_and_get_mcfont", FALSE);
260 DestroyWindow(hWnd);
263 static void test_dtm_get_monthcal(void)
265 LRESULT r;
266 HWND hWnd;
268 hWnd = create_datetime_control(DTS_SHOWNONE);
270 flush_sequences(sequences, NUM_MSG_SEQUENCES);
272 todo_wine {
273 r = SendMessage(hWnd, DTM_GETMONTHCAL, 0, 0);
274 ok(r == 0, "Expected NULL(no child month calendar control), got %ld\n", r);
277 ok_sequence(sequences, DATETIME_SEQ_INDEX, test_dtm_get_monthcal_seq, "test_dtm_get_monthcal", FALSE);
278 DestroyWindow(hWnd);
281 static void fill_systime_struct(SYSTEMTIME *st, int year, int month, int dayofweek, int day, int hour, int minute, int second, int milliseconds)
283 st->wYear = year;
284 st->wMonth = month;
285 st->wDayOfWeek = dayofweek;
286 st->wDay = day;
287 st->wHour = hour;
288 st->wMinute = minute;
289 st->wSecond = second;
290 st->wMilliseconds = milliseconds;
293 static LPARAM compare_systime_date(SYSTEMTIME *st1, SYSTEMTIME *st2)
295 return (st1->wYear == st2->wYear)
296 && (st1->wMonth == st2->wMonth)
297 && (st1->wDayOfWeek == st2->wDayOfWeek)
298 && (st1->wDay == st2->wDay);
301 static LPARAM compare_systime_time(SYSTEMTIME *st1, SYSTEMTIME *st2)
303 return (st1->wHour == st2->wHour)
304 && (st1->wMinute == st2->wMinute)
305 && (st1->wSecond == st2->wSecond)
306 && (st1->wMilliseconds == st2->wMilliseconds);
309 static LPARAM compare_systime(SYSTEMTIME *st1, SYSTEMTIME *st2)
311 if(!compare_systime_date(st1, st2))
312 return 0;
314 return compare_systime_time(st1, st2);
317 #define expect_systime(ST1, ST2) ok(compare_systime((ST1), (ST2))==1, "ST1 != ST2\n")
318 #define expect_systime_date(ST1, ST2) ok(compare_systime_date((ST1), (ST2))==1, "ST1.date != ST2.date\n")
319 #define expect_systime_time(ST1, ST2) ok(compare_systime_time((ST1), (ST2))==1, "ST1.time != ST2.time\n")
321 static void test_dtm_set_and_get_range(void)
323 LRESULT r;
324 SYSTEMTIME st[2];
325 SYSTEMTIME getSt[2];
326 HWND hWnd;
328 hWnd = create_datetime_control(DTS_SHOWNONE);
330 flush_sequences(sequences, NUM_MSG_SEQUENCES);
332 /* initialize st[0] to lowest possible value */
333 fill_systime_struct(&st[0], 1601, 1, 0, 1, 0, 0, 0, 0);
334 /* initialize st[1] to all invalid numbers */
335 fill_systime_struct(&st[1], 0, 0, 7, 0, 24, 60, 60, 1000);
337 r = SendMessage(hWnd, DTM_SETRANGE, GDTR_MIN, (LPARAM)st);
338 expect(1, r);
339 r = SendMessage(hWnd, DTM_GETRANGE, 0, (LPARAM)getSt);
340 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);
341 expect_systime(&st[0], &getSt[0]);
343 r = SendMessage(hWnd, DTM_SETRANGE, GDTR_MAX, (LPARAM)st);
344 expect_unsuccess(0, r);
346 /* set st[0] to all invalid numbers */
347 fill_systime_struct(&st[0], 0, 0, 7, 0, 24, 60, 60, 1000);
348 /* set st[1] to highest possible value */
349 fill_systime_struct(&st[1], 30827, 12, 6, 31, 23, 59, 59, 999);
351 r = SendMessage(hWnd, DTM_SETRANGE, GDTR_MAX, (LPARAM)st);
352 expect(1, r);
353 r = SendMessage(hWnd, DTM_GETRANGE, 0, (LPARAM)getSt);
354 todo_wine {
355 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);
357 expect_systime(&st[1], &getSt[1]);
359 r = SendMessage(hWnd, DTM_SETRANGE, GDTR_MIN, (LPARAM)st);
360 expect_unsuccess(0, r);
361 r = SendMessage(hWnd, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st);
362 expect_unsuccess(0, r);
364 /* set st[0] to highest possible value */
365 fill_systime_struct(&st[0], 30827, 12, 6, 31, 23, 59, 59, 999);
367 r = SendMessage(hWnd, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st);
368 expect(1, r);
369 r = SendMessage(hWnd, DTM_GETRANGE, 0, (LPARAM)getSt);
370 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);
371 expect_systime(&st[0], &getSt[0]);
372 expect_systime(&st[1], &getSt[1]);
374 /* initialize st[0] to lowest possible value */
375 fill_systime_struct(&st[0], 1601, 1, 0, 1, 0, 0, 0, 0);
376 /* set st[1] to highest possible value */
377 fill_systime_struct(&st[1], 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 /* set st[0] to value higher than minimum */
387 fill_systime_struct(&st[0], 1980, 1, 3, 23, 14, 34, 37, 465);
388 /* set st[1] to value lower than maximum */
389 fill_systime_struct(&st[1], 2007, 3, 2, 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 ok_sequence(sequences, DATETIME_SEQ_INDEX, test_dtm_set_and_get_range_seq, "test_dtm_set_and_get_range", FALSE);
400 DestroyWindow(hWnd);
403 /* when max<min for DTM_SETRANGE, Windows seems to swap the min and max values,
404 although that's undocumented. However, it doesn't seem to be implemented
405 correctly, causing some strange side effects */
406 static void test_dtm_set_range_swap_min_max(void)
408 LRESULT r;
409 SYSTEMTIME st[2];
410 SYSTEMTIME getSt[2];
411 SYSTEMTIME origSt;
412 HWND hWnd;
414 hWnd = create_datetime_control(DTS_SHOWNONE);
415 flush_sequences(sequences, NUM_MSG_SEQUENCES);
417 fill_systime_struct(&st[0], 2007, 2, 4, 15, 2, 2, 2, 2);
419 r = SendMessage(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st[0]);
420 expect(1, r);
421 r = SendMessage(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&origSt);
422 ok(r == GDT_VALID, "Expected %d, not %d(GDT_NONE) or %d(GDT_ERROR), got %ld\n", GDT_VALID, GDT_NONE, GDT_ERROR, r);
423 expect_systime(&st[0], &origSt);
425 /* set st[0] to value higher than st[1] */
426 fill_systime_struct(&st[0], 2007, 3, 2, 31, 23, 59, 59, 999);
427 fill_systime_struct(&st[1], 1980, 1, 3, 23, 14, 34, 37, 465);
429 /* since min>max, min and max values should be swapped by DTM_SETRANGE
430 automatically */
431 r = SendMessage(hWnd, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st);
432 expect(1, r);
433 r = SendMessage(hWnd, DTM_GETRANGE, 0, (LPARAM)getSt);
434 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);
435 todo_wine {
436 ok(compare_systime(&st[0], &getSt[0]) == 1 ||
437 broken(compare_systime(&st[0], &getSt[1]) == 1), /* comctl32 version <= 5.80 */
438 "ST1 != ST2\n");
440 ok(compare_systime(&st[1], &getSt[1]) == 1 ||
441 broken(compare_systime(&st[1], &getSt[0]) == 1), /* comctl32 version <= 5.80 */
442 "ST1 != ST2\n");
445 fill_systime_struct(&st[0], 1980, 1, 3, 23, 14, 34, 37, 465);
447 r = SendMessage(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st[0]);
448 expect(1, r);
449 r = SendMessage(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt[0]);
450 ok(r == GDT_VALID, "Expected %d, not %d(GDT_NONE) or %d(GDT_ERROR), got %ld\n", GDT_VALID, GDT_NONE, GDT_ERROR, r);
451 /* the time part seems to not change after swapping the min and max values
452 and doing DTM_SETSYSTEMTIME */
453 expect_systime_date(&st[0], &getSt[0]);
454 todo_wine {
455 ok(compare_systime_time(&origSt, &getSt[0]) == 1 ||
456 broken(compare_systime_time(&st[0], &getSt[0]) == 1), /* comctl32 version <= 5.80 */
457 "ST1.time != ST2.time\n");
460 /* set st[0] to value higher than minimum */
461 fill_systime_struct(&st[0], 1980, 1, 3, 23, 14, 34, 37, 465);
462 /* set st[1] to value lower than maximum */
463 fill_systime_struct(&st[1], 2007, 3, 2, 31, 23, 59, 59, 999);
465 r = SendMessage(hWnd, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st);
466 expect(1, r);
467 /* for some reason after we swapped the min and max values before,
468 whenever we do a DTM_SETRANGE, the DTM_GETRANGE will return the values
469 swapped*/
470 r = SendMessage(hWnd, DTM_GETRANGE, 0, (LPARAM)getSt);
471 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);
472 todo_wine {
473 ok(compare_systime(&st[0], &getSt[1]) == 1 ||
474 broken(compare_systime(&st[0], &getSt[0]) == 1), /* comctl32 version <= 5.80 */
475 "ST1 != ST2\n");
477 ok(compare_systime(&st[1], &getSt[0]) == 1 ||
478 broken(compare_systime(&st[1], &getSt[1]) == 1), /* comctl32 version <= 5.80 */
479 "ST1 != ST2\n");
482 /* set st[0] to value higher than st[1] */
483 fill_systime_struct(&st[0], 2007, 3, 2, 31, 23, 59, 59, 999);
484 fill_systime_struct(&st[1], 1980, 1, 3, 23, 14, 34, 37, 465);
486 /* set min>max again, so that the return values of DTM_GETRANGE are no
487 longer swapped the next time we do a DTM SETRANGE and DTM_GETRANGE*/
488 r = SendMessage(hWnd, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st);
489 expect(1, r);
490 r = SendMessage(hWnd, DTM_GETRANGE, 0, (LPARAM)getSt);
491 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);
492 expect_systime(&st[0], &getSt[1]);
493 expect_systime(&st[1], &getSt[0]);
495 /* initialize st[0] to lowest possible value */
496 fill_systime_struct(&st[0], 1601, 1, 0, 1, 0, 0, 0, 0);
497 /* set st[1] to highest possible value */
498 fill_systime_struct(&st[1], 30827, 12, 6, 31, 23, 59, 59, 999);
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[0]);
505 expect_systime(&st[1], &getSt[1]);
507 ok_sequence(sequences, DATETIME_SEQ_INDEX, test_dtm_set_range_swap_min_max_seq, "test_dtm_set_range_swap_min_max", FALSE);
509 DestroyWindow(hWnd);
512 static void test_dtm_set_and_get_system_time(void)
514 LRESULT r;
515 SYSTEMTIME st, getSt, ref;
516 HWND hWnd, hWndDateTime_test_gdt_none;
518 hWndDateTime_test_gdt_none = create_datetime_control(0);
520 ok(hWndDateTime_test_gdt_none!=NULL, "Expected non NULL, got %p\n", hWndDateTime_test_gdt_none);
521 if(hWndDateTime_test_gdt_none) {
522 r = SendMessage(hWndDateTime_test_gdt_none, DTM_SETSYSTEMTIME, GDT_NONE, (LPARAM)&st);
523 expect(0, r);
525 else {
526 skip("hWndDateTime_test_gdt_none is NULL\n");
527 flush_sequences(sequences, NUM_MSG_SEQUENCES);
529 return;
532 DestroyWindow(hWndDateTime_test_gdt_none);
534 hWnd = create_datetime_control(DTS_SHOWNONE);
535 flush_sequences(sequences, NUM_MSG_SEQUENCES);
537 r = SendMessage(hWnd, DTM_SETSYSTEMTIME, GDT_NONE, (LPARAM)&st);
538 expect(1, r);
539 r = SendMessage(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt);
540 ok(r == GDT_NONE, "Expected %d, not %d(GDT_VALID) or %d(GDT_ERROR), got %ld\n", GDT_NONE, GDT_VALID, GDT_ERROR, r);
542 /* set st to lowest possible value */
543 fill_systime_struct(&st, 1601, 1, 0, 1, 0, 0, 0, 0);
545 r = SendMessage(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st);
546 expect(1, r);
548 /* set st to highest possible value */
549 fill_systime_struct(&st, 30827, 12, 6, 31, 23, 59, 59, 999);
551 r = SendMessage(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st);
552 expect(1, r);
554 /* set st to value between min and max */
555 fill_systime_struct(&st, 1980, 1, 3, 23, 14, 34, 37, 465);
557 r = SendMessage(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st);
558 expect(1, r);
559 r = SendMessage(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt);
560 ok(r == GDT_VALID, "Expected %d, not %d(GDT_NONE) or %d(GDT_ERROR), got %ld\n", GDT_VALID, GDT_NONE, GDT_ERROR, r);
561 expect_systime(&st, &getSt);
563 /* set st to invalid value */
564 fill_systime_struct(&st, 0, 0, 7, 0, 24, 60, 60, 1000);
566 r = SendMessage(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st);
567 expect_unsuccess(0, r);
569 ok_sequence(sequences, DATETIME_SEQ_INDEX, test_dtm_set_and_get_system_time_seq, "test_dtm_set_and_get_system_time", FALSE);
571 /* set to some valid value */
572 GetSystemTime(&ref);
573 r = SendMessage(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&ref);
574 expect(1, r);
575 r = SendMessage(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt);
576 expect(GDT_VALID, r);
577 expect_systime(&ref, &getSt);
579 /* year invalid */
580 st = ref;
581 st.wYear = 0;
582 r = SendMessage(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st);
583 todo_wine expect(1, r);
584 r = SendMessage(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt);
585 expect(GDT_VALID, r);
586 expect_systime(&ref, &getSt);
587 /* month invalid */
588 st = ref;
589 st.wMonth = 13;
590 r = SendMessage(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st);
591 expect(0, r);
592 r = SendMessage(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt);
593 expect(GDT_VALID, r);
594 expect_systime(&ref, &getSt);
595 /* day invalid */
596 st = ref;
597 st.wDay = 32;
598 r = SendMessage(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st);
599 expect(0, r);
600 r = SendMessage(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt);
601 expect(GDT_VALID, r);
602 expect_systime(&ref, &getSt);
603 /* day of week isn't validated */
604 st = ref;
605 st.wDayOfWeek = 10;
606 r = SendMessage(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st);
607 expect(1, r);
608 r = SendMessage(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt);
609 expect(GDT_VALID, r);
610 expect_systime(&ref, &getSt);
611 /* hour invalid */
612 st = ref;
613 st.wHour = 25;
614 r = SendMessage(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st);
615 expect(0, r);
616 r = SendMessage(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt);
617 expect(GDT_VALID, r);
618 expect_systime(&ref, &getSt);
619 /* minute invalid */
620 st = ref;
621 st.wMinute = 60;
622 r = SendMessage(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st);
623 expect(0, r);
624 r = SendMessage(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt);
625 expect(GDT_VALID, r);
626 expect_systime(&ref, &getSt);
627 /* sec invalid */
628 st = ref;
629 st.wSecond = 60;
630 r = SendMessage(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st);
631 expect(0, r);
632 r = SendMessage(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt);
633 expect(GDT_VALID, r);
634 expect_systime(&ref, &getSt);
635 /* msec invalid */
636 st = ref;
637 st.wMilliseconds = 1000;
638 r = SendMessage(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st);
639 expect(0, r);
640 r = SendMessage(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt);
641 expect(GDT_VALID, r);
642 expect_systime(&ref, &getSt);
644 /* day of week should be calculated automatically,
645 actual day of week for this date is 4 */
646 fill_systime_struct(&st, 2009, 10, 1, 1, 0, 0, 10, 200);
647 r = SendMessage(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st);
648 expect(1, r);
649 r = SendMessage(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt);
650 expect(GDT_VALID, r);
651 /* 01.10.2009 is Thursday */
652 expect(4, (LRESULT)getSt.wDayOfWeek);
653 st.wDayOfWeek = 4;
654 expect_systime(&st, &getSt);
656 DestroyWindow(hWnd);
659 static void test_wm_set_get_text(void)
661 static const CHAR a_str[] = "a";
662 char buff[16], time[16];
663 HWND hWnd;
664 LRESULT ret;
666 hWnd = create_datetime_control(0);
668 ret = SendMessage(hWnd, WM_SETTEXT, 0, (LPARAM)a_str);
669 ok(CB_ERR == ret ||
670 broken(0 == ret) || /* comctl32 <= 4.72 */
671 broken(1 == ret), /* comctl32 <= 4.70 */
672 "Expected CB_ERR, got %ld\n", ret);
674 buff[0] = 0;
675 ret = SendMessage(hWnd, WM_GETTEXT, sizeof(buff), (LPARAM)buff);
676 ok(strcmp(buff, a_str) != 0, "Expected text not to change, got %s\n", buff);
678 GetDateFormat(LOCALE_USER_DEFAULT, 0, NULL, NULL, time, sizeof(time));
679 ok(!strcmp(buff, time), "Expected %s, got %s\n", time, buff);
681 DestroyWindow(hWnd);
684 static void test_dts_shownone(void)
686 HWND hwnd;
687 DWORD style;
689 /* it isn't allowed to change DTS_SHOWNONE after creation */
690 hwnd = create_datetime_control(0);
691 style = GetWindowLong(hwnd, GWL_STYLE);
692 SetWindowLong(hwnd, GWL_STYLE, style | DTS_SHOWNONE);
693 style = GetWindowLong(hwnd, GWL_STYLE);
694 ok(!(style & DTS_SHOWNONE), "Expected DTS_SHOWNONE not to be set\n");
695 DestroyWindow(hwnd);
697 hwnd = create_datetime_control(DTS_SHOWNONE);
698 style = GetWindowLong(hwnd, GWL_STYLE);
699 SetWindowLong(hwnd, GWL_STYLE, style & ~DTS_SHOWNONE);
700 style = GetWindowLong(hwnd, GWL_STYLE);
701 ok(style & DTS_SHOWNONE, "Expected DTS_SHOWNONE to be set\n");
702 DestroyWindow(hwnd);
705 START_TEST(datetime)
707 HMODULE hComctl32;
708 BOOL (WINAPI *pInitCommonControlsEx)(const INITCOMMONCONTROLSEX*);
709 INITCOMMONCONTROLSEX iccex;
711 hComctl32 = GetModuleHandleA("comctl32.dll");
712 pInitCommonControlsEx = (void*)GetProcAddress(hComctl32, "InitCommonControlsEx");
713 if (!pInitCommonControlsEx)
715 skip("InitCommonControlsEx() is missing. Skipping the tests\n");
716 return;
718 iccex.dwSize = sizeof(iccex);
719 iccex.dwICC = ICC_DATE_CLASSES;
720 pInitCommonControlsEx(&iccex);
722 init_msg_sequences(sequences, NUM_MSG_SEQUENCES);
724 test_dtm_set_format();
725 test_dtm_set_and_get_mccolor();
726 test_dtm_set_and_get_mcfont();
727 test_dtm_get_monthcal();
728 test_dtm_set_and_get_range();
729 test_dtm_set_range_swap_min_max();
730 test_dtm_set_and_get_system_time();
731 test_wm_set_get_text();
732 test_dts_shownone();