mcicda: Exclude unused headers.
[wine] / dlls / comctl32 / tests / monthcal.c
1 /*
2  * comctl32 month calendar unit tests
3  *
4  * Copyright (C) 2006 Vitaliy Margolen
5  * Copyright (C) 2007 Farshad Agah
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21
22 #include <stdarg.h>
23
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winuser.h"
27
28 #include "commctrl.h"
29
30 #include "wine/test.h"
31 #include <assert.h>
32 #include <windows.h>
33 #include "msg.h"
34
35 #define expect(expected, got) ok(expected == got, "Expected %d, got %d\n", expected, got);
36
37 #define NUM_MSG_SEQUENCES   2
38 #define PARENT_SEQ_INDEX    0
39 #define MONTHCAL_SEQ_INDEX  1
40
41 struct subclass_info
42 {
43     WNDPROC oldproc;
44 };
45
46 static struct msg_sequence *sequences[NUM_MSG_SEQUENCES];
47
48 static const struct message create_parent_window_seq[] = {
49     { WM_GETMINMAXINFO, sent },
50     { WM_NCCREATE, sent },
51     { WM_NCCALCSIZE, sent|wparam, 0 },
52     { WM_CREATE, sent },
53     { WM_SHOWWINDOW, sent|wparam, 1 },
54     { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
55     { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
56     { WM_ACTIVATEAPP, sent|wparam, 1 },
57     { WM_NCACTIVATE, sent|wparam, 1 },
58     { WM_ACTIVATE, sent|wparam, 1 },
59     { WM_IME_SETCONTEXT, sent|wparam|defwinproc|optional, 1 },
60     { WM_IME_NOTIFY, sent|defwinproc|optional },
61     { WM_SETFOCUS, sent|wparam|defwinproc, 0 },
62     /* Win9x adds SWP_NOZORDER below */
63     { WM_WINDOWPOSCHANGED, sent, /*|wparam, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE*/ },
64     { WM_NCCALCSIZE, sent|wparam|optional, 1 },
65     { WM_SIZE, sent },
66     { WM_MOVE, sent },
67     { 0 }
68 };
69
70 static const struct message create_monthcal_control_seq[] = {
71     { WM_NOTIFYFORMAT, sent|lparam, 0, NF_QUERY },
72     { WM_QUERYUISTATE, sent },
73     { WM_GETFONT, sent },
74     { WM_PARENTNOTIFY, sent|wparam, WM_CREATE},
75     { 0 }
76 };
77
78 static const struct message create_monthcal_multi_sel_style_seq[] = {
79     { WM_NOTIFYFORMAT, sent|lparam, 0, NF_QUERY },
80     { WM_QUERYUISTATE, sent },
81     { WM_GETFONT, sent },
82     { 0 }
83 };
84
85 static const struct message monthcal_color_seq[] = {
86     { MCM_GETCOLOR, sent|wparam|lparam, MCSC_BACKGROUND, 0},
87     { MCM_SETCOLOR, sent|wparam|lparam, MCSC_BACKGROUND, RGB(0,0,0)},
88     { MCM_GETCOLOR, sent|wparam|lparam, MCSC_BACKGROUND, 0},
89     { MCM_SETCOLOR, sent|wparam|lparam, MCSC_BACKGROUND, RGB(255,255,255)},
90     { MCM_GETCOLOR, sent|wparam|lparam, MCSC_BACKGROUND, 0},
91
92     { MCM_GETCOLOR, sent|wparam|lparam, MCSC_MONTHBK, 0},
93     { MCM_SETCOLOR, sent|wparam|lparam, MCSC_MONTHBK, RGB(0,0,0)},
94     { MCM_GETCOLOR, sent|wparam|lparam, MCSC_MONTHBK, 0},
95     { MCM_SETCOLOR, sent|wparam|lparam, MCSC_MONTHBK, RGB(255,255,255)},
96     { MCM_GETCOLOR, sent|wparam|lparam, MCSC_MONTHBK, 0},
97
98     { MCM_GETCOLOR, sent|wparam|lparam, MCSC_TEXT, 0},
99     { MCM_SETCOLOR, sent|wparam|lparam, MCSC_TEXT, RGB(0,0,0)},
100     { MCM_GETCOLOR, sent|wparam|lparam, MCSC_TEXT, 0},
101     { MCM_SETCOLOR, sent|wparam|lparam, MCSC_TEXT, RGB(255,255,255)},
102     { MCM_GETCOLOR, sent|wparam|lparam, MCSC_TEXT, 0},
103
104     { MCM_GETCOLOR, sent|wparam|lparam, MCSC_TITLEBK, 0},
105     { MCM_SETCOLOR, sent|wparam|lparam, MCSC_TITLEBK, RGB(0,0,0)},
106     { MCM_GETCOLOR, sent|wparam|lparam, MCSC_TITLEBK, 0},
107     { MCM_SETCOLOR, sent|wparam|lparam, MCSC_TITLEBK, RGB(255,255,255)},
108     { MCM_GETCOLOR, sent|wparam|lparam, MCSC_TITLEBK, 0},
109
110     { MCM_GETCOLOR, sent|wparam|lparam, MCSC_TITLETEXT, 0},
111     { MCM_SETCOLOR, sent|wparam|lparam, MCSC_TITLETEXT, RGB(0,0,0)},
112     { MCM_GETCOLOR, sent|wparam|lparam, MCSC_TITLETEXT, 0},
113     { MCM_SETCOLOR, sent|wparam|lparam, MCSC_TITLETEXT, RGB(255,255,255)},
114     { MCM_GETCOLOR, sent|wparam|lparam, MCSC_TITLETEXT, 0},
115
116     { MCM_GETCOLOR, sent|wparam|lparam, MCSC_TRAILINGTEXT, 0},
117     { MCM_SETCOLOR, sent|wparam|lparam, MCSC_TRAILINGTEXT, RGB(0,0,0)},
118     { MCM_GETCOLOR, sent|wparam|lparam, MCSC_TRAILINGTEXT, 0},
119     { MCM_SETCOLOR, sent|wparam|lparam, MCSC_TRAILINGTEXT, RGB(255,255,255)},
120     { MCM_GETCOLOR, sent|wparam|lparam, MCSC_TRAILINGTEXT, 0},
121     { 0 }
122 };
123
124 static const struct message monthcal_curr_date_seq[] = {
125     { MCM_SETCURSEL, sent|wparam, 0},
126     { WM_PAINT, sent|wparam|lparam|defwinproc, 0, 0},
127     { WM_NCPAINT, sent|wparam|lparam|defwinproc, 1, 0},
128     { WM_ERASEBKGND, sent|lparam|defwinproc, 0},
129     { MCM_SETCURSEL, sent|wparam, 0},
130     { MCM_SETCURSEL, sent|wparam, 0},
131     { MCM_GETCURSEL, sent|wparam, 0},
132     { MCM_GETCURSEL, sent|wparam|lparam, 0, 0},
133     { 0 }
134 };
135
136 static const struct message monthcal_first_day_seq[] = {
137     { MCM_GETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 0},
138
139     { MCM_SETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, -5},
140     { MCM_GETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 0},
141
142     { MCM_SETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, -4},
143     { MCM_GETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 0},
144
145     { MCM_SETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, -3},
146     { MCM_GETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 0},
147
148     { MCM_SETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, -2},
149     { MCM_GETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 0},
150
151     { MCM_SETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, -1},
152     { MCM_GETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 0},
153
154     { MCM_SETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 0},
155     { MCM_GETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 0},
156
157     { MCM_SETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 1},
158     { MCM_GETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 0},
159
160     { MCM_SETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 2},
161     { MCM_GETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 0},
162
163     { MCM_SETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 3},
164     { MCM_GETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 0},
165
166     { MCM_SETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 4},
167     { MCM_GETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 0},
168
169     { MCM_SETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 5},
170     { MCM_GETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 0},
171
172     { MCM_SETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 6},
173     { MCM_GETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 0},
174
175     { MCM_SETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 7},
176     { MCM_GETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 0},
177
178     { MCM_SETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 8},
179     { MCM_GETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 0},
180
181     { MCM_SETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 9},
182     { MCM_GETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 0},
183
184     { MCM_SETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 10},
185     { MCM_GETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 0},
186
187     { MCM_SETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 11},
188     { MCM_GETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 0},
189     { 0 }
190 };
191
192 static const struct message monthcal_unicode_seq[] = {
193     { MCM_GETUNICODEFORMAT, sent|wparam|lparam, 0, 0},
194     { MCM_SETUNICODEFORMAT, sent|wparam|lparam, 1, 0},
195     { MCM_GETUNICODEFORMAT, sent|wparam|lparam, 0, 0},
196     { MCM_SETUNICODEFORMAT, sent|wparam|lparam, 0, 0},
197     { MCM_GETUNICODEFORMAT, sent|wparam|lparam, 0, 0},
198     { MCM_SETUNICODEFORMAT, sent|wparam|lparam, 1, 0},
199     { 0 }
200 };
201
202 static const struct message monthcal_hit_test_seq[] = {
203     { MCM_HITTEST, sent|wparam, 0},
204     { MCM_HITTEST, sent|wparam, 0},
205     { MCM_HITTEST, sent|wparam, 0},
206     { MCM_HITTEST, sent|wparam, 0},
207     { MCM_HITTEST, sent|wparam, 0},
208     { MCM_HITTEST, sent|wparam, 0},
209     { MCM_HITTEST, sent|wparam, 0},
210     { MCM_HITTEST, sent|wparam, 0},
211     { MCM_HITTEST, sent|wparam, 0},
212     { MCM_HITTEST, sent|wparam, 0},
213     { MCM_HITTEST, sent|wparam, 0},
214     { MCM_HITTEST, sent|wparam, 0},
215     { MCM_HITTEST, sent|wparam, 0},
216     { MCM_HITTEST, sent|wparam, 0},
217     { MCM_HITTEST, sent|wparam, 0},
218     { MCM_HITTEST, sent|wparam, 0},
219     { MCM_HITTEST, sent|wparam, 0},
220     { MCM_HITTEST, sent|wparam, 0},
221     { 0 }
222 };
223
224 static const struct message monthcal_today_seq[] = {
225     { MCM_SETTODAY, sent|wparam, 0},
226     { WM_PAINT, sent|wparam|lparam|defwinproc, 0, 0},
227     { MCM_GETTODAY, sent|wparam, 0},
228     { MCM_SETTODAY, sent|wparam, 0},
229     { WM_PAINT, sent|wparam|lparam|defwinproc, 0, 0},
230     { MCM_GETTODAY, sent|wparam, 0},
231     { 0 }
232 };
233
234 static const struct message monthcal_scroll_seq[] = {
235     { MCM_SETMONTHDELTA, sent|wparam|lparam, 2, 0},
236     { MCM_SETMONTHDELTA, sent|wparam|lparam, 3, 0},
237     { MCM_GETMONTHDELTA, sent|wparam|lparam, 0, 0},
238     { MCM_SETMONTHDELTA, sent|wparam|lparam, 12, 0},
239     { MCM_GETMONTHDELTA, sent|wparam|lparam, 0, 0},
240     { MCM_SETMONTHDELTA, sent|wparam|lparam, 15, 0},
241     { MCM_GETMONTHDELTA, sent|wparam|lparam, 0, 0},
242     { MCM_SETMONTHDELTA, sent|wparam|lparam, -5, 0},
243     { MCM_GETMONTHDELTA, sent|wparam|lparam, 0, 0},
244     { 0 }
245 };
246
247 static const struct message monthcal_monthrange_seq[] = {
248     { MCM_GETMONTHRANGE, sent|wparam, GMR_VISIBLE},
249     { MCM_GETMONTHRANGE, sent|wparam, GMR_DAYSTATE},
250     { 0 }
251 };
252
253 static const struct message monthcal_max_sel_day_seq[] = {
254     { MCM_SETMAXSELCOUNT, sent|wparam|lparam, 5, 0},
255     { MCM_GETMAXSELCOUNT, sent|wparam|lparam, 0, 0},
256     { MCM_SETMAXSELCOUNT, sent|wparam|lparam, 15, 0},
257     { MCM_GETMAXSELCOUNT, sent|wparam|lparam, 0, 0},
258     { MCM_SETMAXSELCOUNT, sent|wparam|lparam, -1, 0},
259     { MCM_GETMAXSELCOUNT, sent|wparam|lparam, 0, 0},
260     { 0 }
261 };
262
263 /* expected message sequence for parent*/
264 static const struct message destroy_monthcal_parent_msgs_seq[] = {
265     { WM_PARENTNOTIFY, sent|wparam, WM_DESTROY},
266     { 0 }
267 };
268
269 /* expected message sequence for child*/
270 static const struct message destroy_monthcal_child_msgs_seq[] = {
271     { WM_SHOWWINDOW, sent|wparam|lparam, 0, 0},
272     { WM_WINDOWPOSCHANGING, sent|wparam, 0},
273     { WM_WINDOWPOSCHANGED, sent|wparam, 0},
274     { WM_DESTROY, sent|wparam|lparam, 0, 0},
275     { WM_NCDESTROY, sent|wparam|lparam, 0, 0},
276     { 0 }
277 };
278
279 static const struct message destroy_monthcal_multi_sel_style_seq[] = {
280     { WM_DESTROY, sent|wparam|lparam, 0, 0},
281     { WM_NCDESTROY, sent|wparam|lparam, 0, 0},
282     { 0 }
283 };
284
285 /* expected message sequence for parent window*/
286 static const struct message destroy_parent_seq[] = {
287     { WM_WINDOWPOSCHANGING, sent|wparam, 0},
288     { WM_WINDOWPOSCHANGED, sent|wparam, 0},
289     { WM_NCACTIVATE, sent|wparam|lparam, 0, 0},
290     { WM_ACTIVATE, sent|wparam|lparam, 0, 0},
291     { WM_ACTIVATEAPP, sent|wparam, 0},
292     { WM_KILLFOCUS, sent|wparam|lparam, 0, 0},
293     { WM_IME_SETCONTEXT, sent|wparam|optional, 0},
294     { WM_IME_NOTIFY, sent|wparam|lparam|defwinproc|optional, 1, 0},
295     { WM_DESTROY, sent|wparam|lparam, 0, 0},
296     { WM_NCDESTROY, sent|wparam|lparam, 0, 0},
297     { 0 }
298 };
299
300 static void test_monthcal(void)
301 {
302     HWND hwnd;
303     SYSTEMTIME st[2], st1[2];
304     INITCOMMONCONTROLSEX ic = {sizeof(INITCOMMONCONTROLSEX), ICC_DATE_CLASSES};
305     int res, month_range;
306
307     InitCommonControlsEx(&ic);
308     hwnd = CreateWindowA(MONTHCAL_CLASSA, "MonthCal", WS_POPUP | WS_VISIBLE, CW_USEDEFAULT,
309                          0, 300, 300, 0, 0, NULL, NULL);
310     ok(hwnd != NULL, "Failed to create MonthCal\n");
311     GetSystemTime(&st[0]);
312     st[1] = st[0];
313
314     /* Invalid date/time */
315     st[0].wYear  = 2000;
316     /* Time should not matter */
317     st[1].wHour = st[1].wMinute = st[1].wSecond = 70;
318     ok(SendMessage(hwnd, MCM_SETRANGE, GDTR_MAX, (LPARAM)st), "Failed to set MAX limit\n");
319     ok(SendMessage(hwnd, MCM_GETRANGE, 0, (LPARAM)st1) == GDTR_MAX, "No limits should be set\n");
320     ok(st1[0].wYear != 2000, "Lover limit changed\n");
321
322     st[1].wMonth = 0;
323     ok(!SendMessage(hwnd, MCM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st), "Should have failed to set limits\n");
324     ok(SendMessage(hwnd, MCM_GETRANGE, 0, (LPARAM)st1) == GDTR_MAX, "No limits should be set\n");
325     ok(st1[0].wYear != 2000, "Lover limit changed\n");
326     ok(!SendMessage(hwnd, MCM_SETRANGE, GDTR_MAX, (LPARAM)st), "Should have failed to set MAX limit\n");
327     ok(SendMessage(hwnd, MCM_GETRANGE, 0, (LPARAM)st1) == GDTR_MAX, "No limits should be set\n");
328     ok(st1[0].wYear != 2000, "Lover limit changed\n");
329
330     GetSystemTime(&st[0]);
331     st[0].wDay = 20;
332     st[0].wMonth = 5;
333     st[1] = st[0];
334
335     month_range = SendMessage(hwnd, MCM_GETMONTHRANGE, GMR_VISIBLE, (LPARAM)st1);
336     st[1].wMonth--;
337     ok(SendMessage(hwnd, MCM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st), "Failed to set both min and max limits\n");
338     res = SendMessage(hwnd, MCM_GETMONTHRANGE, GMR_VISIBLE, (LPARAM)st1);
339     ok(res == month_range, "Invalid month range (%d)\n", res);
340     ok(SendMessage(hwnd, MCM_GETRANGE, 0, (LPARAM)st1) == (GDTR_MIN|GDTR_MAX), "Limits should be set\n");
341
342     st[1].wMonth += 2;
343     ok(SendMessage(hwnd, MCM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st), "Failed to set both min and max limits\n");
344     res = SendMessage(hwnd, MCM_GETMONTHRANGE, GMR_VISIBLE, (LPARAM)st1);
345     ok(res == month_range, "Invalid month range (%d)\n", res);
346
347     st[1].wYear --;
348     ok(SendMessage(hwnd, MCM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st), "Failed to set both min and max limits\n");
349     st[1].wYear += 1;
350     ok(SendMessage(hwnd, MCM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st), "Failed to set both min and max limits\n");
351
352     st[1].wMonth -= 3;
353     ok(SendMessage(hwnd, MCM_SETRANGE, GDTR_MAX, (LPARAM)st), "Failed to set max limit\n");
354     ok(SendMessage(hwnd, MCM_GETRANGE, 0, (LPARAM)st1) == GDTR_MAX, "Only MAX limit should be set\n");
355     st[1].wMonth += 4;
356     ok(SendMessage(hwnd, MCM_SETRANGE, GDTR_MAX, (LPARAM)st), "Failed to set max limit\n");
357     st[1].wYear -= 3;
358     ok(SendMessage(hwnd, MCM_SETRANGE, GDTR_MAX, (LPARAM)st), "Failed to set max limit\n");
359     st[1].wYear += 4;
360     ok(SendMessage(hwnd, MCM_SETRANGE, GDTR_MAX, (LPARAM)st), "Failed to set max limit\n");
361     ok(SendMessage(hwnd, MCM_GETRANGE, 0, (LPARAM)st1) == GDTR_MAX, "Only MAX limit should be set\n");
362
363     DestroyWindow(hwnd);
364 }
365
366 static LRESULT WINAPI parent_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
367 {
368     static long defwndproc_counter = 0;
369     LRESULT ret;
370     struct message msg;
371
372     /* do not log painting messages */
373     if (message != WM_PAINT &&
374         message != WM_ERASEBKGND &&
375         message != WM_NCPAINT &&
376         message != WM_NCHITTEST &&
377         message != WM_GETTEXT &&
378         message != WM_GETICON &&
379         message != WM_DEVICECHANGE)
380     {
381         trace("parent: %p, %04x, %08x, %08lx\n", hwnd, message, wParam, lParam);
382
383         msg.message = message;
384         msg.flags = sent|wparam|lparam;
385         if (defwndproc_counter) msg.flags |= defwinproc;
386         msg.wParam = wParam;
387         msg.lParam = lParam;
388         add_message(sequences, PARENT_SEQ_INDEX, &msg);
389     }
390
391     defwndproc_counter++;
392     ret = DefWindowProcA(hwnd, message, wParam, lParam);
393     defwndproc_counter--;
394
395     return ret;
396 }
397
398 static BOOL register_parent_wnd_class()
399 {
400     WNDCLASSA cls;
401
402     cls.style = 0;
403     cls.lpfnWndProc = parent_wnd_proc;
404     cls.cbClsExtra = 0;
405     cls.cbWndExtra = 0;
406     cls.hInstance = GetModuleHandleA(NULL);
407     cls.hIcon = 0;
408     cls.hCursor = LoadCursorA(0, (LPSTR)IDC_ARROW);
409     cls.hbrBackground = GetStockObject(WHITE_BRUSH);
410     cls.lpszMenuName = NULL;
411     cls.lpszClassName = "Month-Cal test parent class";
412     return RegisterClassA(&cls);
413 }
414
415 static HWND create_parent_window(void)
416 {
417     HWND hwnd;
418
419     InitCommonControls();
420
421     /* flush message sequences, so we can check the new sequence by the end of function */
422     flush_sequences(sequences, NUM_MSG_SEQUENCES);
423
424     if (!register_parent_wnd_class())
425         return NULL;
426
427     hwnd = CreateWindowEx(0, "Month-Cal test parent class",
428                           "Month-Cal test parent window",
429                           WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX |
430                           WS_MAXIMIZEBOX | WS_VISIBLE,
431                           0, 0, 500, 500,
432                           GetDesktopWindow(), NULL, GetModuleHandleA(NULL), NULL);
433
434     assert(hwnd);
435
436     /* check for message sequences */
437     ok_sequence(sequences, PARENT_SEQ_INDEX, create_parent_window_seq, "create parent window", TRUE);
438
439     return hwnd;
440 }
441
442 static LRESULT WINAPI monthcal_subclass_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
443 {
444     struct subclass_info *info = (struct subclass_info *)GetWindowLongA(hwnd, GWL_USERDATA);
445     static long defwndproc_counter = 0;
446     LRESULT ret;
447     struct message msg;
448
449     trace("monthcal: %p, %04x, %08x, %08lx\n", hwnd, message, wParam, lParam);
450
451     msg.message = message;
452     msg.flags = sent|wparam|lparam;
453     if (defwndproc_counter) msg.flags |= defwinproc;
454     msg.wParam = wParam;
455     msg.lParam = lParam;
456     add_message(sequences, MONTHCAL_SEQ_INDEX, &msg);
457
458     defwndproc_counter++;
459     ret = CallWindowProcA(info->oldproc, hwnd, message, wParam, lParam);
460     defwndproc_counter--;
461
462     return ret;
463 }
464
465 static HWND create_monthcal_control(DWORD style, HWND parent_window)
466 {
467     struct subclass_info *info;
468     HWND hwnd;
469     static const INITCOMMONCONTROLSEX ic = {sizeof(INITCOMMONCONTROLSEX), ICC_DATE_CLASSES};
470
471     InitCommonControlsEx(&ic);
472
473     info = HeapAlloc(GetProcessHeap(), 0, sizeof(struct subclass_info));
474     if (!info)
475         return NULL;
476
477     hwnd = CreateWindowEx(0,
478                     MONTHCAL_CLASS,
479                     "",
480                     style,
481                     0, 0, 300, 300,
482                     parent_window, NULL, GetModuleHandleA(NULL), NULL);
483
484     if (!hwnd)
485     {
486         HeapFree(GetProcessHeap(), 0, info);
487         return NULL;
488     }
489
490     info->oldproc = (WNDPROC)SetWindowLongA(hwnd, GWL_WNDPROC,
491                                             (LONG)monthcal_subclass_proc);
492     SetWindowLongA(hwnd, GWL_USERDATA, (LONG)info);
493
494     return hwnd;
495 }
496
497
498 /* Setter and Getters Tests */
499
500 static void test_monthcal_color(HWND hwnd)
501 {
502     int res, temp;
503
504     flush_sequences(sequences, NUM_MSG_SEQUENCES);
505
506     /* Setter and Getters for color*/
507     temp = SendMessage(hwnd, MCM_GETCOLOR, MCSC_BACKGROUND, 0);
508     res = SendMessage(hwnd, MCM_SETCOLOR, MCSC_BACKGROUND, RGB(0,0,0));
509     expect(temp, res);
510     temp = SendMessage(hwnd, MCM_GETCOLOR, MCSC_BACKGROUND, 0);
511     expect(RGB(0,0,0), temp);
512     res = SendMessage(hwnd, MCM_SETCOLOR, MCSC_BACKGROUND, RGB(255,255,255));
513     expect(temp, res);
514     temp = SendMessage(hwnd, MCM_GETCOLOR, MCSC_BACKGROUND, 0);
515     expect(RGB(255,255,255), temp);
516
517     temp = SendMessage(hwnd, MCM_GETCOLOR, MCSC_MONTHBK, 0);
518     res = SendMessage(hwnd, MCM_SETCOLOR, MCSC_MONTHBK, RGB(0,0,0));
519     expect(temp, res);
520     temp = SendMessage(hwnd, MCM_GETCOLOR, MCSC_MONTHBK, 0);
521     expect(RGB(0,0,0), temp);
522     res = SendMessage(hwnd, MCM_SETCOLOR, MCSC_MONTHBK, RGB(255,255,255));
523     expect(temp, res);
524     temp = SendMessage(hwnd, MCM_GETCOLOR, MCSC_MONTHBK, 0);
525     expect(RGB(255,255,255), temp);
526
527     temp = SendMessage(hwnd, MCM_GETCOLOR, MCSC_TEXT, 0);
528     res = SendMessage(hwnd, MCM_SETCOLOR, MCSC_TEXT, RGB(0,0,0));
529     expect(temp, res);
530     temp = SendMessage(hwnd, MCM_GETCOLOR, MCSC_TEXT, 0);
531     expect(RGB(0,0,0), temp);
532     res = SendMessage(hwnd, MCM_SETCOLOR, MCSC_TEXT, RGB(255,255,255));
533     expect(temp, res);
534     temp = SendMessage(hwnd, MCM_GETCOLOR, MCSC_TEXT, 0);
535     expect(RGB(255,255,255), temp);
536
537     temp = SendMessage(hwnd, MCM_GETCOLOR, MCSC_TITLEBK, 0);
538     res = SendMessage(hwnd, MCM_SETCOLOR, MCSC_TITLEBK, RGB(0,0,0));
539     expect(temp, res);
540     temp = SendMessage(hwnd, MCM_GETCOLOR, MCSC_TITLEBK, 0);
541     expect(RGB(0,0,0), temp);
542     res = SendMessage(hwnd, MCM_SETCOLOR, MCSC_TITLEBK, RGB(255,255,255));
543     expect(temp, res);
544     temp = SendMessage(hwnd, MCM_GETCOLOR, MCSC_TITLEBK, 0);
545     expect(RGB(255,255,255), temp);
546
547     temp = SendMessage(hwnd, MCM_GETCOLOR, MCSC_TITLETEXT, 0);
548     res = SendMessage(hwnd, MCM_SETCOLOR, MCSC_TITLETEXT, RGB(0,0,0));
549     expect(temp, res);
550     temp = SendMessage(hwnd, MCM_GETCOLOR, MCSC_TITLETEXT, 0);
551     expect(RGB(0,0,0), temp);
552     res = SendMessage(hwnd, MCM_SETCOLOR, MCSC_TITLETEXT, RGB(255,255,255));
553     expect(temp, res);
554     temp = SendMessage(hwnd, MCM_GETCOLOR, MCSC_TITLETEXT, 0);
555     expect(RGB(255,255,255), temp);
556
557     temp = SendMessage(hwnd, MCM_GETCOLOR, MCSC_TRAILINGTEXT, 0);
558     res = SendMessage(hwnd, MCM_SETCOLOR, MCSC_TRAILINGTEXT, RGB(0,0,0));
559     expect(temp, res);
560     temp = SendMessage(hwnd, MCM_GETCOLOR, MCSC_TRAILINGTEXT, 0);
561     expect(RGB(0,0,0), temp);
562     res = SendMessage(hwnd, MCM_SETCOLOR, MCSC_TRAILINGTEXT, RGB(255,255,255));
563     expect(temp, res);
564     temp = SendMessage(hwnd, MCM_GETCOLOR, MCSC_TRAILINGTEXT, 0);
565     expect(RGB(255,255,255), temp);
566
567     ok_sequence(sequences, MONTHCAL_SEQ_INDEX, monthcal_color_seq, "monthcal color", FALSE);
568 }
569
570 static void test_monthcal_currDate(HWND hwnd)
571 {
572     SYSTEMTIME st_original, st_new, st_test;
573     int res;
574
575     flush_sequences(sequences, NUM_MSG_SEQUENCES);
576
577     /* Setter and Getters for current date selected */
578     st_original.wYear = 2000;
579     st_original.wMonth = 11;
580     st_original.wDay = 28;
581     st_original.wHour = 11;
582     st_original.wMinute = 59;
583     st_original.wSecond = 30;
584     st_original.wMilliseconds = 0;
585     st_original.wDayOfWeek = 0;
586
587     st_new = st_test = st_original;
588
589     /* Should not validate the time */
590     res = SendMessage(hwnd, MCM_SETCURSEL, 0, (LPARAM)&st_test);
591     expect(1,res);
592
593     /* Overflow matters, check for wDay */
594     st_test.wDay += 4;
595     res = SendMessage(hwnd, MCM_SETCURSEL, 0, (LPARAM)&st_test);
596     expect(0,res);
597
598     /* correct wDay before checking for wMonth */
599     st_test.wDay -= 4;
600     expect(st_original.wDay, st_test.wDay);
601
602     /* Overflow matters, check for wMonth */
603     st_test.wMonth += 4;
604     res = SendMessage(hwnd, MCM_SETCURSEL, 0, (LPARAM)&st_test);
605     expect(0,res);
606
607     /* checking if gets the information right, modify st_new */
608     st_new.wYear += 4;
609     st_new.wMonth += 4;
610     st_new.wDay += 4;
611     st_new.wHour += 4;
612     st_new.wMinute += 4;
613     st_new.wSecond += 4;
614
615     res = SendMessage(hwnd, MCM_GETCURSEL, 0, (LPARAM)&st_new);
616     expect(1, res);
617
618     /* st_new change to st_origin, above settings with overflow */
619     /* should not change the current settings */
620     expect(st_original.wYear, st_new.wYear);
621     expect(st_original.wMonth, st_new.wMonth);
622     expect(st_original.wDay, st_new.wDay);
623     expect(st_original.wHour, st_new.wHour);
624     expect(st_original.wMinute, st_new.wMinute);
625     expect(st_original.wSecond, st_new.wSecond);
626
627     /* lparam cannot be NULL */
628     res = SendMessage(hwnd, MCM_GETCURSEL, 0, (LPARAM) NULL);
629     expect(0, res);
630
631     ok_sequence(sequences, MONTHCAL_SEQ_INDEX, monthcal_curr_date_seq, "monthcal currDate", TRUE);
632 }
633
634 static void test_monthcal_firstDay(HWND hwnd)
635 {
636     int res, fday, i, prev;
637     TCHAR b[128];
638     LCID lcid = LOCALE_USER_DEFAULT;
639
640     flush_sequences(sequences, NUM_MSG_SEQUENCES);
641
642     /* Setter and Getters for first day of week */
643     /* check for locale first day */
644     if(GetLocaleInfo(lcid, LOCALE_IFIRSTDAYOFWEEK, b, 128)){
645         fday = atoi(b);
646         res = SendMessage(hwnd, MCM_GETFIRSTDAYOFWEEK, 0, 0);
647         expect(fday, res);
648         prev = fday;
649
650         /* checking for the values that actually will be stored as */
651         /* current first day when we set a new value */
652         for (i = -5; i < 12; i++){
653             res = SendMessage(hwnd, MCM_SETFIRSTDAYOFWEEK, 0, (LPARAM) i);
654             expect(prev, res);
655             res = SendMessage(hwnd, MCM_GETFIRSTDAYOFWEEK, 0, 0);
656             prev = res;
657
658             if (i == -1){
659                 expect(MAKELONG(fday, FALSE), res);
660             }else if (i >= 7){
661                 expect(MAKELONG(fday, TRUE), res);
662             }else{
663                 expect(MAKELONG(i, TRUE), res);
664             }
665         }
666
667         ok_sequence(sequences, MONTHCAL_SEQ_INDEX, monthcal_first_day_seq, "monthcal firstDay", FALSE);
668
669     }else{
670         skip("Cannot retrieve first day of the week\n");
671     }
672
673 }
674
675 static void test_monthcal_unicode(HWND hwnd)
676 {
677     int res, temp;
678
679     flush_sequences(sequences, NUM_MSG_SEQUENCES);
680
681     /* Setter and Getters for Unicode format */
682
683     /* getting the current settings */
684     temp = SendMessage(hwnd, MCM_GETUNICODEFORMAT, 0, 0);
685
686     /* setting to 1, should return previous settings */
687     res = SendMessage(hwnd, MCM_SETUNICODEFORMAT, 1, 0);
688     expect(temp, res);
689
690     /* current setting is 1, so, should return 1 */
691     res = SendMessage(hwnd, MCM_GETUNICODEFORMAT, 0, 0);
692     todo_wine {expect(1, res);}
693
694     /* setting to 0, should return previous settings */
695     res = SendMessage(hwnd, MCM_SETUNICODEFORMAT, 0, 0);
696     todo_wine {expect(1, res);}
697
698     /* current setting is 0, so, it should return 0 */
699     res = SendMessage(hwnd, MCM_GETUNICODEFORMAT, 0, 0);
700     expect(0, res);
701
702     /* should return previous settings */
703     res = SendMessage(hwnd, MCM_SETUNICODEFORMAT, 1, 0);
704     expect(0, res);
705
706     ok_sequence(sequences, MONTHCAL_SEQ_INDEX, monthcal_unicode_seq, "monthcal unicode", FALSE);
707 }
708
709 static void test_monthcal_HitTest(HWND hwnd)
710 {
711     MCHITTESTINFO mchit;
712     int res;
713
714     memset(&mchit, 0, sizeof(MCHITTESTINFO));
715
716     flush_sequences(sequences, NUM_MSG_SEQUENCES);
717
718     /* Setters for HITTEST */
719
720     /* (0, 0) is the top left of the control and should not be active */
721     mchit.cbSize = sizeof(MCHITTESTINFO);
722     mchit.pt.x = 0;
723     mchit.pt.y = 0;
724     res = SendMessage(hwnd, MCM_HITTEST, 0, (LPARAM) & mchit);
725     expect(0, mchit.pt.x);
726     expect(0, mchit.pt.y);
727     expect(mchit.uHit, res);
728     todo_wine {expect(MCHT_NOWHERE, res);}
729
730     /* (300, 300) is the bottom right of the control and should not be active */
731     mchit.pt.x = 300;
732     mchit.pt.y = 300;
733     res = SendMessage(hwnd, MCM_HITTEST, 0, (LPARAM) & mchit);
734     expect(300, mchit.pt.x);
735     expect(300, mchit.pt.y);
736     expect(mchit.uHit, res);
737     todo_wine {expect(MCHT_NOWHERE, res);}
738
739     /* (500, 500) is completely out of the control and should not be active */
740     mchit.pt.x = 500;
741     mchit.pt.y = 500;
742     res = SendMessage(hwnd, MCM_HITTEST, 0, (LPARAM) & mchit);
743     expect(500, mchit.pt.x);
744     expect(500, mchit.pt.y);
745     expect(mchit.uHit, res);
746     todo_wine {expect(MCHT_NOWHERE, res);}
747
748     /* (150, 200) is in active area - calendar background */
749     mchit.pt.x = 150;
750     mchit.pt.y = 200;
751     res = SendMessage(hwnd, MCM_HITTEST, 0, (LPARAM) & mchit);
752     expect(150, mchit.pt.x);
753     expect(200, mchit.pt.y);
754     expect(mchit.uHit, res);
755     expect(MCHT_CALENDARBK, res);
756
757     /* (70, 20) is in active area - previous month button */
758     mchit.pt.x = 70;
759     mchit.pt.y = 20;
760     res = SendMessage(hwnd, MCM_HITTEST, 0, (LPARAM) & mchit);
761     expect(70, mchit.pt.x);
762     expect(20, mchit.pt.y);
763     expect(mchit.uHit, res);
764     todo_wine {expect(MCHT_TITLEBTNPREV, res);}
765
766     /* (90, 20) is in active area - background section of the title */
767     mchit.pt.x = 90;
768     mchit.pt.y = 20;
769     res = SendMessage(hwnd, MCM_HITTEST, 0, (LPARAM) & mchit);
770     expect(90, mchit.pt.x);
771     expect(20, mchit.pt.y);
772     expect(mchit.uHit, res);
773     todo_wine {expect(MCHT_TITLE, res);}
774
775     /* (150, 20) is in active area - month section of the title */
776     mchit.pt.x = 150;
777     mchit.pt.y = 20;
778     res = SendMessage(hwnd, MCM_HITTEST, 0, (LPARAM) & mchit);
779     expect(150, mchit.pt.x);
780     expect(20, mchit.pt.y);
781     expect(mchit.uHit, res);
782     todo_wine {expect(MCHT_TITLEMONTH, res);}
783
784     /* (230, 20) is in active area - previous month button */
785     mchit.pt.x = 230;
786     mchit.pt.y = 20;
787     res = SendMessage(hwnd, MCM_HITTEST, 0, (LPARAM) & mchit);
788     expect(230, mchit.pt.x);
789     expect(20, mchit.pt.y);
790     expect(mchit.uHit, res);
791     todo_wine {expect(MCHT_TITLEBTNNEXT, res);}
792
793     /* (70, 40) is in active area - day of the week */
794     mchit.pt.x = 70;
795     mchit.pt.y = 40;
796     res = SendMessage(hwnd, MCM_HITTEST, 0, (LPARAM) & mchit);
797     expect(70, mchit.pt.x);
798     expect(40, mchit.pt.y);
799     expect(mchit.uHit, res);
800     todo_wine {expect(MCHT_CALENDARDAY, res);}
801
802     /* (70, 55) is in active area - date from prev month */
803     mchit.pt.x = 70;
804     mchit.pt.y = 55;
805     res = SendMessage(hwnd, MCM_HITTEST, 0, (LPARAM) & mchit);
806     expect(70, mchit.pt.x);
807     expect(55, mchit.pt.y);
808     expect(mchit.uHit, res);
809     todo_wine {expect(MCHT_CALENDARDATEPREV, res);}
810
811     /* (125, 115) is in active area - date from this month */
812     mchit.pt.x = 125;
813     mchit.pt.y = 115;
814     res = SendMessage(hwnd, MCM_HITTEST, 0, (LPARAM) & mchit);
815     expect(125, mchit.pt.x);
816     expect(115, mchit.pt.y);
817     expect(mchit.uHit, res);
818     todo_wine {expect(MCHT_CALENDARDATE, res);}
819
820     /* (80, 160) is in active area - background section of the title */
821     mchit.pt.x = 80;
822     mchit.pt.y = 160;
823     res = SendMessage(hwnd, MCM_HITTEST, 0, (LPARAM) & mchit);
824     expect(80, mchit.pt.x);
825     expect(160, mchit.pt.y);
826     expect(mchit.uHit, res);
827     todo_wine {expect(MCHT_TITLEBK, res);}
828
829     /* (150, 160) is in active area - month section of the title */
830     mchit.pt.x = 150;
831     mchit.pt.y = 160;
832     res = SendMessage(hwnd, MCM_HITTEST, 0, (LPARAM) & mchit);
833     expect(150, mchit.pt.x);
834     expect(160, mchit.pt.y);
835     expect(mchit.uHit, res);
836     todo_wine {expect(MCHT_TITLEMONTH, res);}
837
838     /* (170, 160) is in active area - year section of the title */
839     mchit.pt.x = 170;
840     mchit.pt.y = 160;
841     res = SendMessage(hwnd, MCM_HITTEST, 0, (LPARAM) & mchit);
842     expect(170, mchit.pt.x);
843     expect(160, mchit.pt.y);
844     expect(mchit.uHit, res);
845     todo_wine {expect(MCHT_TITLEYEAR, res);}
846
847     /* (150, 240) is in active area - date from this month */
848     mchit.pt.x = 150;
849     mchit.pt.y = 240;
850     res = SendMessage(hwnd, MCM_HITTEST, 0, (LPARAM) & mchit);
851     expect(150, mchit.pt.x);
852     expect(240, mchit.pt.y);
853     expect(mchit.uHit, res);
854     todo_wine {expect(MCHT_CALENDARDATE, res);}
855
856     /* (150, 270) is in active area - date from next month */
857     mchit.pt.x = 150;
858     mchit.pt.y = 270;
859     res = SendMessage(hwnd, MCM_HITTEST, 0, (LPARAM) & mchit);
860     expect(150, mchit.pt.x);
861     expect(270, mchit.pt.y);
862     expect(mchit.uHit, res);
863     todo_wine {expect(MCHT_CALENDARDATENEXT, res);}
864
865     /* (150, 290) is in active area - today link */
866     mchit.pt.x = 150;
867     mchit.pt.y = 290;
868     res = SendMessage(hwnd, MCM_HITTEST, 0, (LPARAM) & mchit);
869     expect(150, mchit.pt.x);
870     expect(290, mchit.pt.y);
871     expect(mchit.uHit, res);
872     todo_wine {expect(MCHT_TODAYLINK, res);}
873
874     /* (70, 290) is in active area - today link */
875     mchit.pt.x = 70;
876     mchit.pt.y = 290;
877     res = SendMessage(hwnd, MCM_HITTEST, 0, (LPARAM) & mchit);
878     expect(70, mchit.pt.x);
879     expect(290, mchit.pt.y);
880     expect(mchit.uHit, res);
881     todo_wine {expect(MCHT_TODAYLINK, res);}
882
883     ok_sequence(sequences, MONTHCAL_SEQ_INDEX, monthcal_hit_test_seq, "monthcal hit test", FALSE);
884 }
885
886 static void test_monthcal_today(HWND hwnd)
887 {
888     SYSTEMTIME st_test, st_new;
889     int res;
890
891     flush_sequences(sequences, NUM_MSG_SEQUENCES);
892
893     /* Setter and Getters for "today" information */
894
895     /* check for overflow, should be ok */
896     st_test.wDay = 38;
897     st_test.wMonth = 38;
898
899     st_new.wDay = 27;
900     st_new.wMonth = 27;
901
902     SendMessage(hwnd, MCM_SETTODAY, 0, (LPARAM)&st_test);
903
904     res = SendMessage(hwnd, MCM_GETTODAY, 0, (LPARAM)&st_new);
905     expect(1, res);
906
907     /* st_test should not change */
908     expect(38, st_test.wDay);
909     expect(38, st_test.wMonth);
910
911     /* st_new should change, overflow does not matter */
912     expect(38, st_new.wDay);
913     expect(38, st_new.wMonth);
914
915     /* check for zero, should be ok*/
916     st_test.wDay = 0;
917     st_test.wMonth = 0;
918
919     SendMessage(hwnd, MCM_SETTODAY, 0, (LPARAM)&st_test);
920
921     res = SendMessage(hwnd, MCM_GETTODAY, 0, (LPARAM)&st_new);
922     expect(1, res);
923
924     /* st_test should not change */
925     expect(0, st_test.wDay);
926     expect(0, st_test.wMonth);
927
928     /* st_new should change to zero*/
929     expect(0, st_new.wDay);
930     expect(0, st_new.wMonth);
931
932     ok_sequence(sequences, MONTHCAL_SEQ_INDEX, monthcal_today_seq, "monthcal today", TRUE);
933 }
934
935 static void test_monthcal_scroll(HWND hwnd)
936 {
937     int res;
938
939     flush_sequences(sequences, NUM_MSG_SEQUENCES);
940
941     /* Setter and Getters for scroll rate */
942     res = SendMessage(hwnd, MCM_SETMONTHDELTA, 2, 0);
943     expect(0, res);
944
945     res = SendMessage(hwnd, MCM_SETMONTHDELTA, 3, 0);
946     expect(2, res);
947     res = SendMessage(hwnd, MCM_GETMONTHDELTA, 0, 0);
948     expect(3, res);
949
950     res = SendMessage(hwnd, MCM_SETMONTHDELTA, 12, 0);
951     expect(3, res);
952     res = SendMessage(hwnd, MCM_GETMONTHDELTA, 0, 0);
953     expect(12, res);
954
955     res = SendMessage(hwnd, MCM_SETMONTHDELTA, 15, 0);
956     expect(12, res);
957     res = SendMessage(hwnd, MCM_GETMONTHDELTA, 0, 0);
958     expect(15, res);
959
960     res = SendMessage(hwnd, MCM_SETMONTHDELTA, -5, 0);
961     expect(15, res);
962     res = SendMessage(hwnd, MCM_GETMONTHDELTA, 0, 0);
963     expect(-5, res);
964
965     ok_sequence(sequences, MONTHCAL_SEQ_INDEX, monthcal_scroll_seq, "monthcal scroll", FALSE);
966 }
967
968 static void test_monthcal_monthrange(HWND hwnd)
969 {
970     int res;
971     SYSTEMTIME st_visible[2], st_daystate[2];
972
973     flush_sequences(sequences, NUM_MSG_SEQUENCES);
974     st_visible[0].wYear = 0;
975     st_visible[0].wMonth = 0;
976     st_visible[0].wDay = 0;
977     st_daystate[1] = st_daystate[0] = st_visible[1] = st_visible[0];
978
979     res = SendMessage(hwnd, MCM_GETMONTHRANGE, GMR_VISIBLE, (LPARAM)st_visible);
980     todo_wine {
981         expect(2, res);
982         expect(2000, st_visible[0].wYear);
983         expect(11, st_visible[0].wMonth);
984         expect(1, st_visible[0].wDay);
985         expect(2000, st_visible[1].wYear);
986         expect(12, st_visible[1].wMonth);
987         expect(31, st_visible[1].wDay);
988     }
989     res = SendMessage(hwnd, MCM_GETMONTHRANGE, GMR_DAYSTATE, (LPARAM)st_daystate);
990     todo_wine {
991         expect(4, res);
992         expect(2000, st_daystate[0].wYear);
993         expect(10, st_daystate[0].wMonth);
994         expect(29, st_daystate[0].wDay);
995         expect(2001, st_daystate[1].wYear);
996         expect(1, st_daystate[1].wMonth);
997         expect(6, st_daystate[1].wDay);
998     }
999
1000     ok_sequence(sequences, MONTHCAL_SEQ_INDEX, monthcal_monthrange_seq, "monthcal monthrange", FALSE);
1001 }
1002
1003 static void test_monthcal_MaxSelDay(HWND hwnd)
1004 {
1005     int res;
1006
1007     flush_sequences(sequences, NUM_MSG_SEQUENCES);
1008
1009     /* Setter and Getters for max selected days */
1010     res = SendMessage(hwnd, MCM_SETMAXSELCOUNT, 5, 0);
1011     expect(1, res);
1012     res = SendMessage(hwnd, MCM_GETMAXSELCOUNT, 0, 0);
1013     expect(5, res);
1014
1015     res = SendMessage(hwnd, MCM_SETMAXSELCOUNT, 15, 0);
1016     expect(1, res);
1017     res = SendMessage(hwnd, MCM_GETMAXSELCOUNT, 0, 0);
1018     expect(15, res);
1019
1020     res = SendMessage(hwnd, MCM_SETMAXSELCOUNT, -1, 0);
1021     todo_wine {expect(0, res);}
1022     res = SendMessage(hwnd, MCM_GETMAXSELCOUNT, 0, 0);
1023     todo_wine {expect(15, res);}
1024
1025     ok_sequence(sequences, MONTHCAL_SEQ_INDEX, monthcal_max_sel_day_seq, "monthcal MaxSelDay", FALSE);
1026 }
1027
1028
1029 START_TEST(monthcal)
1030 {
1031     HWND hwnd, parent_wnd;
1032     test_monthcal();
1033
1034     init_msg_sequences(sequences, NUM_MSG_SEQUENCES);
1035
1036     parent_wnd = create_parent_window();
1037
1038     flush_sequences(sequences, NUM_MSG_SEQUENCES);
1039     hwnd = create_monthcal_control(WS_CHILD | WS_BORDER | WS_VISIBLE, parent_wnd);
1040     assert(hwnd);
1041     ok_sequence(sequences, PARENT_SEQ_INDEX, create_monthcal_control_seq, "create monthcal control", TRUE);
1042
1043     test_monthcal_color(hwnd);
1044     test_monthcal_currDate(hwnd);
1045     test_monthcal_firstDay(hwnd);
1046     test_monthcal_unicode(hwnd);
1047     test_monthcal_HitTest(hwnd);
1048     test_monthcal_today(hwnd);
1049     test_monthcal_scroll(hwnd);
1050     test_monthcal_monthrange(hwnd);
1051
1052     flush_sequences(sequences, NUM_MSG_SEQUENCES);
1053     DestroyWindow(hwnd);
1054     ok_sequence(sequences, PARENT_SEQ_INDEX, destroy_monthcal_parent_msgs_seq, "Destroy monthcal (parent msg)", FALSE);
1055     ok_sequence(sequences, MONTHCAL_SEQ_INDEX, destroy_monthcal_child_msgs_seq, "Destroy monthcal (child msg)", FALSE);
1056
1057     flush_sequences(sequences, NUM_MSG_SEQUENCES);
1058     hwnd = create_monthcal_control(MCS_MULTISELECT, parent_wnd);
1059     assert(hwnd);
1060     ok_sequence(sequences, PARENT_SEQ_INDEX, create_monthcal_multi_sel_style_seq, "create monthcal (multi sel style)", TRUE);
1061
1062     test_monthcal_MaxSelDay(hwnd);
1063
1064     flush_sequences(sequences, NUM_MSG_SEQUENCES);
1065     DestroyWindow(hwnd);
1066     ok_sequence(sequences, MONTHCAL_SEQ_INDEX, destroy_monthcal_multi_sel_style_seq, "Destroy monthcal (multi sel style)", FALSE);
1067
1068     flush_sequences(sequences, NUM_MSG_SEQUENCES);
1069     DestroyWindow(parent_wnd);
1070     ok_sequence(sequences, PARENT_SEQ_INDEX, destroy_parent_seq, "Destroy parent window", FALSE);
1071 }