quartz: Use proper alloc/free functions for COM objects.
[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
34 #define expect(expected, got) ok(expected == got, "Expected %d, got %d\n", expected, got);
35
36 static void test_monthcal(void)
37 {
38     HWND hwnd;
39     SYSTEMTIME st[2], st1[2];
40     INITCOMMONCONTROLSEX ic = {sizeof(INITCOMMONCONTROLSEX), ICC_DATE_CLASSES};
41     int res, month_range;
42
43     InitCommonControlsEx(&ic);
44     hwnd = CreateWindowA(MONTHCAL_CLASSA, "MonthCal", WS_POPUP | WS_VISIBLE, CW_USEDEFAULT,
45                          0, 300, 300, 0, 0, NULL, NULL);
46     ok(hwnd != NULL, "Failed to create MonthCal\n");
47     GetSystemTime(&st[0]);
48     st[1] = st[0];
49
50     /* Invalid date/time */
51     st[0].wYear  = 2000;
52     /* Time should not matter */
53     st[1].wHour = st[1].wMinute = st[1].wSecond = 70;
54     ok(SendMessage(hwnd, MCM_SETRANGE, GDTR_MAX, (LPARAM)st), "Failed to set MAX limit\n");
55     ok(SendMessage(hwnd, MCM_GETRANGE, 0, (LPARAM)st1) == GDTR_MAX, "No limits should be set\n");
56     ok(st1[0].wYear != 2000, "Lover limit changed\n");
57
58     st[1].wMonth = 0;
59     ok(!SendMessage(hwnd, MCM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st), "Should have failed to set limits\n");
60     ok(SendMessage(hwnd, MCM_GETRANGE, 0, (LPARAM)st1) == GDTR_MAX, "No limits should be set\n");
61     ok(st1[0].wYear != 2000, "Lover limit changed\n");
62     ok(!SendMessage(hwnd, MCM_SETRANGE, GDTR_MAX, (LPARAM)st), "Should have failed to set MAX limit\n");
63     ok(SendMessage(hwnd, MCM_GETRANGE, 0, (LPARAM)st1) == GDTR_MAX, "No limits should be set\n");
64     ok(st1[0].wYear != 2000, "Lover limit changed\n");
65
66     GetSystemTime(&st[0]);
67     st[0].wDay = 20;
68     st[0].wMonth = 5;
69     st[1] = st[0];
70
71     month_range = SendMessage(hwnd, MCM_GETMONTHRANGE, GMR_VISIBLE, (LPARAM)st1);
72     st[1].wMonth--;
73     ok(SendMessage(hwnd, MCM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st), "Failed to set both min and max limits\n");
74     res = SendMessage(hwnd, MCM_GETMONTHRANGE, GMR_VISIBLE, (LPARAM)st1);
75     ok(res == month_range, "Invalid month range (%d)\n", res);
76     ok(SendMessage(hwnd, MCM_GETRANGE, 0, (LPARAM)st1) == (GDTR_MIN|GDTR_MAX), "Limits should be set\n");
77
78     st[1].wMonth += 2;
79     ok(SendMessage(hwnd, MCM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st), "Failed to set both min and max limits\n");
80     res = SendMessage(hwnd, MCM_GETMONTHRANGE, GMR_VISIBLE, (LPARAM)st1);
81     ok(res == month_range, "Invalid month range (%d)\n", res);
82
83     st[1].wYear --;
84     ok(SendMessage(hwnd, MCM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st), "Failed to set both min and max limits\n");
85     st[1].wYear += 1;
86     ok(SendMessage(hwnd, MCM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st), "Failed to set both min and max limits\n");
87
88     st[1].wMonth -= 3;
89     ok(SendMessage(hwnd, MCM_SETRANGE, GDTR_MAX, (LPARAM)st), "Failed to set max limit\n");
90     ok(SendMessage(hwnd, MCM_GETRANGE, 0, (LPARAM)st1) == GDTR_MAX, "Only MAX limit should be set\n");
91     st[1].wMonth += 4;
92     ok(SendMessage(hwnd, MCM_SETRANGE, GDTR_MAX, (LPARAM)st), "Failed to set max limit\n");
93     st[1].wYear -= 3;
94     ok(SendMessage(hwnd, MCM_SETRANGE, GDTR_MAX, (LPARAM)st), "Failed to set max limit\n");
95     st[1].wYear += 4;
96     ok(SendMessage(hwnd, MCM_SETRANGE, GDTR_MAX, (LPARAM)st), "Failed to set max limit\n");
97     ok(SendMessage(hwnd, MCM_GETRANGE, 0, (LPARAM)st1) == GDTR_MAX, "Only MAX limit should be set\n");
98
99     DestroyWindow(hwnd);
100 }
101
102 static HWND create_monthcal_control(DWORD style)
103 {
104     HWND hwnd;
105     static const INITCOMMONCONTROLSEX ic = {sizeof(INITCOMMONCONTROLSEX), ICC_DATE_CLASSES};
106
107     InitCommonControlsEx(&ic);
108
109     hwnd = CreateWindowEx(0,
110                     MONTHCAL_CLASS,
111                     "",
112                     style,
113                     0, 300, 300, 0, NULL, NULL, NULL, NULL);
114
115     assert(hwnd);
116     return hwnd;
117 }
118
119 static void test_monthcal_color(HWND hwnd)
120 {
121     int res, temp;
122
123     /* Setter and Getters for color*/
124     temp = SendMessage(hwnd, MCM_GETCOLOR, MCSC_BACKGROUND, 0);
125     res = SendMessage(hwnd, MCM_SETCOLOR, MCSC_BACKGROUND, RGB(0,0,0));
126     expect(temp, res);
127     temp = SendMessage(hwnd, MCM_GETCOLOR, MCSC_BACKGROUND, 0);
128     expect(RGB(0,0,0), temp);
129     res = SendMessage(hwnd, MCM_SETCOLOR, MCSC_BACKGROUND, RGB(255,255,255));
130     expect(temp, res);
131     temp = SendMessage(hwnd, MCM_GETCOLOR, MCSC_BACKGROUND, 0);
132     expect(RGB(255,255,255), temp);
133
134     temp = SendMessage(hwnd, MCM_GETCOLOR, MCSC_MONTHBK, 0);
135     res = SendMessage(hwnd, MCM_SETCOLOR, MCSC_MONTHBK, RGB(0,0,0));
136     expect(temp, res);
137     temp = SendMessage(hwnd, MCM_GETCOLOR, MCSC_MONTHBK, 0);
138     expect(RGB(0,0,0), temp);
139     res = SendMessage(hwnd, MCM_SETCOLOR, MCSC_MONTHBK, RGB(255,255,255));
140     expect(temp, res);
141     temp = SendMessage(hwnd, MCM_GETCOLOR, MCSC_MONTHBK, 0);
142     expect(RGB(255,255,255), temp);
143
144     temp = SendMessage(hwnd, MCM_GETCOLOR, MCSC_TEXT, 0);
145     res = SendMessage(hwnd, MCM_SETCOLOR, MCSC_TEXT, RGB(0,0,0));
146     expect(temp, res);
147     temp = SendMessage(hwnd, MCM_GETCOLOR, MCSC_TEXT, 0);
148     expect(RGB(0,0,0), temp);
149     res = SendMessage(hwnd, MCM_SETCOLOR, MCSC_TEXT, RGB(255,255,255));
150     expect(temp, res);
151     temp = SendMessage(hwnd, MCM_GETCOLOR, MCSC_TEXT, 0);
152     expect(RGB(255,255,255), temp);
153
154     temp = SendMessage(hwnd, MCM_GETCOLOR, MCSC_TITLEBK, 0);
155     res = SendMessage(hwnd, MCM_SETCOLOR, MCSC_TITLEBK, RGB(0,0,0));
156     expect(temp, res);
157     temp = SendMessage(hwnd, MCM_GETCOLOR, MCSC_TITLEBK, 0);
158     expect(RGB(0,0,0), temp);
159     res = SendMessage(hwnd, MCM_SETCOLOR, MCSC_TITLEBK, RGB(255,255,255));
160     expect(temp, res);
161     temp = SendMessage(hwnd, MCM_GETCOLOR, MCSC_TITLEBK, 0);
162     expect(RGB(255,255,255), temp);
163
164     temp = SendMessage(hwnd, MCM_GETCOLOR, MCSC_TITLETEXT, 0);
165     res = SendMessage(hwnd, MCM_SETCOLOR, MCSC_TITLETEXT, RGB(0,0,0));
166     expect(temp, res);
167     temp = SendMessage(hwnd, MCM_GETCOLOR, MCSC_TITLETEXT, 0);
168     expect(RGB(0,0,0), temp);
169     res = SendMessage(hwnd, MCM_SETCOLOR, MCSC_TITLETEXT, RGB(255,255,255));
170     expect(temp, res);
171     temp = SendMessage(hwnd, MCM_GETCOLOR, MCSC_TITLETEXT, 0);
172     expect(RGB(255,255,255), temp);
173
174     temp = SendMessage(hwnd, MCM_GETCOLOR, MCSC_TRAILINGTEXT, 0);
175     res = SendMessage(hwnd, MCM_SETCOLOR, MCSC_TRAILINGTEXT, RGB(0,0,0));
176     expect(temp, res);
177     temp = SendMessage(hwnd, MCM_GETCOLOR, MCSC_TRAILINGTEXT, 0);
178     expect(RGB(0,0,0), temp);
179     res = SendMessage(hwnd, MCM_SETCOLOR, MCSC_TRAILINGTEXT, RGB(255,255,255));
180     expect(temp, res);
181     temp = SendMessage(hwnd, MCM_GETCOLOR, MCSC_TRAILINGTEXT, 0);
182     expect(RGB(255,255,255), temp);
183 }
184
185 static void test_monthcal_currDate(HWND hwnd)
186 {
187     SYSTEMTIME st_original, st_new, st_test;
188     int res;
189
190     /* Setter and Getters for current date selected */
191     st_original.wYear = 2000;
192     st_original.wMonth = 11;
193     st_original.wDay = 28;
194     st_original.wHour = 11;
195     st_original.wMinute = 59;
196     st_original.wSecond = 30;
197     st_original.wMilliseconds = 0;
198     st_original.wDayOfWeek = 0;
199
200     st_new = st_test = st_original;
201
202     /* Should not validate the time */
203     res = SendMessage(hwnd, MCM_SETCURSEL, 0, (LPARAM)&st_test);
204     expect(1,res);
205
206     /* Overflow matters, check for wDay */
207     st_test.wDay += 4;
208     res = SendMessage(hwnd, MCM_SETCURSEL, 0, (LPARAM)&st_test);
209     todo_wine {expect(0,res);}
210
211     /* correct wDay before checking for wMonth */
212     st_test.wDay -= 4;
213     expect(st_original.wDay, st_test.wDay);
214
215     /* Overflow matters, check for wMonth */
216     st_test.wMonth += 4;
217     res = SendMessage(hwnd, MCM_SETCURSEL, 0, (LPARAM)&st_test);
218     todo_wine {expect(0,res);}
219
220     /* checking if gets the information right, modify st_new */
221     st_new.wYear += 4;
222     st_new.wMonth += 4;
223     st_new.wDay += 4;
224     st_new.wHour += 4;
225     st_new.wMinute += 4;
226     st_new.wSecond += 4;
227
228     res = SendMessage(hwnd, MCM_GETCURSEL, 0, (LPARAM)&st_new);
229     expect(1, res);
230
231     /* st_new change to st_origin, above settings with overflow */
232     /* should not change the current settings */
233     expect(st_original.wYear, st_new.wYear);
234     todo_wine {expect(st_original.wMonth, st_new.wMonth);}
235     expect(st_original.wDay, st_new.wDay);
236     expect(st_original.wHour, st_new.wHour);
237     expect(st_original.wMinute, st_new.wMinute);
238     expect(st_original.wSecond, st_new.wSecond);
239
240     /* lparam cannot be NULL */
241     res = SendMessage(hwnd, MCM_GETCURSEL, 0, (LPARAM) NULL);
242     expect(0, res);
243 }
244
245 static void test_monthcal_firstDay(HWND hwnd)
246 {
247     int res, fday, i, temp;
248     TCHAR b[128];
249     LCID lcid = LOCALE_USER_DEFAULT;
250
251     /* Setter and Getters for first day of week */
252     todo_wine {
253         /* check for locale first day */
254         if(GetLocaleInfo(lcid, LOCALE_IFIRSTDAYOFWEEK, b, 128)){
255             fday = atoi(b);
256             res = SendMessage(hwnd, MCM_GETFIRSTDAYOFWEEK, 0, 0);
257             expect(fday, res);
258             res = SendMessage(hwnd, MCM_SETFIRSTDAYOFWEEK, 0, (LPARAM) 0);
259             expect(fday, res);
260         }else{
261             skip("Cannot retrieve first day of the week\n");
262             SendMessage(hwnd, MCM_SETFIRSTDAYOFWEEK, 0, (LPARAM) 0);
263         }
264
265         /* check for days of the week*/
266         for (i = 1, temp = 0x10000; i < 7; i++, temp++){
267             res = SendMessage(hwnd, MCM_GETFIRSTDAYOFWEEK, 0, 0);
268             expect(temp, res);
269             res = SendMessage(hwnd, MCM_SETFIRSTDAYOFWEEK, 0, (LPARAM) i);
270             expect(temp, res);
271         }
272
273         /* check for returning to the original first day */
274         res = SendMessage(hwnd, MCM_GETFIRSTDAYOFWEEK, 0, 0);
275         todo_wine {expect(temp, res);}
276     }
277 }
278
279 static void test_monthcal_unicode(HWND hwnd)
280 {
281     int res, temp;
282
283     /* Setter and Getters for Unicode format */
284
285     /* getting the current settings */
286     temp = SendMessage(hwnd, MCM_GETUNICODEFORMAT, 0, 0);
287
288     /* setting to 1, should return previous settings */
289     res = SendMessage(hwnd, MCM_SETUNICODEFORMAT, 1, 0);
290     expect(temp, res);
291
292     /* current setting is 1, so, should return 1 */
293     res = SendMessage(hwnd, MCM_GETUNICODEFORMAT, 0, 0);
294     todo_wine {expect(1, res);}
295
296     /* setting to 0, should return previous settings */
297     res = SendMessage(hwnd, MCM_SETUNICODEFORMAT, 0, 0);
298     todo_wine {expect(1, res);}
299
300     /* current setting is 0, so, it should return 0 */
301     res = SendMessage(hwnd, MCM_GETUNICODEFORMAT, 0, 0);
302     expect(0, res);
303
304     /* should return previous settings */
305     res = SendMessage(hwnd, MCM_SETUNICODEFORMAT, 1, 0);
306     expect(0, res);
307 }
308
309 static void test_monthcal_HitTest(HWND hwnd)
310 {
311     MCHITTESTINFO mchit;
312     int res;
313
314     memset(&mchit, 0, sizeof(MCHITTESTINFO));
315
316     /* Setters for HITTEST */
317
318     /* (0, 0) is the top left of the control and should not be active */
319     mchit.cbSize = sizeof(MCHITTESTINFO);
320     mchit.pt.x = 0;
321     mchit.pt.y = 0;
322     res = SendMessage(hwnd, MCM_HITTEST, 0, (LPARAM) & mchit);
323     expect(0, mchit.pt.x);
324     expect(0, mchit.pt.y);
325     expect(mchit.uHit, res);
326     todo_wine {expect(MCHT_NOWHERE, res);}
327
328     /* (300, 300) is the bottom right of the control and should not be active */
329     mchit.pt.x = 300;
330     mchit.pt.y = 300;
331     res = SendMessage(hwnd, MCM_HITTEST, 0, (LPARAM) & mchit);
332     expect(300, mchit.pt.x);
333     expect(300, mchit.pt.y);
334     expect(mchit.uHit, res);
335     todo_wine {expect(MCHT_NOWHERE, res);}
336
337     /* (500, 500) is completely out of the control and should not be active */
338     mchit.pt.x = 500;
339     mchit.pt.y = 500;
340     res = SendMessage(hwnd, MCM_HITTEST, 0, (LPARAM) & mchit);
341     expect(500, mchit.pt.x);
342     expect(500, mchit.pt.y);
343     expect(mchit.uHit, res);
344     todo_wine {expect(MCHT_NOWHERE, res);}
345
346     /* (150, 200) is in active area */
347     mchit.pt.x = 150;
348     mchit.pt.y = 200;
349     res = SendMessage(hwnd, MCM_HITTEST, 0, (LPARAM) & mchit);
350     expect(150, mchit.pt.x);
351     expect(200, mchit.pt.y);
352     expect(mchit.uHit, res);
353 }
354
355 static void test_monthcal_today(HWND hwnd)
356 {
357     SYSTEMTIME st_test, st_new;
358     int res;
359
360     /* Setter and Getters for "today" information */
361
362     /* check for overflow, should be ok */
363     st_test.wDay = 38;
364     st_test.wMonth = 38;
365
366     st_new.wDay = 27;
367     st_new.wMonth = 27;
368
369     SendMessage(hwnd, MCM_SETTODAY, 0, (LPARAM)&st_test);
370
371     res = SendMessage(hwnd, MCM_GETTODAY, 0, (LPARAM)&st_new);
372     expect(1, res);
373
374     /* st_test should not change */
375     expect(38, st_test.wDay);
376     expect(38, st_test.wMonth);
377
378     /* st_new should change, overflow does not matter */
379     expect(38, st_new.wDay);
380     expect(38, st_new.wMonth);
381
382     /* check for zero, should be ok*/
383     st_test.wDay = 0;
384     st_test.wMonth = 0;
385
386     SendMessage(hwnd, MCM_SETTODAY, 0, (LPARAM)&st_test);
387
388     res = SendMessage(hwnd, MCM_GETTODAY, 0, (LPARAM)&st_new);
389     expect(1, res);
390
391     /* st_test should not change */
392     expect(0, st_test.wDay);
393     expect(0, st_test.wMonth);
394
395     /* st_new should change to zero*/
396     expect(0, st_new.wDay);
397     expect(0, st_new.wMonth);
398 }
399
400 static void test_monthcal_scroll(HWND hwnd)
401 {
402     int res;
403
404     /* Setter and Getters for scroll rate */
405     res = SendMessage(hwnd, MCM_SETMONTHDELTA, 2, 0);
406     expect(0, res);
407
408     res = SendMessage(hwnd, MCM_SETMONTHDELTA, 3, 0);
409     expect(2, res);
410     res = SendMessage(hwnd, MCM_GETMONTHDELTA, 0, 0);
411     expect(3, res);
412
413     res = SendMessage(hwnd, MCM_SETMONTHDELTA, 12, 0);
414     expect(3, res);
415     res = SendMessage(hwnd, MCM_GETMONTHDELTA, 0, 0);
416     expect(12, res);
417
418     res = SendMessage(hwnd, MCM_SETMONTHDELTA, 15, 0);
419     expect(12, res);
420     res = SendMessage(hwnd, MCM_GETMONTHDELTA, 0, 0);
421     expect(15, res);
422
423     res = SendMessage(hwnd, MCM_SETMONTHDELTA, -5, 0);
424     expect(15, res);
425     res = SendMessage(hwnd, MCM_GETMONTHDELTA, 0, 0);
426     expect(-5, res);
427 }
428
429 static void test_monthcal_MaxSelDay(HWND hwnd)
430 {
431     int res;
432
433     /* Setter and Getters for max selected days */
434     res = SendMessage(hwnd, MCM_SETMAXSELCOUNT, 5, 0);
435     expect(1, res);
436     res = SendMessage(hwnd, MCM_GETMAXSELCOUNT, 0, 0);
437     expect(5, res);
438
439     res = SendMessage(hwnd, MCM_SETMAXSELCOUNT, 15, 0);
440     expect(1, res);
441     res = SendMessage(hwnd, MCM_GETMAXSELCOUNT, 0, 0);
442     expect(15, res);
443
444     res = SendMessage(hwnd, MCM_SETMAXSELCOUNT, -1, 0);
445     todo_wine {expect(0, res);}
446     res = SendMessage(hwnd, MCM_GETMAXSELCOUNT, 0, 0);
447     todo_wine {expect(15, res);}
448 }
449
450
451 START_TEST(monthcal)
452 {
453     HWND hwnd;
454     test_monthcal();
455
456     hwnd = create_monthcal_control(0);
457     test_monthcal_color(hwnd);
458     test_monthcal_currDate(hwnd);
459     test_monthcal_firstDay(hwnd);
460     test_monthcal_unicode(hwnd);
461     test_monthcal_HitTest(hwnd);
462     test_monthcal_today(hwnd);
463     test_monthcal_scroll(hwnd);
464
465     DestroyWindow(hwnd);
466     hwnd = create_monthcal_control(MCS_MULTISELECT);
467
468     test_monthcal_MaxSelDay(hwnd);
469
470     DestroyWindow(hwnd);
471 }