hhctrl.ocx: Added hhc parser.
[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
25 #define expect(EXPECTED, GOT) ok((GOT)==(EXPECTED), "Expected %d, got %ld\n", (EXPECTED), (GOT))
26
27 #define expect_unsuccess(EXPECTED, GOT) ok((GOT)==(EXPECTED), "Expected %d(unsuccessful), got %ld(successful)\n", (EXPECTED), (GOT))
28
29 static HWND create_datetime_control(DWORD style, DWORD exstyle)
30 {
31     HWND hWndDateTime = NULL;
32
33     hWndDateTime = CreateWindowEx(0,
34         DATETIMEPICK_CLASS,
35         NULL,
36         style,
37         0,50,300,120,
38         NULL,
39         NULL,
40         NULL,
41         NULL);
42
43     return hWndDateTime;
44 }
45
46 static void test_dtm_set_format(HWND hWndDateTime)
47 {
48     LRESULT r;
49
50     todo_wine {
51         r = SendMessage(hWndDateTime, DTM_SETFORMAT, 0, (LPARAM)NULL);
52         expect(1, r);
53
54         r = SendMessage(hWndDateTime, DTM_SETFORMAT, 0,
55             (LPARAM)"'Today is: 'hh':'m':'s dddd MMM dd', 'yyyy");
56         expect(1, r);
57     }
58 }
59
60 void test_mccolor_types(HWND hWndDateTime, int mccolor_type, const char* mccolor_name)
61 {
62     LRESULT r;
63     COLORREF theColor, prevColor;
64
65     theColor=RGB(0,0,0);
66     r = SendMessage(hWndDateTime, DTM_SETMCCOLOR, mccolor_type, theColor);
67     ok(r != -1, "%s: Set RGB(0,0,0): Expected COLORREF of previous value, got %ld\n", mccolor_name, r);
68     prevColor=theColor;
69     theColor=RGB(255,255,255);
70     r = SendMessage(hWndDateTime, DTM_SETMCCOLOR, mccolor_type, theColor);
71     ok(r==prevColor, "%s: Set RGB(255,255,255): Expected COLORREF of previous value, got %ld\n", mccolor_name, r);
72     prevColor=theColor;
73     theColor=RGB(100,180,220);
74     r = SendMessage(hWndDateTime, DTM_SETMCCOLOR, mccolor_type, theColor);
75     ok(r==prevColor, "%s: Set RGB(100,180,220): Expected COLORREF of previous value, got %ld\n", mccolor_name, r);
76     r = SendMessage(hWndDateTime, DTM_GETMCCOLOR, mccolor_type, 0);
77     ok(r==theColor, "%s: GETMCCOLOR: Expected %d, got %ld\n", mccolor_name, theColor, r);
78 }
79
80 static void test_dtm_set_and_get_mccolor(HWND hWndDateTime)
81 {
82     test_mccolor_types(hWndDateTime, MCSC_BACKGROUND, "MCSC_BACKGROUND");
83     test_mccolor_types(hWndDateTime, MCSC_MONTHBK, "MCSC_MONTHBK");
84     test_mccolor_types(hWndDateTime, MCSC_TEXT, "MCSC_TEXT");
85     test_mccolor_types(hWndDateTime, MCSC_TITLEBK, "MCSC_TITLEBK");
86     test_mccolor_types(hWndDateTime, MCSC_TITLETEXT, "MCSC_TITLETEXT");
87     test_mccolor_types(hWndDateTime, MCSC_TRAILINGTEXT, "MCSC_TRAILINGTEXT");
88 }
89
90 static void test_dtm_set_and_get_mcfont(HWND hWndDateTime)
91 {
92     HFONT hFontOrig, hFontNew;
93
94     hFontOrig = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
95     SendMessage(hWndDateTime, DTM_SETMCFONT, (WPARAM)hFontOrig, TRUE);
96     hFontNew = (HFONT)SendMessage(hWndDateTime, DTM_GETMCFONT, 0, 0);
97     ok(hFontOrig == hFontNew, "Expected hFontOrig==hFontNew, hFontOrig=%p, hFontNew=%p\n", hFontOrig, hFontNew);
98 }
99
100 static void test_dtm_get_monthcal(HWND hWndDateTime)
101 {
102     LRESULT r;
103
104     todo_wine {
105         r = SendMessage(hWndDateTime, DTM_GETMONTHCAL, 0, 0);
106         ok(r == (LPARAM)NULL, "Expected NULL(no child month calendar control), got %ld\n", r);
107     }
108 }
109
110 void fill_systime_struct(SYSTEMTIME *st, int year, int month, int dayofweek, int day, int hour, int minute, int second, int milliseconds)
111 {
112     st->wYear = year;
113     st->wMonth = month;
114     st->wDayOfWeek = dayofweek;
115     st->wDay = day;
116     st->wHour = hour;
117     st->wMinute = minute;
118     st->wSecond = second;
119     st->wMilliseconds = milliseconds;
120 }
121
122 LPARAM compare_systime_date(SYSTEMTIME *st1, SYSTEMTIME *st2)
123 {
124     return (st1->wYear == st2->wYear)
125             && (st1->wMonth == st2->wMonth)
126             && (st1->wDayOfWeek == st2->wDayOfWeek)
127             && (st1->wDay == st2->wDay);
128 }
129
130 LPARAM compare_systime_time(SYSTEMTIME *st1, SYSTEMTIME *st2)
131 {
132     return (st1->wHour == st2->wHour)
133             && (st1->wMinute == st2->wMinute)
134             && (st1->wSecond == st2->wSecond)
135             && (st1->wMilliseconds == st2->wMilliseconds);
136 }
137
138 LPARAM compare_systime(SYSTEMTIME *st1, SYSTEMTIME *st2)
139 {
140     if(!compare_systime_date(st1, st2))
141         return 0;
142
143     return compare_systime_time(st1, st2);
144 }
145
146 #define expect_systime(ST1, ST2) ok(compare_systime((ST1), (ST2))==1, "ST1 != ST2\n")
147 #define expect_systime_date(ST1, ST2) ok(compare_systime_date((ST1), (ST2))==1, "ST1.date != ST2.date\n")
148 #define expect_systime_time(ST1, ST2) ok(compare_systime_time((ST1), (ST2))==1, "ST1.time != ST2.time\n")
149
150 static void test_dtm_set_and_get_range(HWND hWndDateTime)
151 {
152     LRESULT r;
153     SYSTEMTIME st[2];
154     SYSTEMTIME getSt[2];
155
156     /* initialize st[0] to lowest possible value */
157     fill_systime_struct(&st[0], 1601, 1, 0, 1, 0, 0, 0, 0);
158     /* intialize st[1] to all invalid numbers */
159     fill_systime_struct(&st[1], 0, 0, 7, 0, 24, 60, 60, 1000);
160
161     r = SendMessage(hWndDateTime, DTM_SETRANGE, GDTR_MIN, (LPARAM)st);
162     expect(1, r);
163     r = SendMessage(hWndDateTime, DTM_GETRANGE, 0, (LPARAM)getSt);
164     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);
165     expect_systime(&st[0], &getSt[0]);
166
167     r = SendMessage(hWndDateTime, DTM_SETRANGE, GDTR_MAX, (LPARAM)st);
168     expect_unsuccess(0, r);
169
170     /* set st[0] to all invalid numbers */
171     fill_systime_struct(&st[0], 0, 0, 7, 0, 24, 60, 60, 1000);
172     /* set st[1] to highest possible value */
173     fill_systime_struct(&st[1], 30827, 12, 6, 31, 23, 59, 59, 999);
174
175     r = SendMessage(hWndDateTime, DTM_SETRANGE, GDTR_MAX, (LPARAM)st);
176     expect(1, r);
177     r = SendMessage(hWndDateTime, DTM_GETRANGE, 0, (LPARAM)getSt);
178     todo_wine {
179         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);
180     }
181     expect_systime(&st[1], &getSt[1]);
182
183     r = SendMessage(hWndDateTime, DTM_SETRANGE, GDTR_MIN, (LPARAM)st);
184     expect_unsuccess(0, r);
185     r = SendMessage(hWndDateTime, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st);
186     expect_unsuccess(0, r);
187
188     /* set st[0] to highest possible value */
189     fill_systime_struct(&st[0], 30827, 12, 6, 31, 23, 59, 59, 999);
190
191     r = SendMessage(hWndDateTime, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st);
192     expect(1, r);
193     r = SendMessage(hWndDateTime, DTM_GETRANGE, 0, (LPARAM)getSt);
194     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);
195     expect_systime(&st[0], &getSt[0]);
196     expect_systime(&st[1], &getSt[1]);
197
198     /* initialize st[0] to lowest possible value */
199     fill_systime_struct(&st[0], 1601, 1, 0, 1, 0, 0, 0, 0);
200     /* set st[1] to highest possible value */
201     fill_systime_struct(&st[1], 30827, 12, 6, 31, 23, 59, 59, 999);
202
203     r = SendMessage(hWndDateTime, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st);
204     expect(1, r);
205     r = SendMessage(hWndDateTime, DTM_GETRANGE, 0, (LPARAM)getSt);
206     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);
207     expect_systime(&st[0], &getSt[0]);
208     expect_systime(&st[1], &getSt[1]);
209
210     /* set st[0] to value higher than minimum */
211     fill_systime_struct(&st[0], 1980, 1, 3, 23, 14, 34, 37, 465);
212     /* set st[1] to value lower than maximum */
213     fill_systime_struct(&st[1], 2007, 3, 2, 31, 23, 59, 59, 999);
214
215     r = SendMessage(hWndDateTime, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st);
216     expect(1, r);
217     r = SendMessage(hWndDateTime, DTM_GETRANGE, 0, (LPARAM)getSt);
218     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);
219     expect_systime(&st[0], &getSt[0]);
220     expect_systime(&st[1], &getSt[1]);
221 }
222
223 /* when max<min for DTM_SETRANGE, Windows seems to swap the min and max values,
224 although that's undocumented.  However, it doesn't seem to be implemented
225 correctly, causing some strange side effects */
226 static void test_dtm_set_range_swap_min_max(HWND hWndDateTime)
227 {
228     LRESULT r;
229     SYSTEMTIME st[2];
230     SYSTEMTIME getSt[2];
231     SYSTEMTIME origSt;
232
233     fill_systime_struct(&st[0], 2007, 2, 4, 15, 2, 2, 2, 2);
234
235     r = SendMessage(hWndDateTime, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st[0]);
236     expect(1, r);
237     r = SendMessage(hWndDateTime, DTM_GETSYSTEMTIME, 0, (LPARAM)&origSt);
238     ok(r == GDT_VALID, "Expected %d, not %d(GDT_NONE) or %d(GDT_ERROR), got %ld\n", GDT_VALID, GDT_NONE, GDT_ERROR, r);
239     expect_systime(&st[0], &origSt);
240
241     /* set st[0] to value higher than st[1] */
242     fill_systime_struct(&st[0], 2007, 3, 2, 31, 23, 59, 59, 999);
243     fill_systime_struct(&st[1], 1980, 1, 3, 23, 14, 34, 37, 465);
244
245     /* since min>max, min and max values should be swapped by DTM_SETRANGE
246     automatically */
247     r = SendMessage(hWndDateTime, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st);
248     expect(1, r);
249     r = SendMessage(hWndDateTime, DTM_GETRANGE, 0, (LPARAM)getSt);
250     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);
251     todo_wine {
252         expect_systime(&st[0], &getSt[0]);
253     }
254     todo_wine {
255         expect_systime(&st[1], &getSt[1]);
256     }
257
258     fill_systime_struct(&st[0], 1980, 1, 3, 23, 14, 34, 37, 465);
259
260     r = SendMessage(hWndDateTime, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st[0]);
261     expect(1, r);
262     r = SendMessage(hWndDateTime, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt[0]);
263     ok(r == GDT_VALID, "Expected %d, not %d(GDT_NONE) or %d(GDT_ERROR), got %ld\n", GDT_VALID, GDT_NONE, GDT_ERROR, r);
264     /* the time part seems to not change after swapping the min and max values
265     and doing DTM_SETSYSTEMTIME */
266     expect_systime_date(&st[0], &getSt[0]);
267     todo_wine {
268         expect_systime_time(&origSt, &getSt[0]);
269     }
270
271     /* set st[0] to value higher than minimum */
272     fill_systime_struct(&st[0], 1980, 1, 3, 23, 14, 34, 37, 465);
273     /* set st[1] to value lower than maximum */
274     fill_systime_struct(&st[1], 2007, 3, 2, 31, 23, 59, 59, 999);
275
276     r = SendMessage(hWndDateTime, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st);
277     expect(1, r);
278     /* for some reason after we swapped the min and max values before,
279     whenever we do a DTM_SETRANGE, the DTM_GETRANGE will return the values
280     swapped*/
281     r = SendMessage(hWndDateTime, DTM_GETRANGE, 0, (LPARAM)getSt);
282     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);
283     todo_wine {
284         expect_systime(&st[0], &getSt[1]);
285     }
286     todo_wine {
287         expect_systime(&st[1], &getSt[0]);
288     }
289
290     /* set st[0] to value higher than st[1] */
291     fill_systime_struct(&st[0], 2007, 3, 2, 31, 23, 59, 59, 999);
292     fill_systime_struct(&st[1], 1980, 1, 3, 23, 14, 34, 37, 465);
293
294     /* set min>max again, so that the return values of DTM_GETRANGE are no
295     longer swapped the next time we do a DTM SETRANGE and DTM_GETRANGE*/
296     r = SendMessage(hWndDateTime, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st);
297     expect(1, r);
298     r = SendMessage(hWndDateTime, DTM_GETRANGE, 0, (LPARAM)getSt);
299     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);
300     expect_systime(&st[0], &getSt[1]);
301     expect_systime(&st[1], &getSt[0]);
302
303     /* initialize st[0] to lowest possible value */
304     fill_systime_struct(&st[0], 1601, 1, 0, 1, 0, 0, 0, 0);
305     /* set st[1] to highest possible value */
306     fill_systime_struct(&st[1], 30827, 12, 6, 31, 23, 59, 59, 999);
307
308     r = SendMessage(hWndDateTime, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st);
309     expect(1, r);
310     r = SendMessage(hWndDateTime, DTM_GETRANGE, 0, (LPARAM)getSt);
311     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);
312     expect_systime(&st[0], &getSt[0]);
313     expect_systime(&st[1], &getSt[1]);
314 }
315
316 static void test_dtm_set_and_get_system_time(HWND hWndDateTime)
317 {
318     LRESULT r;
319     SYSTEMTIME st;
320     SYSTEMTIME getSt;
321
322     r = SendMessage(hWndDateTime, DTM_SETSYSTEMTIME, GDT_NONE, (LPARAM)&st);
323     expect(1, r);
324     r = SendMessage(hWndDateTime, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt);
325     ok(r == GDT_NONE, "Expected %d, not %d(GDT_VALID) or %d(GDT_ERROR), got %ld\n", GDT_NONE, GDT_VALID, GDT_ERROR, r);
326
327     /* set st to lowest possible value */
328     fill_systime_struct(&st, 1601, 1, 0, 1, 0, 0, 0, 0);
329
330     r = SendMessage(hWndDateTime, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st);
331     expect(1, r);
332
333     /* set st to highest possible value */
334     fill_systime_struct(&st, 30827, 12, 6, 31, 23, 59, 59, 999);
335
336     r = SendMessage(hWndDateTime, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st);
337     expect(1, r);
338
339     /* set st to value between min and max */
340     fill_systime_struct(&st, 1980, 1, 3, 23, 14, 34, 37, 465);
341
342     r = SendMessage(hWndDateTime, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st);
343     expect(1, r);
344     r = SendMessage(hWndDateTime, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt);
345     ok(r == GDT_VALID, "Expected %d, not %d(GDT_NONE) or %d(GDT_ERROR), got %ld\n", GDT_VALID, GDT_NONE, GDT_ERROR, r);
346     expect_systime(&st, &getSt);
347
348     /* set st to invalid value */
349     fill_systime_struct(&st, 0, 0, 7, 0, 24, 60, 60, 1000);
350
351     todo_wine {
352         r = SendMessage(hWndDateTime, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st);
353         expect_unsuccess(0, r);
354     }
355 }
356
357 static void test_datetime_control(void)
358 {
359     HWND hWndDateTime;
360
361     hWndDateTime = create_datetime_control(DTS_SHOWNONE, 0);
362
363     ok(hWndDateTime != NULL, "Expected non NULL, got %p\n", hWndDateTime);
364     if(hWndDateTime!=NULL) {
365         test_dtm_set_format(hWndDateTime);
366         test_dtm_set_and_get_mccolor(hWndDateTime);
367         test_dtm_set_and_get_mcfont(hWndDateTime);
368         test_dtm_get_monthcal(hWndDateTime);
369         test_dtm_set_and_get_range(hWndDateTime);
370         test_dtm_set_range_swap_min_max(hWndDateTime);
371         test_dtm_set_and_get_system_time(hWndDateTime);
372         }
373     else {
374         skip("hWndDateTime is NULL\n");
375     }
376
377     DestroyWindow(hWndDateTime);
378 }
379
380 START_TEST(datetime)
381 {
382     INITCOMMONCONTROLSEX icex;
383
384     icex.dwSize = sizeof(icex);
385     icex.dwICC = ICC_DATE_CLASSES;
386     InitCommonControlsEx(&icex);
387
388     test_datetime_control();
389 }