msi/tests: automation: Add more tests for Installer::RegistryValue.
[wine] / dlls / comctl32 / tests / datetime.c
1 /* Unit test suite for datetime control.
2 *
3 * Copyright 2007 Kanit Therdsteerasukdi
4 *
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.
9 *
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.
14 *
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
18 */
19
20 #include <windows.h>
21 #include <commctrl.h>
22
23 #include "wine/test.h"
24 #include "msg.h"
25
26 #define expect(EXPECTED, GOT) ok((GOT)==(EXPECTED), "Expected %d, got %ld\n", (EXPECTED), (GOT))
27
28 #define expect_unsuccess(EXPECTED, GOT) ok((GOT)==(EXPECTED), "Expected %d(unsuccessful), got %ld(successful)\n", (EXPECTED), (GOT))
29
30 #define NUM_MSG_SEQUENCES   1
31 #define DATETIME_SEQ_INDEX    0
32
33 static struct msg_sequence *sequences[NUM_MSG_SEQUENCES];
34
35 static const struct message test_dtm_set_format_seq[] = {
36     { DTM_SETFORMATA, sent|wparam|lparam, 0x00000000, 0x00000000 },
37     { DTM_SETFORMATA, sent|wparam, 0x00000000 },
38     { 0 }
39 };
40
41 static const struct message test_dtm_set_and_get_mccolor_seq[] = {
42     { DTM_SETMCCOLOR, sent|wparam|lparam, 0x00000000, 0x00000000 },
43     { DTM_SETMCCOLOR, sent|wparam|lparam, 0x00000000, 0x00ffffff },
44     { DTM_SETMCCOLOR, sent|wparam|lparam, 0x00000000, 0x00dcb464 },
45     { DTM_GETMCCOLOR, sent|wparam|lparam, 0x00000000, 0x00000000 },
46     { DTM_SETMCCOLOR, sent|wparam|lparam, 0x00000004, 0x00000000 },
47     { DTM_SETMCCOLOR, sent|wparam|lparam, 0x00000004, 0x00ffffff },
48     { DTM_SETMCCOLOR, sent|wparam|lparam, 0x00000004, 0x00dcb464 },
49     { DTM_GETMCCOLOR, sent|wparam|lparam, 0x00000004, 0x00000000 },
50     { DTM_SETMCCOLOR, sent|wparam|lparam, 0x00000001, 0x00000000 },
51     { DTM_SETMCCOLOR, sent|wparam|lparam, 0x00000001, 0x00ffffff },
52     { DTM_SETMCCOLOR, sent|wparam|lparam, 0x00000001, 0x00dcb464 },
53     { DTM_GETMCCOLOR, sent|wparam|lparam, 0x00000001, 0x00000000 },
54     { DTM_SETMCCOLOR, sent|wparam|lparam, 0x00000002, 0x00000000 },
55     { DTM_SETMCCOLOR, sent|wparam|lparam, 0x00000002, 0x00ffffff },
56     { DTM_SETMCCOLOR, sent|wparam|lparam, 0x00000002, 0x00dcb464 },
57     { DTM_GETMCCOLOR, sent|wparam|lparam, 0x00000002, 0x00000000 },
58     { DTM_SETMCCOLOR, sent|wparam|lparam, 0x00000003, 0x00000000 },
59     { DTM_SETMCCOLOR, sent|wparam|lparam, 0x00000003, 0x00ffffff },
60     { DTM_SETMCCOLOR, sent|wparam|lparam, 0x00000003, 0x00dcb464 },
61     { DTM_GETMCCOLOR, sent|wparam|lparam, 0x00000003, 0x00000000 },
62     { DTM_SETMCCOLOR, sent|wparam|lparam, 0x00000005, 0x00000000 },
63     { DTM_SETMCCOLOR, sent|wparam|lparam, 0x00000005, 0x00ffffff },
64     { DTM_SETMCCOLOR, sent|wparam|lparam, 0x00000005, 0x00dcb464 },
65     { DTM_GETMCCOLOR, sent|wparam|lparam, 0x00000005, 0x00000000 },
66     { 0 }
67 };
68
69 static const struct message test_dtm_set_and_get_mcfont_seq[] = {
70     { DTM_SETMCFONT, sent|lparam, 0, 0x00000001 },
71     { DTM_GETMCFONT, sent|wparam|lparam, 0x00000000, 0x00000000 },
72     { 0 }
73 };
74
75 static const struct message test_dtm_get_monthcal_seq[] = {
76     { DTM_GETMONTHCAL, sent|wparam|lparam, 0x00000000, 0x00000000 },
77     { 0 }
78 };
79
80 static const struct message test_dtm_set_and_get_range_seq[] = {
81     { DTM_SETRANGE, sent|wparam, 0x00000001 },
82     { DTM_GETRANGE, sent|wparam, 0x00000000 },
83     { DTM_SETRANGE, sent|wparam, 0x00000002 },
84     { DTM_SETRANGE, sent|wparam, 0x00000002 },
85     { DTM_GETRANGE, sent|wparam, 0x00000000},
86     { DTM_SETRANGE, sent|wparam, 0x00000001 },
87     { DTM_SETRANGE, sent|wparam, 0x00000003 },
88     { DTM_SETRANGE, sent|wparam, 0x00000003 },
89     { DTM_GETRANGE, sent|wparam, 0x00000000 },
90     { DTM_SETRANGE, sent|wparam, 0x00000003 },
91     { DTM_GETRANGE, sent|wparam, 0x00000000 },
92     { DTM_SETRANGE, sent|wparam, 0x00000003 },
93     { DTM_GETRANGE, sent|wparam, 0x00000000 },
94     { 0 }
95 };
96
97 static const struct message test_dtm_set_range_swap_min_max_seq[] = {
98     { DTM_SETSYSTEMTIME, sent|wparam, 0x00000000 },
99     { DTM_GETSYSTEMTIME, sent|wparam, 0x00000000 },
100     { DTM_SETRANGE, sent|wparam, 0x00000003 },
101     { DTM_GETRANGE, sent|wparam, 0x00000000 },
102     { DTM_SETSYSTEMTIME, sent|wparam, 0x00000000 },
103     { DTM_GETSYSTEMTIME, sent|wparam, 0x00000000 },
104     { DTM_SETRANGE, sent|wparam, 0x00000003 },
105     { DTM_GETRANGE, sent|wparam, 0x00000000 },
106     { DTM_SETRANGE, sent|wparam, 0x00000003 },
107     { DTM_GETRANGE, sent|wparam, 0x00000000 },
108     { DTM_SETRANGE, sent|wparam, 0x00000003 },
109     { DTM_GETRANGE, sent|wparam, 0x00000000 },
110     { 0 }
111 };
112
113 static const struct message test_dtm_set_and_get_system_time_seq[] = {
114     { DTM_SETSYSTEMTIME, sent|wparam, 0x00000001 },
115     { WM_DESTROY, sent|wparam|lparam, 0x00000000, 0x00000000 },
116     { WM_NCDESTROY, sent|wparam|lparam, 0x00000000, 0x00000000 },
117     { DTM_SETSYSTEMTIME, sent|wparam, 0x00000001 },
118     { DTM_GETSYSTEMTIME, sent|wparam, 0x00000000 },
119     { DTM_SETSYSTEMTIME, sent|wparam, 0x00000000 },
120     { DTM_SETSYSTEMTIME, sent|wparam, 0x00000000 },
121     { DTM_SETSYSTEMTIME, sent|wparam, 0x00000000 },
122     { DTM_GETSYSTEMTIME, sent|wparam, 0x00000000 },
123     { DTM_SETSYSTEMTIME, sent|wparam, 0x00000000 },
124     { 0 }
125 };
126
127 static const struct message destroy_window_seq[] = {
128     { WM_DESTROY, sent|wparam|lparam, 0x00000000, 0x00000000 },
129     { WM_NCDESTROY, sent|wparam|lparam, 0x00000000, 0x00000000 },
130     { 0 }
131 };
132
133 struct subclass_info
134 {
135     WNDPROC oldproc;
136 };
137
138 static LRESULT WINAPI datetime_subclass_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
139 {
140     struct subclass_info *info = (struct subclass_info *)GetWindowLongA(hwnd, GWL_USERDATA);
141     static long defwndproc_counter = 0;
142     LRESULT ret;
143     struct message msg;
144
145     trace("datetime: %p, %04x, %08x, %08lx\n", hwnd, message, wParam, lParam);
146
147     msg.message = message;
148     msg.flags = sent|wparam|lparam;
149     if (defwndproc_counter) msg.flags |= defwinproc;
150     msg.wParam = wParam;
151     msg.lParam = lParam;
152     add_message(sequences, DATETIME_SEQ_INDEX, &msg);
153
154     defwndproc_counter++;
155     ret = CallWindowProcA(info->oldproc, hwnd, message, wParam, lParam);
156     defwndproc_counter--;
157
158     return ret;
159 }
160
161 static HWND create_datetime_control(DWORD style, DWORD exstyle)
162 {
163     struct subclass_info *info;
164     HWND hWndDateTime = NULL;
165
166     info = HeapAlloc(GetProcessHeap(), 0, sizeof(struct subclass_info));
167     if (!info)
168         return NULL;
169
170     hWndDateTime = CreateWindowEx(0,
171         DATETIMEPICK_CLASS,
172         NULL,
173         style,
174         0,50,300,120,
175         NULL,
176         NULL,
177         NULL,
178         NULL);
179
180     if (!hWndDateTime) {
181         HeapFree(GetProcessHeap(), 0, info);
182         return NULL;
183     }
184
185     info->oldproc = (WNDPROC)SetWindowLongA(hWndDateTime, GWL_WNDPROC,
186                                             (LONG)datetime_subclass_proc);
187     SetWindowLongA(hWndDateTime, GWL_USERDATA, (LONG)info);
188
189     return hWndDateTime;
190 }
191
192 static void test_dtm_set_format(HWND hWndDateTime)
193 {
194     LRESULT r;
195
196     r = SendMessage(hWndDateTime, DTM_SETFORMAT, 0, (LPARAM)NULL);
197     expect(1, r);
198
199     r = SendMessage(hWndDateTime, DTM_SETFORMAT, 0,
200                     (LPARAM)"'Today is: 'hh':'m':'s dddd MMM dd', 'yyyy");
201     expect(1, r);
202
203     ok_sequence(sequences, DATETIME_SEQ_INDEX, test_dtm_set_format_seq, "test_dtm_set_format", FALSE);
204     flush_sequences(sequences, NUM_MSG_SEQUENCES);
205 }
206
207 static void test_mccolor_types(HWND hWndDateTime, int mccolor_type, const char* mccolor_name)
208 {
209     LRESULT r;
210     COLORREF theColor, prevColor;
211
212     theColor=RGB(0,0,0);
213     r = SendMessage(hWndDateTime, DTM_SETMCCOLOR, mccolor_type, theColor);
214     ok(r != -1, "%s: Set RGB(0,0,0): Expected COLORREF of previous value, got %ld\n", mccolor_name, r);
215     prevColor=theColor;
216     theColor=RGB(255,255,255);
217     r = SendMessage(hWndDateTime, DTM_SETMCCOLOR, mccolor_type, theColor);
218     ok(r==prevColor, "%s: Set RGB(255,255,255): Expected COLORREF of previous value, got %ld\n", mccolor_name, r);
219     prevColor=theColor;
220     theColor=RGB(100,180,220);
221     r = SendMessage(hWndDateTime, DTM_SETMCCOLOR, mccolor_type, theColor);
222     ok(r==prevColor, "%s: Set RGB(100,180,220): Expected COLORREF of previous value, got %ld\n", mccolor_name, r);
223     r = SendMessage(hWndDateTime, DTM_GETMCCOLOR, mccolor_type, 0);
224     ok(r==theColor, "%s: GETMCCOLOR: Expected %d, got %ld\n", mccolor_name, theColor, r);
225 }
226
227 static void test_dtm_set_and_get_mccolor(HWND hWndDateTime)
228 {
229     test_mccolor_types(hWndDateTime, MCSC_BACKGROUND, "MCSC_BACKGROUND");
230     test_mccolor_types(hWndDateTime, MCSC_MONTHBK, "MCSC_MONTHBK");
231     test_mccolor_types(hWndDateTime, MCSC_TEXT, "MCSC_TEXT");
232     test_mccolor_types(hWndDateTime, MCSC_TITLEBK, "MCSC_TITLEBK");
233     test_mccolor_types(hWndDateTime, MCSC_TITLETEXT, "MCSC_TITLETEXT");
234     test_mccolor_types(hWndDateTime, MCSC_TRAILINGTEXT, "MCSC_TRAILINGTEXT");
235
236     ok_sequence(sequences, DATETIME_SEQ_INDEX, test_dtm_set_and_get_mccolor_seq, "test_dtm_set_and_get_mccolor", FALSE);
237     flush_sequences(sequences, NUM_MSG_SEQUENCES);
238 }
239
240 static void test_dtm_set_and_get_mcfont(HWND hWndDateTime)
241 {
242     HFONT hFontOrig, hFontNew;
243
244     hFontOrig = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
245     SendMessage(hWndDateTime, DTM_SETMCFONT, (WPARAM)hFontOrig, TRUE);
246     hFontNew = (HFONT)SendMessage(hWndDateTime, DTM_GETMCFONT, 0, 0);
247     ok(hFontOrig == hFontNew, "Expected hFontOrig==hFontNew, hFontOrig=%p, hFontNew=%p\n", hFontOrig, hFontNew);
248
249     ok_sequence(sequences, DATETIME_SEQ_INDEX, test_dtm_set_and_get_mcfont_seq, "test_dtm_set_and_get_mcfont", FALSE);
250     flush_sequences(sequences, NUM_MSG_SEQUENCES);
251 }
252
253 static void test_dtm_get_monthcal(HWND hWndDateTime)
254 {
255     LRESULT r;
256
257     todo_wine {
258         r = SendMessage(hWndDateTime, DTM_GETMONTHCAL, 0, 0);
259         ok(r == (LPARAM)NULL, "Expected NULL(no child month calendar control), got %ld\n", r);
260     }
261
262     ok_sequence(sequences, DATETIME_SEQ_INDEX, test_dtm_get_monthcal_seq, "test_dtm_get_monthcal", FALSE);
263     flush_sequences(sequences, NUM_MSG_SEQUENCES);
264 }
265
266 static void fill_systime_struct(SYSTEMTIME *st, int year, int month, int dayofweek, int day, int hour, int minute, int second, int milliseconds)
267 {
268     st->wYear = year;
269     st->wMonth = month;
270     st->wDayOfWeek = dayofweek;
271     st->wDay = day;
272     st->wHour = hour;
273     st->wMinute = minute;
274     st->wSecond = second;
275     st->wMilliseconds = milliseconds;
276 }
277
278 static LPARAM compare_systime_date(SYSTEMTIME *st1, SYSTEMTIME *st2)
279 {
280     return (st1->wYear == st2->wYear)
281             && (st1->wMonth == st2->wMonth)
282             && (st1->wDayOfWeek == st2->wDayOfWeek)
283             && (st1->wDay == st2->wDay);
284 }
285
286 static LPARAM compare_systime_time(SYSTEMTIME *st1, SYSTEMTIME *st2)
287 {
288     return (st1->wHour == st2->wHour)
289             && (st1->wMinute == st2->wMinute)
290             && (st1->wSecond == st2->wSecond)
291             && (st1->wMilliseconds == st2->wMilliseconds);
292 }
293
294 static LPARAM compare_systime(SYSTEMTIME *st1, SYSTEMTIME *st2)
295 {
296     if(!compare_systime_date(st1, st2))
297         return 0;
298
299     return compare_systime_time(st1, st2);
300 }
301
302 #define expect_systime(ST1, ST2) ok(compare_systime((ST1), (ST2))==1, "ST1 != ST2\n")
303 #define expect_systime_date(ST1, ST2) ok(compare_systime_date((ST1), (ST2))==1, "ST1.date != ST2.date\n")
304 #define expect_systime_time(ST1, ST2) ok(compare_systime_time((ST1), (ST2))==1, "ST1.time != ST2.time\n")
305
306 static void test_dtm_set_and_get_range(HWND hWndDateTime)
307 {
308     LRESULT r;
309     SYSTEMTIME st[2];
310     SYSTEMTIME getSt[2];
311
312     /* initialize st[0] to lowest possible value */
313     fill_systime_struct(&st[0], 1601, 1, 0, 1, 0, 0, 0, 0);
314     /* intialize st[1] to all invalid numbers */
315     fill_systime_struct(&st[1], 0, 0, 7, 0, 24, 60, 60, 1000);
316
317     r = SendMessage(hWndDateTime, DTM_SETRANGE, GDTR_MIN, (LPARAM)st);
318     expect(1, r);
319     r = SendMessage(hWndDateTime, DTM_GETRANGE, 0, (LPARAM)getSt);
320     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);
321     expect_systime(&st[0], &getSt[0]);
322
323     r = SendMessage(hWndDateTime, DTM_SETRANGE, GDTR_MAX, (LPARAM)st);
324     expect_unsuccess(0, r);
325
326     /* set st[0] to all invalid numbers */
327     fill_systime_struct(&st[0], 0, 0, 7, 0, 24, 60, 60, 1000);
328     /* set st[1] to highest possible value */
329     fill_systime_struct(&st[1], 30827, 12, 6, 31, 23, 59, 59, 999);
330
331     r = SendMessage(hWndDateTime, DTM_SETRANGE, GDTR_MAX, (LPARAM)st);
332     expect(1, r);
333     r = SendMessage(hWndDateTime, DTM_GETRANGE, 0, (LPARAM)getSt);
334     todo_wine {
335         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);
336     }
337     expect_systime(&st[1], &getSt[1]);
338
339     r = SendMessage(hWndDateTime, DTM_SETRANGE, GDTR_MIN, (LPARAM)st);
340     expect_unsuccess(0, r);
341     r = SendMessage(hWndDateTime, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st);
342     expect_unsuccess(0, r);
343
344     /* set st[0] to highest possible value */
345     fill_systime_struct(&st[0], 30827, 12, 6, 31, 23, 59, 59, 999);
346
347     r = SendMessage(hWndDateTime, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st);
348     expect(1, r);
349     r = SendMessage(hWndDateTime, DTM_GETRANGE, 0, (LPARAM)getSt);
350     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);
351     expect_systime(&st[0], &getSt[0]);
352     expect_systime(&st[1], &getSt[1]);
353
354     /* initialize st[0] to lowest possible value */
355     fill_systime_struct(&st[0], 1601, 1, 0, 1, 0, 0, 0, 0);
356     /* set st[1] to highest possible value */
357     fill_systime_struct(&st[1], 30827, 12, 6, 31, 23, 59, 59, 999);
358
359     r = SendMessage(hWndDateTime, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st);
360     expect(1, r);
361     r = SendMessage(hWndDateTime, DTM_GETRANGE, 0, (LPARAM)getSt);
362     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);
363     expect_systime(&st[0], &getSt[0]);
364     expect_systime(&st[1], &getSt[1]);
365
366     /* set st[0] to value higher than minimum */
367     fill_systime_struct(&st[0], 1980, 1, 3, 23, 14, 34, 37, 465);
368     /* set st[1] to value lower than maximum */
369     fill_systime_struct(&st[1], 2007, 3, 2, 31, 23, 59, 59, 999);
370
371     r = SendMessage(hWndDateTime, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st);
372     expect(1, r);
373     r = SendMessage(hWndDateTime, DTM_GETRANGE, 0, (LPARAM)getSt);
374     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);
375     expect_systime(&st[0], &getSt[0]);
376     expect_systime(&st[1], &getSt[1]);
377
378     ok_sequence(sequences, DATETIME_SEQ_INDEX, test_dtm_set_and_get_range_seq, "test_dtm_set_and_get_range", FALSE);
379     flush_sequences(sequences, NUM_MSG_SEQUENCES);
380 }
381
382 /* when max<min for DTM_SETRANGE, Windows seems to swap the min and max values,
383 although that's undocumented.  However, it doesn't seem to be implemented
384 correctly, causing some strange side effects */
385 static void test_dtm_set_range_swap_min_max(HWND hWndDateTime)
386 {
387     LRESULT r;
388     SYSTEMTIME st[2];
389     SYSTEMTIME getSt[2];
390     SYSTEMTIME origSt;
391
392     fill_systime_struct(&st[0], 2007, 2, 4, 15, 2, 2, 2, 2);
393
394     r = SendMessage(hWndDateTime, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st[0]);
395     expect(1, r);
396     r = SendMessage(hWndDateTime, DTM_GETSYSTEMTIME, 0, (LPARAM)&origSt);
397     ok(r == GDT_VALID, "Expected %d, not %d(GDT_NONE) or %d(GDT_ERROR), got %ld\n", GDT_VALID, GDT_NONE, GDT_ERROR, r);
398     expect_systime(&st[0], &origSt);
399
400     /* set st[0] to value higher than st[1] */
401     fill_systime_struct(&st[0], 2007, 3, 2, 31, 23, 59, 59, 999);
402     fill_systime_struct(&st[1], 1980, 1, 3, 23, 14, 34, 37, 465);
403
404     /* since min>max, min and max values should be swapped by DTM_SETRANGE
405     automatically */
406     r = SendMessage(hWndDateTime, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st);
407     expect(1, r);
408     r = SendMessage(hWndDateTime, DTM_GETRANGE, 0, (LPARAM)getSt);
409     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);
410     todo_wine {
411         expect_systime(&st[0], &getSt[0]);
412     }
413     todo_wine {
414         expect_systime(&st[1], &getSt[1]);
415     }
416
417     fill_systime_struct(&st[0], 1980, 1, 3, 23, 14, 34, 37, 465);
418
419     r = SendMessage(hWndDateTime, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st[0]);
420     expect(1, r);
421     r = SendMessage(hWndDateTime, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt[0]);
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     /* the time part seems to not change after swapping the min and max values
424     and doing DTM_SETSYSTEMTIME */
425     expect_systime_date(&st[0], &getSt[0]);
426     todo_wine {
427         expect_systime_time(&origSt, &getSt[0]);
428     }
429
430     /* set st[0] to value higher than minimum */
431     fill_systime_struct(&st[0], 1980, 1, 3, 23, 14, 34, 37, 465);
432     /* set st[1] to value lower than maximum */
433     fill_systime_struct(&st[1], 2007, 3, 2, 31, 23, 59, 59, 999);
434
435     r = SendMessage(hWndDateTime, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st);
436     expect(1, r);
437     /* for some reason after we swapped the min and max values before,
438     whenever we do a DTM_SETRANGE, the DTM_GETRANGE will return the values
439     swapped*/
440     r = SendMessage(hWndDateTime, DTM_GETRANGE, 0, (LPARAM)getSt);
441     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);
442     todo_wine {
443         expect_systime(&st[0], &getSt[1]);
444     }
445     todo_wine {
446         expect_systime(&st[1], &getSt[0]);
447     }
448
449     /* set st[0] to value higher than st[1] */
450     fill_systime_struct(&st[0], 2007, 3, 2, 31, 23, 59, 59, 999);
451     fill_systime_struct(&st[1], 1980, 1, 3, 23, 14, 34, 37, 465);
452
453     /* set min>max again, so that the return values of DTM_GETRANGE are no
454     longer swapped the next time we do a DTM SETRANGE and DTM_GETRANGE*/
455     r = SendMessage(hWndDateTime, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st);
456     expect(1, r);
457     r = SendMessage(hWndDateTime, DTM_GETRANGE, 0, (LPARAM)getSt);
458     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);
459     expect_systime(&st[0], &getSt[1]);
460     expect_systime(&st[1], &getSt[0]);
461
462     /* initialize st[0] to lowest possible value */
463     fill_systime_struct(&st[0], 1601, 1, 0, 1, 0, 0, 0, 0);
464     /* set st[1] to highest possible value */
465     fill_systime_struct(&st[1], 30827, 12, 6, 31, 23, 59, 59, 999);
466
467     r = SendMessage(hWndDateTime, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st);
468     expect(1, r);
469     r = SendMessage(hWndDateTime, DTM_GETRANGE, 0, (LPARAM)getSt);
470     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);
471     expect_systime(&st[0], &getSt[0]);
472     expect_systime(&st[1], &getSt[1]);
473
474     ok_sequence(sequences, DATETIME_SEQ_INDEX, test_dtm_set_range_swap_min_max_seq, "test_dtm_set_range_swap_min_max", FALSE);
475     flush_sequences(sequences, NUM_MSG_SEQUENCES);
476 }
477
478 static void test_dtm_set_and_get_system_time(HWND hWndDateTime)
479 {
480     LRESULT r;
481     SYSTEMTIME st;
482     SYSTEMTIME getSt;
483     HWND hWndDateTime_test_gdt_none;
484
485     hWndDateTime_test_gdt_none = create_datetime_control(0, 0);
486
487     ok(hWndDateTime_test_gdt_none!=NULL, "Expected non NULL, got %p\n", hWndDateTime_test_gdt_none);
488     if(hWndDateTime_test_gdt_none) {
489         r = SendMessage(hWndDateTime_test_gdt_none, DTM_SETSYSTEMTIME, GDT_NONE, (LPARAM)&st);
490         expect(0, r);
491     }
492     else {
493         skip("hWndDateTime_test_gdt_none is NULL\n");
494         flush_sequences(sequences, NUM_MSG_SEQUENCES);
495
496         return;
497     }
498
499     DestroyWindow(hWndDateTime_test_gdt_none);
500
501     r = SendMessage(hWndDateTime, DTM_SETSYSTEMTIME, GDT_NONE, (LPARAM)&st);
502     expect(1, r);
503     r = SendMessage(hWndDateTime, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt);
504     ok(r == GDT_NONE, "Expected %d, not %d(GDT_VALID) or %d(GDT_ERROR), got %ld\n", GDT_NONE, GDT_VALID, GDT_ERROR, r);
505
506     /* set st to lowest possible value */
507     fill_systime_struct(&st, 1601, 1, 0, 1, 0, 0, 0, 0);
508
509     r = SendMessage(hWndDateTime, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st);
510     expect(1, r);
511
512     /* set st to highest possible value */
513     fill_systime_struct(&st, 30827, 12, 6, 31, 23, 59, 59, 999);
514
515     r = SendMessage(hWndDateTime, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st);
516     expect(1, r);
517
518     /* set st to value between min and max */
519     fill_systime_struct(&st, 1980, 1, 3, 23, 14, 34, 37, 465);
520
521     r = SendMessage(hWndDateTime, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st);
522     expect(1, r);
523     r = SendMessage(hWndDateTime, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt);
524     ok(r == GDT_VALID, "Expected %d, not %d(GDT_NONE) or %d(GDT_ERROR), got %ld\n", GDT_VALID, GDT_NONE, GDT_ERROR, r);
525     expect_systime(&st, &getSt);
526
527     /* set st to invalid value */
528     fill_systime_struct(&st, 0, 0, 7, 0, 24, 60, 60, 1000);
529
530     r = SendMessage(hWndDateTime, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st);
531     expect_unsuccess(0, r);
532
533     ok_sequence(sequences, DATETIME_SEQ_INDEX, test_dtm_set_and_get_system_time_seq, "test_dtm_set_and_get_system_time", FALSE);
534     flush_sequences(sequences, NUM_MSG_SEQUENCES);
535 }
536
537 static void test_datetime_control(void)
538 {
539     HWND hWndDateTime;
540
541     hWndDateTime = create_datetime_control(DTS_SHOWNONE, 0);
542
543     ok(hWndDateTime != NULL, "Expected non NULL, got %p\n", hWndDateTime);
544     if(hWndDateTime!=NULL) {
545         test_dtm_set_format(hWndDateTime);
546         test_dtm_set_and_get_mccolor(hWndDateTime);
547         test_dtm_set_and_get_mcfont(hWndDateTime);
548         test_dtm_get_monthcal(hWndDateTime);
549         test_dtm_set_and_get_range(hWndDateTime);
550         test_dtm_set_range_swap_min_max(hWndDateTime);
551         test_dtm_set_and_get_system_time(hWndDateTime);
552     }
553     else {
554         skip("hWndDateTime is NULL\n");
555     }
556
557     DestroyWindow(hWndDateTime);
558     ok_sequence(sequences, DATETIME_SEQ_INDEX, destroy_window_seq, "test_dtm_set_and_get_system_time", TRUE);
559 }
560
561 START_TEST(datetime)
562 {
563     INITCOMMONCONTROLSEX icex;
564
565     icex.dwSize = sizeof(icex);
566     icex.dwICC = ICC_DATE_CLASSES;
567     InitCommonControlsEx(&icex);
568     init_msg_sequences(sequences, NUM_MSG_SEQUENCES);
569
570     test_datetime_control();
571 }