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 "v6util.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 #define expect_hex(expected, got) ok(expected == got, "Expected %x, got %x\n", expected, got); 37 #define expect_d(expected, got) ok(abs((expected) - (got)) <= 2, "Expected %d, got %d\n", expected, got); 38 39 #define NUM_MSG_SEQUENCES 2 40 #define PARENT_SEQ_INDEX 0 41 #define MONTHCAL_SEQ_INDEX 1 42 43 #define SEL_NOTIFY_TEST_ID 100 44 45 static BOOL (WINAPI *pInitCommonControlsEx)(const INITCOMMONCONTROLSEX*); 46 47 static struct msg_sequence *sequences[NUM_MSG_SEQUENCES]; 48 49 static HWND parent_wnd; 50 51 static const struct message create_parent_window_seq[] = { 52 { WM_GETMINMAXINFO, sent }, 53 { WM_NCCREATE, sent }, 54 { WM_NCCALCSIZE, sent|wparam, 0 }, 55 { WM_CREATE, sent }, 56 { WM_SHOWWINDOW, sent|wparam, 1 }, 57 { WM_WINDOWPOSCHANGING, sent|wparam, 0 }, 58 { WM_QUERYNEWPALETTE, sent|optional }, 59 { WM_WINDOWPOSCHANGING, sent|wparam|optional, 0 }, 60 { WM_WINDOWPOSCHANGED, sent|optional }, 61 { WM_ACTIVATEAPP, sent|wparam, 1 }, 62 { WM_NCACTIVATE, sent }, 63 { WM_ACTIVATE, sent|wparam, 1 }, 64 { WM_IME_SETCONTEXT, sent|wparam|defwinproc|optional, 1 }, 65 { WM_IME_NOTIFY, sent|defwinproc|optional }, 66 { WM_SETFOCUS, sent|wparam|defwinproc, 0 }, 67 /* Win9x adds SWP_NOZORDER below */ 68 { WM_WINDOWPOSCHANGED, sent, /*|wparam, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE*/ }, 69 { WM_NCCALCSIZE, sent|wparam|optional, 1 }, 70 { WM_SIZE, sent }, 71 { WM_MOVE, sent }, 72 { 0 } 73 }; 74 75 static const struct message create_monthcal_control_seq[] = { 76 { WM_NOTIFYFORMAT, sent|lparam, 0, NF_QUERY }, 77 { WM_QUERYUISTATE, sent|optional }, 78 { WM_GETFONT, sent }, 79 { WM_PARENTNOTIFY, sent|wparam, WM_CREATE}, 80 { 0 } 81 }; 82 83 static const struct message create_monthcal_multi_sel_style_seq[] = { 84 { WM_NOTIFYFORMAT, sent|lparam, 0, NF_QUERY }, 85 { WM_QUERYUISTATE, sent|optional }, 86 { WM_GETFONT, sent }, 87 { WM_PARENTNOTIFY, sent }, 88 { 0 } 89 }; 90 91 static const struct message monthcal_curr_date_seq[] = { 92 { MCM_SETCURSEL, sent|wparam, 0}, 93 { WM_PAINT, sent|wparam|lparam|defwinproc, 0, 0}, 94 { MCM_SETCURSEL, sent|wparam, 0}, 95 { MCM_SETCURSEL, sent|wparam, 0}, 96 { MCM_GETCURSEL, sent|wparam, 0}, 97 { MCM_GETCURSEL, sent|wparam|lparam, 0, 0}, 98 { 0 } 99 }; 100 101 static const struct message monthcal_first_day_seq[] = { 102 { MCM_GETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 0}, 103 104 { MCM_SETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, -5}, 105 { MCM_GETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 0}, 106 107 { MCM_SETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, -4}, 108 { MCM_GETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 0}, 109 110 { MCM_SETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, -3}, 111 { MCM_GETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 0}, 112 113 { MCM_SETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, -2}, 114 { MCM_GETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 0}, 115 116 { MCM_SETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, -1}, 117 { MCM_GETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 0}, 118 119 { MCM_SETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 0}, 120 { MCM_GETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 0}, 121 122 { MCM_SETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 1}, 123 { MCM_GETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 0}, 124 125 { MCM_SETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 2}, 126 { MCM_GETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 0}, 127 128 { MCM_SETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 3}, 129 { MCM_GETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 0}, 130 131 { MCM_SETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 4}, 132 { MCM_GETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 0}, 133 134 { MCM_SETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 5}, 135 { MCM_GETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 0}, 136 137 { MCM_SETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 6}, 138 { MCM_GETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 0}, 139 140 { MCM_SETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 7}, 141 { MCM_GETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 0}, 142 143 { MCM_SETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 8}, 144 { MCM_GETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 0}, 145 146 { MCM_SETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 9}, 147 { MCM_GETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 0}, 148 149 { MCM_SETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 10}, 150 { MCM_GETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 0}, 151 152 { MCM_SETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 11}, 153 { MCM_GETFIRSTDAYOFWEEK, sent|wparam|lparam, 0, 0}, 154 { 0 } 155 }; 156 157 static const struct message monthcal_unicode_seq[] = { 158 { MCM_GETUNICODEFORMAT, sent|wparam|lparam, 0, 0}, 159 { MCM_SETUNICODEFORMAT, sent|wparam|lparam, 1, 0}, 160 { MCM_GETUNICODEFORMAT, sent|wparam|lparam, 0, 0}, 161 { MCM_SETUNICODEFORMAT, sent|wparam|lparam, 0, 0}, 162 { MCM_GETUNICODEFORMAT, sent|wparam|lparam, 0, 0}, 163 { MCM_SETUNICODEFORMAT, sent|wparam|lparam, 1, 0}, 164 { 0 } 165 }; 166 167 static const struct message monthcal_hit_test_seq[] = { 168 { MCM_SETCURSEL, sent|wparam, 0}, 169 { WM_PAINT, sent|wparam|lparam|defwinproc, 0, 0}, 170 { MCM_HITTEST, sent|wparam, 0}, 171 { MCM_HITTEST, sent|wparam, 0}, 172 { MCM_HITTEST, sent|wparam, 0}, 173 { MCM_HITTEST, sent|wparam, 0}, 174 { MCM_HITTEST, sent|wparam, 0}, 175 { MCM_HITTEST, sent|wparam, 0}, 176 { MCM_HITTEST, sent|wparam, 0}, 177 { MCM_HITTEST, sent|wparam, 0}, 178 { MCM_HITTEST, sent|wparam, 0}, 179 { MCM_HITTEST, sent|wparam, 0}, 180 { 0 } 181 }; 182 183 static const struct message monthcal_todaylink_seq[] = { 184 { MCM_HITTEST, sent|wparam, 0}, 185 { MCM_SETTODAY, sent|wparam, 0}, 186 { WM_PAINT, sent|wparam|lparam|defwinproc, 0, 0}, 187 { MCM_GETTODAY, sent|wparam, 0}, 188 { WM_LBUTTONDOWN, sent|wparam, MK_LBUTTON}, 189 { WM_CAPTURECHANGED, sent|wparam|lparam|defwinproc, 0, 0}, 190 { WM_PAINT, sent|wparam|lparam|defwinproc, 0, 0}, 191 { MCM_GETCURSEL, sent|wparam, 0}, 192 { 0 } 193 }; 194 195 static const struct message monthcal_today_seq[] = { 196 { MCM_SETTODAY, sent|wparam, 0}, 197 { WM_PAINT, sent|wparam|lparam|defwinproc, 0, 0}, 198 { MCM_GETTODAY, sent|wparam, 0}, 199 { MCM_SETTODAY, sent|wparam, 0}, 200 { WM_PAINT, sent|wparam|lparam|defwinproc, 0, 0}, 201 { MCM_GETTODAY, sent|wparam, 0}, 202 { 0 } 203 }; 204 205 static const struct message monthcal_scroll_seq[] = { 206 { MCM_SETMONTHDELTA, sent|wparam|lparam, 2, 0}, 207 { MCM_SETMONTHDELTA, sent|wparam|lparam, 3, 0}, 208 { MCM_GETMONTHDELTA, sent|wparam|lparam, 0, 0}, 209 { MCM_SETMONTHDELTA, sent|wparam|lparam, 12, 0}, 210 { MCM_GETMONTHDELTA, sent|wparam|lparam, 0, 0}, 211 { MCM_SETMONTHDELTA, sent|wparam|lparam, 15, 0}, 212 { MCM_GETMONTHDELTA, sent|wparam|lparam, 0, 0}, 213 { MCM_SETMONTHDELTA, sent|wparam|lparam, -5, 0}, 214 { MCM_GETMONTHDELTA, sent|wparam|lparam, 0, 0}, 215 { 0 } 216 }; 217 218 static const struct message monthcal_monthrange_seq[] = { 219 { MCM_GETMONTHRANGE, sent|wparam, GMR_VISIBLE}, 220 { MCM_GETMONTHRANGE, sent|wparam, GMR_DAYSTATE}, 221 { 0 } 222 }; 223 224 static const struct message monthcal_max_sel_day_seq[] = { 225 { MCM_SETMAXSELCOUNT, sent|wparam|lparam, 5, 0}, 226 { MCM_GETMAXSELCOUNT, sent|wparam|lparam, 0, 0}, 227 { MCM_SETMAXSELCOUNT, sent|wparam|lparam, 15, 0}, 228 { MCM_GETMAXSELCOUNT, sent|wparam|lparam, 0, 0}, 229 { MCM_SETMAXSELCOUNT, sent|wparam|lparam, -1, 0}, 230 { MCM_GETMAXSELCOUNT, sent|wparam|lparam, 0, 0}, 231 { 0 } 232 }; 233 234 /* expected message sequence for parent*/ 235 static const struct message destroy_monthcal_parent_msgs_seq[] = { 236 { WM_PARENTNOTIFY, sent|wparam, WM_DESTROY}, 237 { 0 } 238 }; 239 240 /* expected message sequence for child*/ 241 static const struct message destroy_monthcal_child_msgs_seq[] = { 242 { 0x0090, sent|optional }, /* Vista */ 243 { WM_SHOWWINDOW, sent|wparam|lparam, 0, 0}, 244 { WM_WINDOWPOSCHANGING, sent|wparam, 0}, 245 { WM_WINDOWPOSCHANGED, sent|wparam, 0}, 246 { WM_DESTROY, sent|wparam|lparam, 0, 0}, 247 { WM_NCDESTROY, sent|wparam|lparam, 0, 0}, 248 { 0 } 249 }; 250 251 static const struct message destroy_monthcal_multi_sel_style_seq[] = { 252 { 0x0090, sent|optional }, /* Vista */ 253 { WM_SHOWWINDOW, sent|wparam|lparam, 0, 0}, 254 { WM_WINDOWPOSCHANGING, sent|wparam, 0}, 255 { WM_WINDOWPOSCHANGED, sent|wparam, 0}, 256 { WM_DESTROY, sent|wparam|lparam, 0, 0}, 257 { WM_NCDESTROY, sent|wparam|lparam, 0, 0}, 258 { 0 } 259 }; 260 261 static void test_monthcal(void) 262 { 263 HWND hwnd; 264 SYSTEMTIME st[2], st1[2], today; 265 int res, month_range; 266 DWORD limits; 267 BOOL r; 268 269 hwnd = CreateWindowA(MONTHCAL_CLASSA, "MonthCal", WS_POPUP | WS_VISIBLE, CW_USEDEFAULT, 270 0, 300, 300, 0, 0, NULL, NULL); 271 ok(hwnd != NULL, "Failed to create MonthCal\n"); 272 273 /* test range just after creation */ 274 memset(&st, 0xcc, sizeof(st)); 275 limits = SendMessageA(hwnd, MCM_GETRANGE, 0, (LPARAM)st); 276 ok(limits == 0 || 277 broken(limits == GDTR_MIN), /* comctl32 <= 4.70 */ 278 "No limits should be set (%d)\n", limits); 279 if (limits == GDTR_MIN) 280 { 281 win_skip("comctl32 <= 4.70 is broken\n"); 282 DestroyWindow(hwnd); 283 return; 284 } 285 286 ok(0 == st[0].wYear || 287 broken(1752 == st[0].wYear), /* comctl32 <= 4.72 */ 288 "Expected 0, got %d\n", st[0].wYear); 289 ok(0 == st[0].wMonth || 290 broken(9 == st[0].wMonth), /* comctl32 <= 4.72 */ 291 "Expected 0, got %d\n", st[0].wMonth); 292 ok(0 == st[0].wDay || 293 broken(14 == st[0].wDay), /* comctl32 <= 4.72 */ 294 "Expected 0, got %d\n", st[0].wDay); 295 expect(0, st[0].wDayOfWeek); 296 expect(0, st[0].wHour); 297 expect(0, st[0].wMinute); 298 expect(0, st[0].wSecond); 299 expect(0, st[0].wMilliseconds); 300 301 expect(0, st[1].wYear); 302 expect(0, st[1].wMonth); 303 expect(0, st[1].wDay); 304 expect(0, st[1].wDayOfWeek); 305 expect(0, st[1].wHour); 306 expect(0, st[1].wMinute); 307 expect(0, st[1].wSecond); 308 expect(0, st[1].wMilliseconds); 309 310 limits = SendMessageA(hwnd, MCM_GETRANGE, 0, 0); 311 ok(limits == 0, "got %u\n", limits); 312 313 GetSystemTime(&st[0]); 314 st[1] = st[0]; 315 316 SendMessageA(hwnd, MCM_GETTODAY, 0, (LPARAM)&today); 317 318 /* Invalid date/time */ 319 st[0].wYear = 2000; 320 /* Time should not matter */ 321 st[1].wHour = st[1].wMinute = st[1].wSecond = 70; 322 st[1].wMilliseconds = 1200; 323 ok(SendMessageA(hwnd, MCM_SETRANGE, GDTR_MAX, (LPARAM)st), "Failed to set MAX limit\n"); 324 /* invalid timestamp is written back with today data and msecs untouched */ 325 expect(today.wHour, st[1].wHour); 326 expect(today.wMinute, st[1].wMinute); 327 expect(today.wSecond, st[1].wSecond); 328 expect(1200, st[1].wMilliseconds); 329 330 ok(SendMessageA(hwnd, MCM_GETRANGE, 0, (LPARAM)st1) == GDTR_MAX, "No limits should be set\n"); 331 ok(st1[0].wYear != 2000, "Lower limit changed\n"); 332 /* invalid timestamp should be replaced with today data, except msecs */ 333 expect(today.wHour, st1[1].wHour); 334 expect(today.wMinute, st1[1].wMinute); 335 expect(today.wSecond, st1[1].wSecond); 336 expect(1200, st1[1].wMilliseconds); 337 338 /* Invalid date/time with invalid milliseconds only */ 339 GetSystemTime(&st[0]); 340 st[1] = st[0]; 341 /* Time should not matter */ 342 st[1].wMilliseconds = 1200; 343 ok(SendMessageA(hwnd, MCM_SETRANGE, GDTR_MAX, (LPARAM)st), "Failed to set MAX limit\n"); 344 /* invalid milliseconds field doesn't lead to invalid timestamp */ 345 expect(st[0].wHour, st[1].wHour); 346 expect(st[0].wMinute, st[1].wMinute); 347 expect(st[0].wSecond, st[1].wSecond); 348 expect(1200, st[1].wMilliseconds); 349 350 GetSystemTime(&st[0]); 351 352 st[1].wMonth = 0; 353 ok(!SendMessageA(hwnd, MCM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st), 354 "Should have failed to set limits\n"); 355 ok(SendMessageA(hwnd, MCM_GETRANGE, 0, (LPARAM)st1) == GDTR_MAX, "No limits should be set\n"); 356 ok(st1[0].wYear != 2000, "Lower limit changed\n"); 357 ok(!SendMessageA(hwnd, MCM_SETRANGE, GDTR_MAX, (LPARAM)st), 358 "Should have failed to set MAX limit\n"); 359 ok(SendMessageA(hwnd, MCM_GETRANGE, 0, (LPARAM)st1) == GDTR_MAX, "No limits should be set\n"); 360 ok(st1[0].wYear != 2000, "Lower limit changed\n"); 361 362 GetSystemTime(&st[0]); 363 st[0].wDay = 20; 364 st[0].wMonth = 5; 365 st[1] = st[0]; 366 367 month_range = SendMessageA(hwnd, MCM_GETMONTHRANGE, GMR_VISIBLE, (LPARAM)st1); 368 st[1].wMonth--; 369 ok(SendMessageA(hwnd, MCM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st), 370 "Failed to set both min and max limits\n"); 371 res = SendMessageA(hwnd, MCM_GETMONTHRANGE, GMR_VISIBLE, (LPARAM)st1); 372 ok(res == month_range, "Invalid month range (%d)\n", res); 373 ok(SendMessageA(hwnd, MCM_GETRANGE, 0, (LPARAM)st1) == (GDTR_MIN|GDTR_MAX), 374 "Limits should be set\n"); 375 376 st[1].wMonth += 2; 377 ok(SendMessageA(hwnd, MCM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st), 378 "Failed to set both min and max limits\n"); 379 res = SendMessageA(hwnd, MCM_GETMONTHRANGE, GMR_VISIBLE, (LPARAM)st1); 380 ok(res == month_range, "Invalid month range (%d)\n", res); 381 382 st[1].wYear --; 383 ok(SendMessageA(hwnd, MCM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st), 384 "Failed to set both min and max limits\n"); 385 st[1].wYear += 1; 386 ok(SendMessageA(hwnd, MCM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st), 387 "Failed to set both min and max limits\n"); 388 389 st[1].wMonth -= 3; 390 ok(SendMessageA(hwnd, MCM_SETRANGE, GDTR_MAX, (LPARAM)st), "Failed to set max limit\n"); 391 ok(SendMessageA(hwnd, MCM_GETRANGE, 0, (LPARAM)st1) == GDTR_MAX, 392 "Only MAX limit should be set\n"); 393 st[1].wMonth += 4; 394 ok(SendMessageA(hwnd, MCM_SETRANGE, GDTR_MAX, (LPARAM)st), "Failed to set max limit\n"); 395 st[1].wYear -= 3; 396 ok(SendMessageA(hwnd, MCM_SETRANGE, GDTR_MAX, (LPARAM)st), "Failed to set max limit\n"); 397 st[1].wYear += 4; 398 ok(SendMessageA(hwnd, MCM_SETRANGE, GDTR_MAX, (LPARAM)st), "Failed to set max limit\n"); 399 ok(SendMessageA(hwnd, MCM_GETRANGE, 0, (LPARAM)st1) == GDTR_MAX, 400 "Only MAX limit should be set\n"); 401 402 /* set both limits, then set max < min */ 403 GetSystemTime(&st[0]); 404 st[0].wDay = 25; 405 st[1] = st[0]; 406 st[1].wYear++; 407 ok(SendMessageA(hwnd, MCM_SETRANGE, GDTR_MIN|GDTR_MAX, (LPARAM)st), "Failed to set limits\n"); 408 ok(SendMessageA(hwnd, MCM_GETRANGE, 0, (LPARAM)st1) == (GDTR_MIN|GDTR_MAX), 409 "Min limit expected\n"); 410 st[1].wYear -= 2; 411 ok(SendMessageA(hwnd, MCM_SETRANGE, GDTR_MAX, (LPARAM)st), "Failed to set limits\n"); 412 ok(SendMessageA(hwnd, MCM_GETRANGE, 0, (LPARAM)st1) == GDTR_MAX, "Max limit expected\n"); 413 414 expect(0, st1[0].wYear); 415 expect(0, st1[0].wMonth); 416 expect(0, st1[0].wDay); 417 expect(0, st1[0].wDayOfWeek); 418 expect(0, st1[0].wHour); 419 expect(0, st1[0].wMinute); 420 expect(0, st1[0].wSecond); 421 expect(0, st1[0].wMilliseconds); 422 423 expect(st[1].wYear, st1[1].wYear); 424 expect(st[1].wMonth, st1[1].wMonth); 425 expect(st[1].wDay, st1[1].wDay); 426 expect(st[1].wDayOfWeek, st1[1].wDayOfWeek); 427 expect(st[1].wHour, st1[1].wHour); 428 expect(st[1].wMinute, st1[1].wMinute); 429 expect(st[1].wSecond, st1[1].wSecond); 430 expect(st[1].wMilliseconds, st1[1].wMilliseconds); 431 432 st[1] = st[0]; 433 st[1].wYear++; 434 ok(SendMessageA(hwnd, MCM_SETRANGE, GDTR_MIN|GDTR_MAX, (LPARAM)st), "Failed to set limits\n"); 435 ok(SendMessageA(hwnd, MCM_GETRANGE, 0, (LPARAM)st1) == (GDTR_MIN|GDTR_MAX), 436 "Min limit expected\n"); 437 st[0].wYear++; /* start == end now */ 438 ok(SendMessageA(hwnd, MCM_SETRANGE, GDTR_MIN, (LPARAM)st), "Failed to set limits\n"); 439 ok(SendMessageA(hwnd, MCM_GETRANGE, 0, (LPARAM)st1) == GDTR_MIN, "Min limit expected\n"); 440 441 expect(st[0].wYear, st1[0].wYear); 442 expect(st[0].wMonth, st1[0].wMonth); 443 expect(st[0].wDay, st1[0].wDay); 444 expect(st[0].wDayOfWeek, st1[0].wDayOfWeek); 445 expect(st[0].wHour, st1[0].wHour); 446 expect(st[0].wMinute, st1[0].wMinute); 447 expect(st[0].wSecond, st1[0].wSecond); 448 expect(st[0].wMilliseconds, st1[0].wMilliseconds); 449 450 expect(0, st1[1].wYear); 451 expect(0, st1[1].wMonth); 452 expect(0, st1[1].wDay); 453 expect(0, st1[1].wDayOfWeek); 454 expect(0, st1[1].wHour); 455 expect(0, st1[1].wMinute); 456 expect(0, st1[1].wSecond); 457 expect(0, st1[1].wMilliseconds); 458 459 /* 0 limit flags */ 460 limits = SendMessageA(hwnd, MCM_GETRANGE, 0, (LPARAM)st1); 461 ok(limits == GDTR_MIN, "got 0x%08x\n", limits); 462 463 GetSystemTime(st); 464 st[1] = st[0]; 465 st[1].wYear++; 466 r = SendMessageA(hwnd, MCM_SETRANGE, 0, (LPARAM)st); 467 ok(r, "got %d\n", r); 468 469 limits = SendMessageA(hwnd, MCM_GETRANGE, 0, (LPARAM)st); 470 ok(limits == 0, "got 0x%08x\n", limits); 471 ok(st[0].wYear == 0 && st[1].wYear == 0, "got %u, %u\n", st[0].wYear, st[1].wYear); 472 473 /* flags are 0, set min limit */ 474 GetSystemTime(st); 475 st[1] = st[0]; 476 st[1].wYear++; 477 478 r = SendMessageA(hwnd, MCM_SETRANGE, GDTR_MIN, (LPARAM)st); 479 ok(r, "got %d\n", r); 480 481 limits = SendMessageA(hwnd, MCM_GETRANGE, 0, (LPARAM)st1); 482 ok(limits == GDTR_MIN, "got 0x%08x\n", limits); 483 ok(st1[1].wYear == 0, "got %u\n", st1[1].wYear); 484 485 /* now set max limit, check flags */ 486 r = SendMessageA(hwnd, MCM_SETRANGE, GDTR_MAX, (LPARAM)st); 487 ok(r, "got %d\n", r); 488 489 limits = SendMessageA(hwnd, MCM_GETRANGE, 0, (LPARAM)st1); 490 ok(limits == GDTR_MAX, "got 0x%08x\n", limits); 491 ok(st1[0].wYear == 0, "got %u\n", st1[0].wYear); 492 493 DestroyWindow(hwnd); 494 } 495 496 static LRESULT WINAPI parent_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 497 { 498 static LONG defwndproc_counter = 0; 499 LRESULT ret; 500 struct message msg; 501 502 /* log system messages, except for painting */ 503 if (message < WM_USER && 504 message != WM_PAINT && 505 message != WM_ERASEBKGND && 506 message != WM_NCPAINT && 507 message != WM_NCHITTEST && 508 message != WM_GETTEXT && 509 message != WM_GETICON && 510 message != WM_DEVICECHANGE) 511 { 512 msg.message = message; 513 msg.flags = sent|wparam|lparam; 514 if (defwndproc_counter) msg.flags |= defwinproc; 515 msg.wParam = wParam; 516 msg.lParam = lParam; 517 add_message(sequences, PARENT_SEQ_INDEX, &msg); 518 } 519 520 if (message == WM_NOTIFY) 521 { 522 NMHDR *hdr = (NMHDR*)lParam; 523 switch (hdr->code) 524 { 525 case MCN_GETDAYSTATE: 526 { 527 NMDAYSTATE *nmstate = (NMDAYSTATE*)lParam; 528 static MONTHDAYSTATE months[14] = { 0 }; 529 530 ok(nmstate->cDayState > 0, "got %d\n", nmstate->cDayState); 531 ok(nmstate->cDayState <= 14, "got %d\n", nmstate->cDayState); 532 ok(nmstate->prgDayState != NULL, "got %p\n", nmstate->prgDayState); 533 534 nmstate->prgDayState = months; 535 536 return TRUE; 537 } 538 case MCN_SELECT: 539 case MCN_SELCHANGE: 540 { 541 NMSELCHANGE *nmchg = (NMSELCHANGE*)lParam; 542 SYSTEMTIME st[2]; 543 BOOL is_multisel = GetWindowLongPtrA(nmchg->nmhdr.hwndFrom, GWL_STYLE) & MCS_MULTISELECT; 544 545 if(GetWindowLongPtrA(nmchg->nmhdr.hwndFrom, GWLP_ID) != SEL_NOTIFY_TEST_ID) 546 break; 547 SendMessageA(nmchg->nmhdr.hwndFrom, is_multisel ? MCM_GETSELRANGE : MCM_GETCURSEL, 548 0, (LPARAM)st); 549 550 expect(st[0].wYear, nmchg->stSelStart.wYear); 551 expect(st[0].wMonth, nmchg->stSelStart.wMonth); 552 expect(0, nmchg->stSelStart.wDayOfWeek); 553 expect(st[0].wDay, nmchg->stSelStart.wDay); 554 555 if(is_multisel) 556 { 557 expect(st[1].wYear, nmchg->stSelEnd.wYear); 558 expect(st[1].wMonth, nmchg->stSelEnd.wMonth); 559 expect(0, nmchg->stSelEnd.wDayOfWeek); 560 expect(st[1].wDay, nmchg->stSelEnd.wDay); 561 } 562 else 563 ok(!(nmchg->stSelEnd.wYear | nmchg->stSelEnd.wMonth | 564 nmchg->stSelEnd.wDayOfWeek | nmchg->stSelEnd.wDay | 565 nmchg->stSelEnd.wHour | nmchg->stSelEnd.wMinute | 566 nmchg->stSelEnd.wSecond | nmchg->stSelEnd.wMilliseconds), 567 "Non-zero member in stSelEnd\n"); 568 return TRUE; 569 } 570 default: 571 break; 572 } 573 } 574 575 defwndproc_counter++; 576 ret = DefWindowProcA(hwnd, message, wParam, lParam); 577 defwndproc_counter--; 578 579 return ret; 580 } 581 582 static BOOL register_parent_wnd_class(void) 583 { 584 WNDCLASSA cls; 585 586 cls.style = 0; 587 cls.lpfnWndProc = parent_wnd_proc; 588 cls.cbClsExtra = 0; 589 cls.cbWndExtra = 0; 590 cls.hInstance = GetModuleHandleA(NULL); 591 cls.hIcon = 0; 592 cls.hCursor = LoadCursorA(0, (LPCSTR)IDC_ARROW); 593 cls.hbrBackground = GetStockObject(WHITE_BRUSH); 594 cls.lpszMenuName = NULL; 595 cls.lpszClassName = "Month-Cal test parent class"; 596 return RegisterClassA(&cls); 597 } 598 599 static HWND create_parent_window(void) 600 { 601 HWND hwnd; 602 603 /* flush message sequences, so we can check the new sequence by the end of function */ 604 flush_sequences(sequences, NUM_MSG_SEQUENCES); 605 606 if (!register_parent_wnd_class()) 607 return NULL; 608 609 hwnd = CreateWindowExA(0, "Month-Cal test parent class", "Month-Cal test parent window", 610 WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_VISIBLE, 611 0, 0, 500, 500, GetDesktopWindow(), NULL, GetModuleHandleA(NULL), NULL); 612 ok(hwnd != NULL, "failed to create parent wnd\n"); 613 614 /* check for message sequences */ 615 ok_sequence(sequences, PARENT_SEQ_INDEX, create_parent_window_seq, "create parent window", FALSE); 616 617 return hwnd; 618 } 619 620 static LRESULT WINAPI monthcal_subclass_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 621 { 622 WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA); 623 static LONG defwndproc_counter = 0; 624 struct message msg = { 0 }; 625 LRESULT ret; 626 627 msg.message = message; 628 msg.flags = sent|wparam|lparam; 629 if (defwndproc_counter) msg.flags |= defwinproc; 630 msg.wParam = wParam; 631 msg.lParam = lParam; 632 add_message(sequences, MONTHCAL_SEQ_INDEX, &msg); 633 634 /* some debug output for style changing */ 635 if ((message == WM_STYLECHANGING || 636 message == WM_STYLECHANGED) && lParam) 637 { 638 STYLESTRUCT *style = (STYLESTRUCT*)lParam; 639 trace("\told style: 0x%08x, new style: 0x%08x\n", style->styleOld, style->styleNew); 640 } 641 642 defwndproc_counter++; 643 ret = CallWindowProcA(oldproc, hwnd, message, wParam, lParam); 644 defwndproc_counter--; 645 646 return ret; 647 } 648 649 static HWND create_monthcal_control(DWORD style) 650 { 651 WNDPROC oldproc; 652 RECT rect; 653 HWND hwnd; 654 BOOL ret; 655 656 hwnd = CreateWindowExA(0, MONTHCAL_CLASSA, "", WS_CHILD | WS_BORDER | WS_VISIBLE | style, 657 0, 0, 300, 400, parent_wnd, NULL, GetModuleHandleA(NULL), NULL); 658 ok(hwnd != NULL, "failed to create monthcal wnd\n"); 659 if (!hwnd) return NULL; 660 661 oldproc = (WNDPROC)SetWindowLongPtrA(hwnd, GWLP_WNDPROC, 662 (LONG_PTR)monthcal_subclass_proc); 663 SetWindowLongPtrA(hwnd, GWLP_USERDATA, (LONG_PTR)oldproc); 664 665 SendMessageA(hwnd, WM_SETFONT, (WPARAM)GetStockObject(SYSTEM_FONT), 0); 666 667 /* make sure calendar grid is 2x1 */ 668 ret = SendMessageA(hwnd, MCM_GETMINREQRECT, 0, (LPARAM)&rect); 669 ok(ret, "got %d\n", ret); 670 671 ret = SetWindowPos(hwnd, NULL, 0, 0, rect.right * 5 / 2, rect.bottom * 3 / 2, SWP_NOMOVE); 672 ok(ret, "got %d\n", ret); 673 674 return hwnd; 675 } 676 677 678 /* Setter and Getters Tests */ 679 680 static void test_color(void) 681 { 682 COLORREF color, prev; 683 HWND hwnd; 684 685 hwnd = create_monthcal_control(0); 686 687 /* invalid color index */ 688 color = SendMessageA(hwnd, MCM_GETCOLOR, MCSC_TRAILINGTEXT + 1, 0); 689 expect(~0u, color); 690 prev = SendMessageA(hwnd, MCM_SETCOLOR, MCSC_TRAILINGTEXT + 1, RGB(255,255,255)); 691 expect(~0u, prev); 692 693 color = SendMessageA(hwnd, MCM_GETCOLOR, MCSC_BACKGROUND, 0); 694 prev = SendMessageA(hwnd, MCM_SETCOLOR, MCSC_BACKGROUND, RGB(0,0,0)); 695 expect(color, prev); 696 color = SendMessageA(hwnd, MCM_GETCOLOR, MCSC_BACKGROUND, 0); 697 expect(RGB(0,0,0), color); 698 prev = SendMessageA(hwnd, MCM_SETCOLOR, MCSC_BACKGROUND, RGB(255,255,255)); 699 expect(color, prev); 700 color = SendMessageA(hwnd, MCM_GETCOLOR, MCSC_BACKGROUND, 0); 701 expect(RGB(255,255,255), color); 702 703 color = SendMessageA(hwnd, MCM_GETCOLOR, MCSC_MONTHBK, 0); 704 prev = SendMessageA(hwnd, MCM_SETCOLOR, MCSC_MONTHBK, RGB(0,0,0)); 705 expect(color, prev); 706 color = SendMessageA(hwnd, MCM_GETCOLOR, MCSC_MONTHBK, 0); 707 expect(RGB(0,0,0), color); 708 prev = SendMessageA(hwnd, MCM_SETCOLOR, MCSC_MONTHBK, RGB(255,255,255)); 709 expect(color, prev); 710 color = SendMessageA(hwnd, MCM_GETCOLOR, MCSC_MONTHBK, 0); 711 expect(RGB(255,255,255), color); 712 713 color = SendMessageA(hwnd, MCM_GETCOLOR, MCSC_TEXT, 0); 714 prev = SendMessageA(hwnd, MCM_SETCOLOR, MCSC_TEXT, RGB(0,0,0)); 715 expect(color, prev); 716 color = SendMessageA(hwnd, MCM_GETCOLOR, MCSC_TEXT, 0); 717 expect(RGB(0,0,0), color); 718 prev = SendMessageA(hwnd, MCM_SETCOLOR, MCSC_TEXT, RGB(255,255,255)); 719 expect(color, prev); 720 color = SendMessageA(hwnd, MCM_GETCOLOR, MCSC_TEXT, 0); 721 expect(RGB(255,255,255), color); 722 723 color = SendMessageA(hwnd, MCM_GETCOLOR, MCSC_TITLEBK, 0); 724 prev = SendMessageA(hwnd, MCM_SETCOLOR, MCSC_TITLEBK, RGB(0,0,0)); 725 expect(color, prev); 726 color = SendMessageA(hwnd, MCM_GETCOLOR, MCSC_TITLEBK, 0); 727 expect(RGB(0,0,0), color); 728 prev = SendMessageA(hwnd, MCM_SETCOLOR, MCSC_TITLEBK, RGB(255,255,255)); 729 expect(color, prev); 730 color = SendMessageA(hwnd, MCM_GETCOLOR, MCSC_TITLEBK, 0); 731 expect(RGB(255,255,255), color); 732 733 color = SendMessageA(hwnd, MCM_GETCOLOR, MCSC_TITLETEXT, 0); 734 prev = SendMessageA(hwnd, MCM_SETCOLOR, MCSC_TITLETEXT, RGB(0,0,0)); 735 expect(color, prev); 736 color = SendMessageA(hwnd, MCM_GETCOLOR, MCSC_TITLETEXT, 0); 737 expect(RGB(0,0,0), color); 738 prev = SendMessageA(hwnd, MCM_SETCOLOR, MCSC_TITLETEXT, RGB(255,255,255)); 739 expect(color, prev); 740 color = SendMessageA(hwnd, MCM_GETCOLOR, MCSC_TITLETEXT, 0); 741 expect(RGB(255,255,255), color); 742 743 color = SendMessageA(hwnd, MCM_GETCOLOR, MCSC_TRAILINGTEXT, 0); 744 prev = SendMessageA(hwnd, MCM_SETCOLOR, MCSC_TRAILINGTEXT, RGB(0,0,0)); 745 expect(color, prev); 746 color = SendMessageA(hwnd, MCM_GETCOLOR, MCSC_TRAILINGTEXT, 0); 747 expect(RGB(0,0,0), color); 748 prev = SendMessageA(hwnd, MCM_SETCOLOR, MCSC_TRAILINGTEXT, RGB(255,255,255)); 749 expect(color, prev); 750 color = SendMessageA(hwnd, MCM_GETCOLOR, MCSC_TRAILINGTEXT, 0); 751 expect(RGB(255,255,255), color); 752 753 DestroyWindow(hwnd); 754 } 755 756 static void test_currdate(void) 757 { 758 SYSTEMTIME st_original, st_new, st_test; 759 int res; 760 HWND hwnd; 761 762 hwnd = create_monthcal_control(0); 763 764 flush_sequences(sequences, NUM_MSG_SEQUENCES); 765 766 /* Setter and Getters for current date selected */ 767 st_original.wYear = 2000; 768 st_original.wMonth = 11; 769 st_original.wDay = 28; 770 st_original.wHour = 11; 771 st_original.wMinute = 59; 772 st_original.wSecond = 30; 773 st_original.wMilliseconds = 0; 774 st_original.wDayOfWeek = 0; 775 776 st_new = st_test = st_original; 777 778 /* Should not validate the time */ 779 res = SendMessageA(hwnd, MCM_SETCURSEL, 0, (LPARAM)&st_test); 780 expect(1,res); 781 782 /* Overflow matters, check for wDay */ 783 st_test.wDay += 4; 784 res = SendMessageA(hwnd, MCM_SETCURSEL, 0, (LPARAM)&st_test); 785 expect(0,res); 786 787 /* correct wDay before checking for wMonth */ 788 st_test.wDay -= 4; 789 expect(st_original.wDay, st_test.wDay); 790 791 /* Overflow matters, check for wMonth */ 792 st_test.wMonth += 4; 793 res = SendMessageA(hwnd, MCM_SETCURSEL, 0, (LPARAM)&st_test); 794 expect(0,res); 795 796 /* checking if gets the information right, modify st_new */ 797 st_new.wYear += 4; 798 st_new.wMonth += 4; 799 st_new.wDay += 4; 800 st_new.wHour += 4; 801 st_new.wMinute += 4; 802 st_new.wSecond += 4; 803 804 res = SendMessageA(hwnd, MCM_GETCURSEL, 0, (LPARAM)&st_new); 805 expect(1, res); 806 807 /* st_new change to st_origin, above settings with overflow */ 808 /* should not change the current settings */ 809 expect(st_original.wYear, st_new.wYear); 810 expect(st_original.wMonth, st_new.wMonth); 811 expect(st_original.wDay, st_new.wDay); 812 ok(st_original.wHour == st_new.wHour || 813 broken(0 == st_new.wHour), /* comctl32 <= 4.70 */ 814 "Expected %d, got %d\n", st_original.wHour, st_new.wHour); 815 ok(st_original.wMinute == st_new.wMinute || 816 broken(0 == st_new.wMinute), /* comctl32 <= 4.70 */ 817 "Expected %d, got %d\n", st_original.wMinute, st_new.wMinute); 818 ok(st_original.wSecond == st_new.wSecond || 819 broken(0 == st_new.wSecond), /* comctl32 <= 4.70 */ 820 "Expected %d, got %d\n", st_original.wSecond, st_new.wSecond); 821 822 /* lparam cannot be NULL */ 823 res = SendMessageA(hwnd, MCM_GETCURSEL, 0, 0); 824 expect(0, res); 825 826 ok_sequence(sequences, MONTHCAL_SEQ_INDEX, monthcal_curr_date_seq, "monthcal currDate", TRUE); 827 828 /* December, 31, 9999 is the maximum allowed date */ 829 memset(&st_new, 0, sizeof(st_new)); 830 st_new.wYear = 9999; 831 st_new.wMonth = 12; 832 st_new.wDay = 31; 833 res = SendMessageA(hwnd, MCM_SETCURSEL, 0, (LPARAM)&st_new); 834 expect(1, res); 835 memset(&st_test, 0, sizeof(st_test)); 836 res = SendMessageA(hwnd, MCM_GETCURSEL, 0, (LPARAM)&st_test); 837 expect(1, res); 838 expect(st_new.wYear, st_test.wYear); 839 expect(st_new.wMonth, st_test.wMonth); 840 expect(st_new.wDay, st_test.wDay); 841 expect(st_new.wHour, st_test.wHour); 842 expect(st_new.wMinute, st_test.wMinute); 843 expect(st_new.wSecond, st_test.wSecond); 844 /* try one day later */ 845 st_original = st_new; 846 st_new.wYear = 10000; 847 st_new.wMonth = 1; 848 st_new.wDay = 1; 849 res = SendMessageA(hwnd, MCM_SETCURSEL, 0, (LPARAM)&st_new); 850 ok(0 == res || 851 broken(1 == res), /* comctl32 <= 4.72 */ 852 "Expected 0, got %d\n", res); 853 if (0 == res) 854 { 855 memset(&st_test, 0, sizeof(st_test)); 856 res = SendMessageA(hwnd, MCM_GETCURSEL, 0, (LPARAM)&st_test); 857 expect(1, res); 858 expect(st_original.wYear, st_test.wYear); 859 expect(st_original.wMonth, st_test.wMonth); 860 expect(st_original.wDay, st_test.wDay); 861 expect(st_original.wHour, st_test.wHour); 862 expect(st_original.wMinute, st_test.wMinute); 863 expect(st_original.wSecond, st_test.wSecond); 864 } 865 866 /* setting selection equal to current reports success even if out range */ 867 memset(&st_new, 0, sizeof(st_new)); 868 st_new.wYear = 2009; 869 st_new.wDay = 5; 870 st_new.wMonth = 10; 871 res = SendMessageA(hwnd, MCM_SETCURSEL, 0, (LPARAM)&st_new); 872 expect(1, res); 873 memset(&st_test, 0, sizeof(st_test)); 874 st_test.wYear = 2009; 875 st_test.wDay = 6; 876 st_test.wMonth = 10; 877 res = SendMessageA(hwnd, MCM_SETRANGE, GDTR_MIN, (LPARAM)&st_test); 878 expect(1, res); 879 /* set to current again */ 880 res = SendMessageA(hwnd, MCM_SETCURSEL, 0, (LPARAM)&st_new); 881 expect(1, res); 882 883 /* set with invalid day of week */ 884 memset(&st_test, 0, sizeof(st_test)); 885 st_test.wYear = 2009; 886 st_test.wDay = 7; 887 st_test.wMonth = 10; 888 st_test.wDayOfWeek = 100; 889 res = SendMessageA(hwnd, MCM_SETCURSEL, 0, (LPARAM)&st_test); 890 expect(1, res); 891 892 memset(&st_test, 0, sizeof(st_test)); 893 res = SendMessageA(hwnd, MCM_GETCURSEL, 0, (LPARAM)&st_test); 894 expect(1, res); 895 expect(2009, st_test.wYear); 896 expect(7, st_test.wDay); 897 expect(10, st_test.wMonth); 898 expect(3, st_test.wDayOfWeek); 899 900 DestroyWindow(hwnd); 901 } 902 903 static void test_firstDay(void) 904 { 905 int res, fday, i, prev; 906 CHAR b[128], caltype[3]; 907 LCID lcid = LOCALE_USER_DEFAULT; 908 HWND hwnd; 909 LRESULT ret; 910 911 SetLastError(0xdeadbeef); 912 ret = GetLocaleInfoA(lcid, LOCALE_ICALENDARTYPE, caltype, 3); 913 if (ret == 0) { 914 skip("Must know local calendar type (%x)\n", GetLastError()); 915 return; 916 } else if (atoi(caltype) != CAL_GREGORIAN) { 917 skip("MonthCalendar Control only supports Gregorian calendar (type: %s)\n", caltype); 918 return; 919 } 920 921 hwnd = create_monthcal_control(0); 922 923 flush_sequences(sequences, NUM_MSG_SEQUENCES); 924 925 /* Setter and Getters for first day of week */ 926 /* check for locale first day */ 927 if(GetLocaleInfoA(lcid, LOCALE_IFIRSTDAYOFWEEK, b, 128)){ 928 fday = atoi(b); 929 res = SendMessageA(hwnd, MCM_GETFIRSTDAYOFWEEK, 0, 0); 930 expect(fday, res); 931 prev = fday; 932 933 /* checking for the values that actually will be stored as */ 934 /* current first day when we set a new value */ 935 for (i = -5; i < 12; i++){ 936 res = SendMessageA(hwnd, MCM_SETFIRSTDAYOFWEEK, 0, i); 937 expect(prev, res); 938 res = SendMessageA(hwnd, MCM_GETFIRSTDAYOFWEEK, 0, 0); 939 prev = res; 940 941 if (i == -1){ 942 expect(MAKELONG(fday, FALSE), res); 943 }else if (i >= 7){ 944 /* out of range sets max first day of week, locale is ignored */ 945 expect(MAKELONG(6, TRUE), res); 946 }else{ 947 expect(MAKELONG(i, TRUE), res); 948 } 949 } 950 951 ok_sequence(sequences, MONTHCAL_SEQ_INDEX, monthcal_first_day_seq, "monthcal firstDay", FALSE); 952 953 }else{ 954 skip("Cannot retrieve first day of the week\n"); 955 } 956 957 DestroyWindow(hwnd); 958 } 959 960 static void test_unicode(void) 961 { 962 int res, temp; 963 HWND hwnd; 964 965 hwnd = create_monthcal_control(0); 966 967 flush_sequences(sequences, NUM_MSG_SEQUENCES); 968 969 /* Setter and Getters for Unicode format */ 970 971 /* getting the current settings */ 972 temp = SendMessageA(hwnd, MCM_GETUNICODEFORMAT, 0, 0); 973 974 /* setting to 1, should return previous settings */ 975 res = SendMessageA(hwnd, MCM_SETUNICODEFORMAT, 1, 0); 976 expect(temp, res); 977 978 /* current setting is 1, so, should return 1 */ 979 res = SendMessageA(hwnd, MCM_GETUNICODEFORMAT, 0, 0); 980 ok(1 == res || 981 broken(0 == res), /* comctl32 <= 4.70 */ 982 "Expected 1, got %d\n", res); 983 984 /* setting to 0, should return previous settings */ 985 res = SendMessageA(hwnd, MCM_SETUNICODEFORMAT, 0, 0); 986 ok(1 == res || 987 broken(0 == res), /* comctl32 <= 4.70 */ 988 "Expected 1, got %d\n", res); 989 990 /* current setting is 0, so, it should return 0 */ 991 res = SendMessageA(hwnd, MCM_GETUNICODEFORMAT, 0, 0); 992 expect(0, res); 993 994 /* should return previous settings */ 995 res = SendMessageA(hwnd, MCM_SETUNICODEFORMAT, 1, 0); 996 expect(0, res); 997 998 ok_sequence(sequences, MONTHCAL_SEQ_INDEX, monthcal_unicode_seq, "monthcal unicode", FALSE); 999 1000 DestroyWindow(hwnd); 1001 } 1002 1003 static void test_hittest(void) 1004 { 1005 typedef struct hittest_test 1006 { 1007 UINT ht; 1008 BOOL todo; 1009 } hittest_test_t; 1010 1011 static const hittest_test_t title_hits[] = { 1012 /* Start is the same everywhere */ 1013 { MCHT_TITLE, FALSE }, 1014 { MCHT_TITLEBTNPREV, FALSE }, 1015 /* The middle piece is only tested for presence of items */ 1016 /* End is the same everywhere */ 1017 { MCHT_TITLEBTNNEXT, FALSE }, 1018 { MCHT_TITLE, FALSE }, 1019 { MCHT_NOWHERE, TRUE } 1020 }; 1021 1022 MCHITTESTINFO mchit; 1023 UINT res, old_res; 1024 SYSTEMTIME st; 1025 LONG x; 1026 UINT title_index; 1027 HWND hwnd; 1028 RECT r; 1029 char yearmonth[80], *locale_month, *locale_year; 1030 int month_count, year_count; 1031 BOOL in_the_middle; 1032 1033 memset(&mchit, 0, sizeof(MCHITTESTINFO)); 1034 1035 hwnd = create_monthcal_control(0); 1036 1037 /* test with invalid structure size */ 1038 mchit.cbSize = MCHITTESTINFO_V1_SIZE - 1; 1039 mchit.pt.x = 0; 1040 mchit.pt.y = 0; 1041 res = SendMessageA(hwnd, MCM_HITTEST, 0, (LPARAM)&mchit); 1042 expect(0, mchit.pt.x); 1043 expect(0, mchit.pt.y); 1044 expect(~0u, res); 1045 expect(0, mchit.uHit); 1046 /* test with invalid pointer */ 1047 res = SendMessageA(hwnd, MCM_HITTEST, 0, 0); 1048 expect(~0u, res); 1049 1050 /* resize control to display single Calendar */ 1051 res = SendMessageA(hwnd, MCM_GETMINREQRECT, 0, (LPARAM)&r); 1052 if (res == 0) 1053 { 1054 win_skip("Message MCM_GETMINREQRECT unsupported. Skipping.\n"); 1055 DestroyWindow(hwnd); 1056 return; 1057 } 1058 MoveWindow(hwnd, 0, 0, r.right, r.bottom, FALSE); 1059 1060 flush_sequences(sequences, NUM_MSG_SEQUENCES); 1061 1062 st.wYear = 2007; 1063 st.wMonth = 4; 1064 st.wDay = 11; 1065 st.wHour = 1; 1066 st.wMinute = 0; 1067 st.wSecond = 0; 1068 st.wMilliseconds = 0; 1069 st.wDayOfWeek = 0; 1070 1071 res = SendMessageA(hwnd, MCM_SETCURSEL, 0, (LPARAM)&st); 1072 expect(1,res); 1073 1074 /* (0, 0) is the top left of the control - title */ 1075 mchit.cbSize = MCHITTESTINFO_V1_SIZE; 1076 mchit.pt.x = 0; 1077 mchit.pt.y = 0; 1078 res = SendMessageA(hwnd, MCM_HITTEST, 0, (LPARAM)&mchit); 1079 expect(0, mchit.pt.x); 1080 expect(0, mchit.pt.y); 1081 expect(mchit.uHit, res); 1082 expect_hex(MCHT_TITLE, res); 1083 1084 /* bottom right of the control and should not be active */ 1085 mchit.pt.x = r.right; 1086 mchit.pt.y = r.bottom; 1087 res = SendMessageA(hwnd, MCM_HITTEST, 0, (LPARAM)&mchit); 1088 expect(r.right, mchit.pt.x); 1089 expect(r.bottom, mchit.pt.y); 1090 expect(mchit.uHit, res); 1091 todo_wine expect_hex(MCHT_NOWHERE, res); 1092 1093 /* completely out of the control, should not be active */ 1094 mchit.pt.x = 2 * r.right; 1095 mchit.pt.y = 2 * r.bottom; 1096 res = SendMessageA(hwnd, MCM_HITTEST, 0, (LPARAM)&mchit); 1097 expect(2 * r.right, mchit.pt.x); 1098 expect(2 * r.bottom, mchit.pt.y); 1099 expect(mchit.uHit, res); 1100 todo_wine expect_hex(MCHT_NOWHERE, res); 1101 1102 /* in active area - day of the week */ 1103 mchit.pt.x = r.right / 2; 1104 mchit.pt.y = r.bottom / 2; 1105 res = SendMessageA(hwnd, MCM_HITTEST, 0, (LPARAM)&mchit); 1106 expect(r.right / 2, mchit.pt.x); 1107 expect(r.bottom / 2, mchit.pt.y); 1108 expect(mchit.uHit, res); 1109 expect_hex(MCHT_CALENDARDATE, res); 1110 1111 /* in active area - day of the week #2 */ 1112 mchit.pt.x = r.right / 14; /* half of first day rect */ 1113 mchit.pt.y = r.bottom / 2; 1114 res = SendMessageA(hwnd, MCM_HITTEST, 0, (LPARAM)&mchit); 1115 expect(r.right / 14, mchit.pt.x); 1116 expect(r.bottom / 2, mchit.pt.y); 1117 expect(mchit.uHit, res); 1118 expect_hex(MCHT_CALENDARDATE, res); 1119 1120 /* in active area - date from prev month */ 1121 mchit.pt.x = r.right / 14; /* half of first day rect */ 1122 mchit.pt.y = 6 * r.bottom / 19; 1123 res = SendMessageA(hwnd, MCM_HITTEST, 0, (LPARAM)&mchit); 1124 expect(r.right / 14, mchit.pt.x); 1125 expect(6 * r.bottom / 19, mchit.pt.y); 1126 expect(mchit.uHit, res); 1127 expect_hex(MCHT_CALENDARDATEPREV, res); 1128 1129 if (0) 1130 { 1131 /* (125, 115) is in active area - date from this month */ 1132 mchit.pt.x = 125; 1133 mchit.pt.y = 115; 1134 res = SendMessageA(hwnd, MCM_HITTEST, 0, (LPARAM)&mchit); 1135 expect(125, mchit.pt.x); 1136 expect(115, mchit.pt.y); 1137 expect(mchit.uHit, res); 1138 expect(MCHT_CALENDARDATE, res); 1139 } 1140 1141 /* in active area - date from next month */ 1142 mchit.pt.x = 11 * r.right / 14; 1143 mchit.pt.y = 16 * r.bottom / 19; 1144 res = SendMessageA(hwnd, MCM_HITTEST, 0, (LPARAM)&mchit); 1145 expect(11 * r.right / 14, mchit.pt.x); 1146 expect(16 * r.bottom / 19, mchit.pt.y); 1147 expect(mchit.uHit, res); 1148 expect_hex(MCHT_CALENDARDATENEXT, res); 1149 1150 /* in active area - today link */ 1151 mchit.pt.x = r.right / 14; 1152 mchit.pt.y = 18 * r.bottom / 19; 1153 res = SendMessageA(hwnd, MCM_HITTEST, 0, (LPARAM)&mchit); 1154 expect(r.right / 14, mchit.pt.x); 1155 expect(18 * r.bottom / 19, mchit.pt.y); 1156 expect(mchit.uHit, res); 1157 expect_hex(MCHT_TODAYLINK, res); 1158 1159 /* in active area - today link */ 1160 mchit.pt.x = r.right / 2; 1161 mchit.pt.y = 18 * r.bottom / 19; 1162 res = SendMessageA(hwnd, MCM_HITTEST, 0, (LPARAM)&mchit); 1163 expect(r.right / 2, mchit.pt.x); 1164 expect(18 * r.bottom / 19, mchit.pt.y); 1165 expect(mchit.uHit, res); 1166 expect_hex(MCHT_TODAYLINK, res); 1167 1168 /* in active area - today link */ 1169 mchit.pt.x = r.right / 10; 1170 mchit.pt.y = 18 * r.bottom / 19; 1171 res = SendMessageA(hwnd, MCM_HITTEST, 0, (LPARAM)&mchit); 1172 expect(r.right / 10, mchit.pt.x); 1173 expect(18 * r.bottom / 19, mchit.pt.y); 1174 expect(mchit.uHit, res); 1175 expect_hex(MCHT_TODAYLINK, res); 1176 1177 ok_sequence(sequences, MONTHCAL_SEQ_INDEX, monthcal_hit_test_seq, "monthcal hit test", TRUE); 1178 1179 /* The horizontal position of title bar elements depends on locale (y pos 1180 is constant), so we sample across a horizontal line and make sure we 1181 find all elements. */ 1182 1183 /* Get the format of the title */ 1184 GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SYEARMONTH, yearmonth, 80); 1185 /* Find out if we have a month and/or year */ 1186 locale_year = strstr(yearmonth, "y"); 1187 locale_month = strstr(yearmonth, "M"); 1188 1189 mchit.pt.x = 0; 1190 mchit.pt.y = (5/2) * r.bottom / 19; 1191 title_index = 0; 1192 old_res = SendMessageA(hwnd, MCM_HITTEST, 0, (LPARAM)&mchit); 1193 expect_hex(title_hits[title_index].ht, old_res); 1194 1195 in_the_middle = FALSE; 1196 month_count = year_count = 0; 1197 for (x = 0; x < r.right; x++){ 1198 mchit.pt.x = x; 1199 res = SendMessageA(hwnd, MCM_HITTEST, 0, (LPARAM)&mchit); 1200 expect(x, mchit.pt.x); 1201 expect((5/2) * r.bottom / 19, mchit.pt.y); 1202 expect(mchit.uHit, res); 1203 if (res != old_res) { 1204 1205 if (old_res == MCHT_TITLEBTNPREV) 1206 in_the_middle = TRUE; 1207 1208 if (res == MCHT_TITLEBTNNEXT) 1209 in_the_middle = FALSE; 1210 1211 if (in_the_middle) { 1212 if (res == MCHT_TITLEMONTH) 1213 month_count++; 1214 else if (res == MCHT_TITLEYEAR) 1215 year_count++; 1216 } else { 1217 title_index++; 1218 1219 if (ARRAY_SIZE(title_hits) <= title_index) 1220 break; 1221 1222 todo_wine_if(title_hits[title_index].todo) 1223 ok(title_hits[title_index].ht == res, "Expected %x, got %x, pos %d\n", 1224 title_hits[title_index].ht, res, x); 1225 } 1226 old_res = res; 1227 } 1228 } 1229 1230 /* There are some limits, even if LOCALE_SYEARMONTH contains rubbish 1231 * or no month/year indicators at all */ 1232 if (locale_month) 1233 todo_wine ok(month_count == 1, "Expected 1 month item, got %d\n", month_count); 1234 else 1235 ok(month_count <= 1, "Too many month items: %d\n", month_count); 1236 1237 if (locale_year) 1238 todo_wine ok(year_count == 1, "Expected 1 year item, got %d\n", year_count); 1239 else 1240 ok(year_count <= 1, "Too many year items: %d\n", year_count); 1241 1242 todo_wine ok(month_count + year_count >= 1, "Not enough month and year items\n"); 1243 1244 ok(r.right <= x && title_index + 1 == ARRAY_SIZE(title_hits), "Wrong title layout\n"); 1245 1246 DestroyWindow(hwnd); 1247 } 1248 1249 static void test_todaylink(void) 1250 { 1251 MCHITTESTINFO mchit; 1252 SYSTEMTIME st_test, st_new; 1253 UINT res; 1254 HWND hwnd; 1255 RECT r; 1256 1257 memset(&mchit, 0, sizeof(MCHITTESTINFO)); 1258 1259 hwnd = create_monthcal_control(0); 1260 1261 res = SendMessageA(hwnd, MCM_GETMINREQRECT, 0, (LPARAM)&r); 1262 expect(1, res); 1263 MoveWindow(hwnd, 0, 0, r.right, r.bottom, FALSE); 1264 1265 flush_sequences(sequences, NUM_MSG_SEQUENCES); 1266 1267 /* hit active area - today link */ 1268 mchit.cbSize = MCHITTESTINFO_V1_SIZE; 1269 mchit.pt.x = r.right / 14; 1270 mchit.pt.y = 18 * r.bottom / 19; 1271 res = SendMessageA(hwnd, MCM_HITTEST, 0, (LPARAM)&mchit); 1272 expect(r.right / 14, mchit.pt.x); 1273 expect(18 * r.bottom / 19, mchit.pt.y); 1274 expect(mchit.uHit, res); 1275 expect(MCHT_TODAYLINK, res); 1276 1277 st_test.wDay = 1; 1278 st_test.wMonth = 1; 1279 st_test.wYear = 2005; 1280 1281 res = SendMessageA(hwnd, MCM_SETTODAY, 0, (LPARAM)&st_test); 1282 expect(0, res); 1283 1284 memset(&st_new, 0, sizeof(st_new)); 1285 res = SendMessageA(hwnd, MCM_GETTODAY, 0, (LPARAM)&st_new); 1286 expect(1, res); 1287 expect(1, st_new.wDay); 1288 expect(1, st_new.wMonth); 1289 expect(2005, st_new.wYear); 1290 1291 res = SendMessageA(hwnd, WM_LBUTTONDOWN, MK_LBUTTON, MAKELONG(mchit.pt.x, mchit.pt.y)); 1292 expect(0, res); 1293 1294 memset(&st_new, 0, sizeof(st_new)); 1295 res = SendMessageA(hwnd, MCM_GETCURSEL, 0, (LPARAM)&st_new); 1296 expect(1, res); 1297 expect(1, st_new.wDay); 1298 expect(1, st_new.wMonth); 1299 expect(2005, st_new.wYear); 1300 1301 ok_sequence(sequences, MONTHCAL_SEQ_INDEX, monthcal_todaylink_seq, "monthcal hit test", TRUE); 1302 1303 DestroyWindow(hwnd); 1304 } 1305 1306 static void test_today(void) 1307 { 1308 SYSTEMTIME st_test, st_new; 1309 int res; 1310 HWND hwnd; 1311 1312 hwnd = create_monthcal_control(0); 1313 1314 flush_sequences(sequences, NUM_MSG_SEQUENCES); 1315 1316 /* Setter and Getters for "today" information */ 1317 1318 /* check for overflow, should be ok */ 1319 memset(&st_test, 0, sizeof(st_test)); 1320 st_test.wDay = 38; 1321 st_test.wMonth = 38; 1322 1323 st_new.wDay = 27; 1324 st_new.wMonth = 27; 1325 1326 res = SendMessageA(hwnd, MCM_SETTODAY, 0, (LPARAM)&st_test); 1327 expect(0, res); 1328 1329 res = SendMessageA(hwnd, MCM_GETTODAY, 0, (LPARAM)&st_new); 1330 expect(1, res); 1331 1332 /* st_test should not change */ 1333 expect(38, st_test.wDay); 1334 expect(38, st_test.wMonth); 1335 1336 /* st_new should change, overflow does not matter */ 1337 expect(38, st_new.wDay); 1338 expect(38, st_new.wMonth); 1339 1340 /* check for zero, should be ok*/ 1341 st_test.wDay = 0; 1342 st_test.wMonth = 0; 1343 1344 res = SendMessageA(hwnd, MCM_SETTODAY, 0, (LPARAM)&st_test); 1345 expect(0, res); 1346 1347 res = SendMessageA(hwnd, MCM_GETTODAY, 0, (LPARAM)&st_new); 1348 expect(1, res); 1349 1350 /* st_test should not change */ 1351 expect(0, st_test.wDay); 1352 expect(0, st_test.wMonth); 1353 1354 /* st_new should change to zero*/ 1355 expect(0, st_new.wDay); 1356 expect(0, st_new.wMonth); 1357 1358 ok_sequence(sequences, MONTHCAL_SEQ_INDEX, monthcal_today_seq, "monthcal today", TRUE); 1359 1360 DestroyWindow(hwnd); 1361 } 1362 1363 static void test_scroll(void) 1364 { 1365 int res; 1366 HWND hwnd; 1367 1368 hwnd = create_monthcal_control(0); 1369 1370 res = SendMessageA(hwnd, MCM_GETMONTHDELTA, 0, 0); 1371 expect(2, res); 1372 1373 flush_sequences(sequences, NUM_MSG_SEQUENCES); 1374 1375 /* Setter and Getters for scroll rate */ 1376 res = SendMessageA(hwnd, MCM_SETMONTHDELTA, 2, 0); 1377 expect(0, res); 1378 1379 res = SendMessageA(hwnd, MCM_SETMONTHDELTA, 3, 0); 1380 expect(2, res); 1381 res = SendMessageA(hwnd, MCM_GETMONTHDELTA, 0, 0); 1382 expect(3, res); 1383 1384 res = SendMessageA(hwnd, MCM_SETMONTHDELTA, 12, 0); 1385 expect(3, res); 1386 res = SendMessageA(hwnd, MCM_GETMONTHDELTA, 0, 0); 1387 expect(12, res); 1388 1389 res = SendMessageA(hwnd, MCM_SETMONTHDELTA, 15, 0); 1390 expect(12, res); 1391 res = SendMessageA(hwnd, MCM_GETMONTHDELTA, 0, 0); 1392 expect(15, res); 1393 1394 res = SendMessageA(hwnd, MCM_SETMONTHDELTA, -5, 0); 1395 expect(15, res); 1396 res = SendMessageA(hwnd, MCM_GETMONTHDELTA, 0, 0); 1397 expect(-5, res); 1398 1399 ok_sequence(sequences, MONTHCAL_SEQ_INDEX, monthcal_scroll_seq, "monthcal scroll", FALSE); 1400 1401 DestroyWindow(hwnd); 1402 } 1403 1404 static void test_monthrange(void) 1405 { 1406 int res; 1407 SYSTEMTIME st_visible[2], st_daystate[2], st; 1408 HWND hwnd; 1409 RECT r; 1410 1411 hwnd = create_monthcal_control(0); 1412 1413 memset(&st_visible, 0, sizeof(st_visible)); 1414 memset(&st_daystate, 0, sizeof(st_daystate)); 1415 1416 st.wYear = 2000; 1417 st.wMonth = 11; 1418 st.wDay = 28; 1419 st.wHour = 11; 1420 st.wMinute = 59; 1421 st.wSecond = 30; 1422 st.wMilliseconds = 0; 1423 st.wDayOfWeek = 0; 1424 1425 res = SendMessageA(hwnd, MCM_SETCURSEL, 0, (LPARAM)&st); 1426 expect(1,res); 1427 1428 /* to be locale independent */ 1429 SendMessageA(hwnd, MCM_SETFIRSTDAYOFWEEK, 0, (LPARAM)6); 1430 1431 res = SendMessageA(hwnd, MCM_GETMINREQRECT, 0, (LPARAM)&r); 1432 expect(TRUE, res); 1433 /* resize control to display two Calendars */ 1434 MoveWindow(hwnd, 0, 0, r.right, (5/2)*r.bottom, FALSE); 1435 1436 flush_sequences(sequences, NUM_MSG_SEQUENCES); 1437 1438 res = SendMessageA(hwnd, MCM_GETMONTHRANGE, GMR_VISIBLE, (LPARAM)st_visible); 1439 expect(2, res); 1440 expect(2000, st_visible[0].wYear); 1441 expect(11, st_visible[0].wMonth); 1442 expect(1, st_visible[0].wDay); 1443 expect(2000, st_visible[1].wYear); 1444 expect(12, st_visible[1].wMonth); 1445 expect(31, st_visible[1].wDay); 1446 1447 res = SendMessageA(hwnd, MCM_GETMONTHRANGE, GMR_DAYSTATE, (LPARAM)st_daystate); 1448 expect(4, res); 1449 expect(2000, st_daystate[0].wYear); 1450 expect(10, st_daystate[0].wMonth); 1451 expect(29, st_daystate[0].wDay); 1452 expect(2001, st_daystate[1].wYear); 1453 expect(1, st_daystate[1].wMonth); 1454 expect(6, st_daystate[1].wDay); 1455 1456 ok_sequence(sequences, MONTHCAL_SEQ_INDEX, monthcal_monthrange_seq, "monthcal monthrange", FALSE); 1457 1458 /* with null date array parameter */ 1459 res = SendMessageA(hwnd, MCM_GETMONTHRANGE, GMR_VISIBLE, 0); 1460 expect(2, res); 1461 1462 res = SendMessageA(hwnd, MCM_GETMONTHRANGE, GMR_DAYSTATE, 0); 1463 expect(4, res); 1464 1465 /* resize control to display single Calendar */ 1466 MoveWindow(hwnd, 0, 0, r.right, r.bottom, FALSE); 1467 1468 memset(&st, 0, sizeof(st)); 1469 st.wMonth = 9; 1470 st.wYear = 1752; 1471 st.wDay = 14; 1472 1473 res = SendMessageA(hwnd, MCM_SETCURSEL, 0, (LPARAM)&st); 1474 expect(1, res); 1475 1476 /* September 1752 has 19 days */ 1477 res = SendMessageA(hwnd, MCM_GETMONTHRANGE, GMR_VISIBLE, (LPARAM)st_visible); 1478 expect(1, res); 1479 1480 expect(1752, st_visible[0].wYear); 1481 expect(9, st_visible[0].wMonth); 1482 ok(14 == st_visible[0].wDay || 1483 broken(1 == st_visible[0].wDay), /* comctl32 <= 4.72 */ 1484 "Expected 14, got %d\n", st_visible[0].wDay); 1485 1486 expect(1752, st_visible[1].wYear); 1487 expect(9, st_visible[1].wMonth); 1488 expect(19, st_visible[1].wDay); 1489 1490 DestroyWindow(hwnd); 1491 } 1492 1493 static void test_maxselday(void) 1494 { 1495 int res; 1496 HWND hwnd; 1497 DWORD style; 1498 1499 hwnd = create_monthcal_control(0); 1500 /* if no style specified default to 1 */ 1501 res = SendMessageA(hwnd, MCM_GETMAXSELCOUNT, 0, 0); 1502 expect(1, res); 1503 res = SendMessageA(hwnd, MCM_SETMAXSELCOUNT, 5, 0); 1504 expect(0, res); 1505 res = SendMessageA(hwnd, MCM_GETMAXSELCOUNT, 0, 0); 1506 expect(1, res); 1507 1508 /* try to set style */ 1509 style = GetWindowLongA(hwnd, GWL_STYLE); 1510 SetWindowLongA(hwnd, GWL_STYLE, style | MCS_MULTISELECT); 1511 style = GetWindowLongA(hwnd, GWL_STYLE); 1512 ok(!(style & MCS_MULTISELECT), "Expected MCS_MULTISELECT not to be set\n"); 1513 DestroyWindow(hwnd); 1514 1515 hwnd = create_monthcal_control(MCS_MULTISELECT); 1516 /* try to remove style */ 1517 style = GetWindowLongA(hwnd, GWL_STYLE); 1518 SetWindowLongA(hwnd, GWL_STYLE, style & ~MCS_MULTISELECT); 1519 style = GetWindowLongA(hwnd, GWL_STYLE); 1520 ok(style & MCS_MULTISELECT, "Expected MCS_MULTISELECT to be set\n"); 1521 DestroyWindow(hwnd); 1522 1523 hwnd = create_monthcal_control(MCS_MULTISELECT); 1524 1525 /* default width is a week */ 1526 res = SendMessageA(hwnd, MCM_GETMAXSELCOUNT, 0, 0); 1527 expect(7, res); 1528 1529 flush_sequences(sequences, NUM_MSG_SEQUENCES); 1530 1531 /* Setter and Getters for max selected days */ 1532 res = SendMessageA(hwnd, MCM_SETMAXSELCOUNT, 5, 0); 1533 expect(1, res); 1534 res = SendMessageA(hwnd, MCM_GETMAXSELCOUNT, 0, 0); 1535 expect(5, res); 1536 1537 res = SendMessageA(hwnd, MCM_SETMAXSELCOUNT, 15, 0); 1538 expect(1, res); 1539 res = SendMessageA(hwnd, MCM_GETMAXSELCOUNT, 0, 0); 1540 expect(15, res); 1541 1542 /* test invalid value */ 1543 res = SendMessageA(hwnd, MCM_SETMAXSELCOUNT, -1, 0); 1544 expect(0, res); 1545 res = SendMessageA(hwnd, MCM_GETMAXSELCOUNT, 0, 0); 1546 expect(15, res); 1547 1548 ok_sequence(sequences, MONTHCAL_SEQ_INDEX, monthcal_max_sel_day_seq, "monthcal MaxSelDay", FALSE); 1549 1550 /* zero value is invalid too */ 1551 res = SendMessageA(hwnd, MCM_SETMAXSELCOUNT, 0, 0); 1552 expect(0, res); 1553 res = SendMessageA(hwnd, MCM_GETMAXSELCOUNT, 0, 0); 1554 expect(15, res); 1555 1556 DestroyWindow(hwnd); 1557 } 1558 1559 static void test_size(void) 1560 { 1561 int res; 1562 RECT r1, r2; 1563 HFONT hFont1, hFont2; 1564 LOGFONTA logfont; 1565 HWND hwnd; 1566 1567 hwnd = create_monthcal_control(0); 1568 1569 lstrcpyA(logfont.lfFaceName, "Arial"); 1570 memset(&logfont, 0, sizeof(logfont)); 1571 logfont.lfHeight = 12; 1572 hFont1 = CreateFontIndirectA(&logfont); 1573 1574 logfont.lfHeight = 24; 1575 hFont2 = CreateFontIndirectA(&logfont); 1576 1577 /* initialize to a font we can compare against */ 1578 SendMessageA(hwnd, WM_SETFONT, (WPARAM)hFont1, 0); 1579 res = SendMessageA(hwnd, MCM_GETMINREQRECT, 0, (LPARAM)&r1); 1580 ok(res, "SendMessageA(MCM_GETMINREQRECT) failed\n"); 1581 1582 /* check that setting a larger font results in an larger rect */ 1583 SendMessageA(hwnd, WM_SETFONT, (WPARAM)hFont2, 0); 1584 res = SendMessageA(hwnd, MCM_GETMINREQRECT, 0, (LPARAM)&r2); 1585 ok(res, "SendMessageA(MCM_GETMINREQRECT) failed\n"); 1586 1587 OffsetRect(&r1, -r1.left, -r1.top); 1588 OffsetRect(&r2, -r2.left, -r2.top); 1589 1590 ok(r1.bottom < r2.bottom, "Failed to get larger rect with larger font\n"); 1591 1592 DestroyWindow(hwnd); 1593 } 1594 1595 static void test_create(void) 1596 { 1597 HWND hwnd; 1598 1599 flush_sequences(sequences, NUM_MSG_SEQUENCES); 1600 1601 hwnd = create_monthcal_control(0); 1602 ok_sequence(sequences, PARENT_SEQ_INDEX, create_monthcal_control_seq, "create monthcal control", TRUE); 1603 1604 DestroyWindow(hwnd); 1605 1606 flush_sequences(sequences, NUM_MSG_SEQUENCES); 1607 hwnd = create_monthcal_control(MCS_MULTISELECT); 1608 ok_sequence(sequences, PARENT_SEQ_INDEX, create_monthcal_multi_sel_style_seq, "create monthcal (multi sel style)", TRUE); 1609 DestroyWindow(hwnd); 1610 } 1611 1612 static void test_destroy(void) 1613 { 1614 HWND hwnd; 1615 1616 hwnd = create_monthcal_control(0); 1617 flush_sequences(sequences, NUM_MSG_SEQUENCES); 1618 DestroyWindow(hwnd); 1619 ok_sequence(sequences, PARENT_SEQ_INDEX, destroy_monthcal_parent_msgs_seq, "Destroy monthcal (parent msg)", FALSE); 1620 ok_sequence(sequences, MONTHCAL_SEQ_INDEX, destroy_monthcal_child_msgs_seq, "Destroy monthcal (child msg)", FALSE); 1621 1622 /* MCS_MULTISELECT */ 1623 hwnd = create_monthcal_control(MCS_MULTISELECT); 1624 flush_sequences(sequences, NUM_MSG_SEQUENCES); 1625 DestroyWindow(hwnd); 1626 ok_sequence(sequences, MONTHCAL_SEQ_INDEX, destroy_monthcal_multi_sel_style_seq, "Destroy monthcal (multi sel style)", FALSE); 1627 } 1628 1629 static void test_selrange(void) 1630 { 1631 HWND hwnd; 1632 SYSTEMTIME st, range[2], range2[2]; 1633 BOOL ret, old_comctl32 = FALSE; 1634 1635 hwnd = create_monthcal_control(MCS_MULTISELECT); 1636 1637 /* just after creation selection should start and end today */ 1638 ret = SendMessageA(hwnd, MCM_GETTODAY, 0, (LPARAM)&st); 1639 expect(TRUE, ret); 1640 1641 memset(range, 0xcc, sizeof(range)); 1642 ret = SendMessageA(hwnd, MCM_GETSELRANGE, 0, (LPARAM)range); 1643 expect(TRUE, ret); 1644 expect(st.wYear, range[0].wYear); 1645 expect(st.wMonth, range[0].wMonth); 1646 expect(st.wDay, range[0].wDay); 1647 if (range[0].wDayOfWeek != st.wDayOfWeek) 1648 { 1649 win_skip("comctl32 <= 4.70 doesn't set some values\n"); 1650 old_comctl32 = TRUE; 1651 } 1652 else 1653 { 1654 expect(st.wDayOfWeek, range[0].wDayOfWeek); 1655 expect(st.wHour, range[0].wHour); 1656 expect(st.wMinute, range[0].wMinute); 1657 expect(st.wSecond, range[0].wSecond); 1658 expect(st.wMilliseconds, range[0].wMilliseconds); 1659 } 1660 1661 expect(st.wYear, range[1].wYear); 1662 expect(st.wMonth, range[1].wMonth); 1663 expect(st.wDay, range[1].wDay); 1664 if (!old_comctl32) 1665 { 1666 expect(st.wDayOfWeek, range[1].wDayOfWeek); 1667 expect(st.wHour, range[1].wHour); 1668 expect(st.wMinute, range[1].wMinute); 1669 expect(st.wSecond, range[1].wSecond); 1670 expect(st.wMilliseconds, range[1].wMilliseconds); 1671 } 1672 1673 /* bounds are swapped if min > max */ 1674 memset(&range[0], 0, sizeof(range[0])); 1675 range[0].wYear = 2009; 1676 range[0].wMonth = 10; 1677 range[0].wDay = 5; 1678 range[1] = range[0]; 1679 range[1].wDay = 3; 1680 1681 ret = SendMessageA(hwnd, MCM_SETSELRANGE, 0, (LPARAM)range); 1682 expect(TRUE, ret); 1683 1684 ret = SendMessageA(hwnd, MCM_GETSELRANGE, 0, (LPARAM)range2); 1685 expect(TRUE, ret); 1686 1687 expect(range[1].wYear, range2[0].wYear); 1688 expect(range[1].wMonth, range2[0].wMonth); 1689 expect(range[1].wDay, range2[0].wDay); 1690 expect(6, range2[0].wDayOfWeek); 1691 expect(range[1].wHour, range2[0].wHour); 1692 expect(range[1].wMinute, range2[0].wMinute); 1693 expect(range[1].wSecond, range2[0].wSecond); 1694 expect(range[1].wMilliseconds, range2[0].wMilliseconds); 1695 1696 expect(range[0].wYear, range2[1].wYear); 1697 expect(range[0].wMonth, range2[1].wMonth); 1698 expect(range[0].wDay, range2[1].wDay); 1699 expect(1, range2[1].wDayOfWeek); 1700 expect(range[0].wHour, range2[1].wHour); 1701 expect(range[0].wMinute, range2[1].wMinute); 1702 expect(range[0].wSecond, range2[1].wSecond); 1703 expect(range[0].wMilliseconds, range2[1].wMilliseconds); 1704 1705 /* try with range larger than maximum configured */ 1706 memset(&range[0], 0, sizeof(range[0])); 1707 range[0].wYear = 2009; 1708 range[0].wMonth = 10; 1709 range[0].wDay = 1; 1710 range[1] = range[0]; 1711 1712 ret = SendMessageA(hwnd, MCM_SETSELRANGE, 0, (LPARAM)range); 1713 expect(TRUE, ret); 1714 1715 range[1] = range[0]; 1716 /* default max. range is 7 days */ 1717 range[1].wDay = 8; 1718 1719 ret = SendMessageA(hwnd, MCM_SETSELRANGE, 0, (LPARAM)range); 1720 expect(FALSE, ret); 1721 1722 ret = SendMessageA(hwnd, MCM_GETSELRANGE, 0, (LPARAM)range2); 1723 expect(TRUE, ret); 1724 1725 expect(range[0].wYear, range2[0].wYear); 1726 expect(range[0].wMonth, range2[0].wMonth); 1727 expect(range[0].wDay, range2[0].wDay); 1728 expect(range[0].wYear, range2[1].wYear); 1729 expect(range[0].wMonth, range2[1].wMonth); 1730 expect(range[0].wDay, range2[1].wDay); 1731 1732 DestroyWindow(hwnd); 1733 } 1734 1735 static void test_killfocus(void) 1736 { 1737 HWND hwnd; 1738 DWORD style; 1739 1740 hwnd = create_monthcal_control(0); 1741 1742 /* make parent invisible */ 1743 style = GetWindowLongA(parent_wnd, GWL_STYLE); 1744 SetWindowLongA(parent_wnd, GWL_STYLE, style & ~WS_VISIBLE); 1745 1746 SendMessageA(hwnd, WM_KILLFOCUS, (WPARAM)GetDesktopWindow(), 0); 1747 1748 style = GetWindowLongA(hwnd, GWL_STYLE); 1749 ok(style & WS_VISIBLE, "Expected WS_VISIBLE to be set\n"); 1750 1751 style = GetWindowLongA(parent_wnd, GWL_STYLE); 1752 SetWindowLongA(parent_wnd, GWL_STYLE, style | WS_VISIBLE); 1753 1754 DestroyWindow(hwnd); 1755 } 1756 1757 static void test_hittest_v6(void) 1758 { 1759 MCHITTESTINFO mchit; 1760 DWORD ret; 1761 HWND hwnd; 1762 RECT r; 1763 1764 hwnd = create_monthcal_control(0); 1765 SendMessageA(hwnd, MCM_SETCALENDARBORDER, TRUE, 0); 1766 1767 SendMessageA(hwnd, MCM_GETMINREQRECT, 0, (LPARAM)&r); 1768 /* reserving some area around calendar */ 1769 MoveWindow(hwnd, 0, 0, r.right * 3 / 2, r.bottom * 3 / 2, FALSE); 1770 mchit.cbSize = sizeof(MCHITTESTINFO); 1771 mchit.pt.x = mchit.pt.y = 0; 1772 mchit.iOffset = -1; 1773 mchit.iRow = -1; 1774 mchit.iCol = -1; 1775 ret = SendMessageA(hwnd, MCM_HITTEST, 0, (LPARAM)&mchit); 1776 if (ret == ~0u) 1777 { 1778 win_skip("Only MCHITTESTINFO_V1 supported\n"); 1779 DestroyWindow(hwnd); 1780 return; 1781 } 1782 todo_wine expect_hex(MCHT_NOWHERE, ret); 1783 expect(-1, mchit.iOffset); 1784 expect(-1, mchit.iRow); 1785 expect(-1, mchit.iCol); 1786 1787 MoveWindow(hwnd, 0, 0, r.right, r.bottom, FALSE); 1788 mchit.pt.x = r.right / 2; 1789 mchit.pt.y = r.bottom / 2; 1790 mchit.iOffset = -1; 1791 ret = SendMessageA(hwnd, MCM_HITTEST, 0, (LPARAM)&mchit); 1792 expect_hex(MCHT_CALENDARDATE, ret); 1793 expect(0, mchit.iOffset); 1794 1795 /* over day area */ 1796 mchit.pt.x = r.right / (7*2); 1797 mchit.pt.y = r.bottom / 2; 1798 mchit.iOffset = -1; 1799 mchit.iCol = mchit.iRow = -1; 1800 mchit.uHit = 0; 1801 SetRect(&mchit.rc, -1, -1, -1, -1); 1802 ret = SendMessageA(hwnd, MCM_HITTEST, 0, (LPARAM)&mchit); 1803 expect_hex(MCHT_CALENDARDATE, ret); 1804 expect_hex(MCHT_CALENDARDATE, mchit.uHit); 1805 expect(0, mchit.iOffset); 1806 expect(2, mchit.iRow); 1807 expect(0, mchit.iCol); 1808 /* returned a one day rectangle */ 1809 expect_d(r.right / 7, mchit.rc.right - mchit.rc.left); 1810 expect_d(r.bottom / 10, mchit.rc.bottom - mchit.rc.top); 1811 1812 /* title */ 1813 mchit.pt.x = 1; 1814 mchit.pt.y = 1; 1815 mchit.iOffset = -1; 1816 mchit.iCol = mchit.iRow = -1; 1817 mchit.uHit = 0; 1818 SetRect(&mchit.rc, -1, -1, -1, -1); 1819 ret = SendMessageA(hwnd, MCM_HITTEST, 0, (LPARAM)&mchit); 1820 expect_hex(MCHT_TITLE, ret); 1821 expect_hex(MCHT_TITLE, mchit.uHit); 1822 expect(0, mchit.iOffset); 1823 expect(-1, mchit.iRow); 1824 expect(-1, mchit.iCol); 1825 expect(0, mchit.rc.left); 1826 expect(0, mchit.rc.top); 1827 expect_d(r.right, mchit.rc.right); 1828 ok(mchit.rc.bottom > 0, "got %d\n", mchit.rc.bottom); 1829 1830 /* between two calendars */ 1831 MoveWindow(hwnd, 0, 0, r.right * 5/2, r.bottom, FALSE); 1832 mchit.pt.x = r.right / (5*4); 1833 mchit.pt.y = r.bottom / 2; 1834 mchit.iOffset = -2; 1835 mchit.iCol = mchit.iRow = -2; 1836 mchit.uHit = ~0; 1837 SetRect(&mchit.rc, -1, -1, -1, -1); 1838 ret = SendMessageA(hwnd, MCM_HITTEST, 0, (LPARAM)&mchit); 1839 todo_wine expect_hex(MCHT_NOWHERE, ret); 1840 todo_wine expect_hex(MCHT_NOWHERE, mchit.uHit); 1841 expect(-2, mchit.iOffset); 1842 expect(-2, mchit.iRow); 1843 expect(-2, mchit.iCol); 1844 todo_wine expect(0, mchit.rc.left); 1845 todo_wine expect(0, mchit.rc.top); 1846 todo_wine expect_d(r.right * 5/2, mchit.rc.right); 1847 todo_wine expect_d(r.bottom, mchit.rc.bottom); 1848 1849 DestroyWindow(hwnd); 1850 } 1851 1852 static void test_get_set_border(void) 1853 { 1854 HWND hwnd; 1855 DWORD ret; 1856 1857 hwnd = create_monthcal_control(0); 1858 1859 /* a non-default value */ 1860 ret = SendMessageA(hwnd, MCM_SETCALENDARBORDER, TRUE, 10); 1861 expect(0, ret); 1862 1863 ret = SendMessageA(hwnd, MCM_GETCALENDARBORDER, 0, 0); 1864 1865 if (ret != 10) 1866 { 1867 skip("MCM_GET/SETCALENDARBORDER not supported\n"); 1868 DestroyWindow(hwnd); 1869 return; 1870 } 1871 1872 expect(10, ret); 1873 1874 DestroyWindow(hwnd); 1875 } 1876 1877 static void test_MCM_SIZERECTTOMIN(void) 1878 { 1879 HWND hwnd; 1880 DWORD ret; 1881 RECT r, r2; 1882 1883 hwnd = create_monthcal_control(0); 1884 1885 ret = SendMessageA(hwnd, MCM_GETMINREQRECT, 0, (LPARAM)&r2); 1886 if (ret == 0) 1887 { 1888 win_skip("Message MCM_GETMINREQRECT unsupported. Skipping.\n"); 1889 DestroyWindow(hwnd); 1890 return; 1891 } 1892 1893 ret = SendMessageA(hwnd, MCM_SIZERECTTOMIN, 0, 0); 1894 ok(ret == 0, "got %d\n", ret); 1895 1896 SetRectEmpty(&r); 1897 ret = SendMessageA(hwnd, MCM_SIZERECTTOMIN, 0, (LPARAM)&r); 1898 if (ret == 0) 1899 { 1900 skip("Message MCM_SIZERECTTOMIN unsupported. Skipping.\n"); 1901 DestroyWindow(hwnd); 1902 return; 1903 } 1904 ok(ret == 1, "got %d\n", ret); 1905 ok(r.left == 0 && r.right > 0, "got %d, %d\n", r.left, r.right); 1906 1907 r = r2; 1908 ret = SendMessageA(hwnd, MCM_SIZERECTTOMIN, 0, (LPARAM)&r); 1909 ok(ret == 1, "got %d\n", ret); 1910 1911 r2.right = (r2.right - r2.left) * 3; 1912 r2.bottom = (r2.bottom - r2.top) * 3; 1913 r2.left = r2.top = 0; 1914 ret = SendMessageA(hwnd, MCM_SIZERECTTOMIN, 0, (LPARAM)&r2); 1915 ok(ret == 1, "got %d\n", ret); 1916 1917 DestroyWindow(hwnd); 1918 } 1919 1920 static void test_MCM_GETCALENDARCOUNT(void) 1921 { 1922 HWND hwnd; 1923 DWORD ret; 1924 1925 hwnd = create_monthcal_control(0); 1926 1927 ret = SendMessageA(hwnd, MCM_GETCALENDARCOUNT, 0, 0); 1928 if (ret == 0) 1929 { 1930 win_skip("Message MCM_GETCALENDARCOUNT unsupported. Skipping.\n"); 1931 DestroyWindow(hwnd); 1932 return; 1933 } 1934 1935 expect(2, ret); 1936 1937 DestroyWindow(hwnd); 1938 } 1939 1940 static void test_daystate(void) 1941 { 1942 MONTHDAYSTATE state[4]; 1943 DWORD ret, style; 1944 HWND hwnd; 1945 RECT r; 1946 1947 /* without MCS_DAYSTATE */ 1948 hwnd = create_monthcal_control(0); 1949 1950 ret = SendMessageA(hwnd, MCM_GETMINREQRECT, 0, (LPARAM)&r); 1951 expect(TRUE, ret); 1952 1953 /* resize control to display two Calendars */ 1954 MoveWindow(hwnd, 0, 0, r.right, (5/2)*r.bottom, FALSE); 1955 1956 ret = SendMessageA(hwnd, MCM_GETMONTHRANGE, GMR_DAYSTATE, 0); 1957 expect(4, ret); 1958 1959 ret = SendMessageA(hwnd, MCM_SETDAYSTATE, 4, (LPARAM)&state); 1960 expect(0, ret); 1961 1962 ret = SendMessageA(hwnd, MCM_SETDAYSTATE, 2, (LPARAM)&state); 1963 expect(0, ret); 1964 1965 ret = SendMessageA(hwnd, MCM_SETDAYSTATE, 0, 0); 1966 expect(0, ret); 1967 1968 /* try to switch on */ 1969 SetWindowLongA(hwnd, GWL_STYLE, GetWindowLongA(hwnd, GWL_STYLE) | MCS_DAYSTATE); 1970 style = GetWindowLongA(hwnd, GWL_STYLE); 1971 ok((style & MCS_DAYSTATE) == 0, "got 0x%08x\n", style); 1972 1973 DestroyWindow(hwnd); 1974 1975 /* with MCS_DAYSTATE */ 1976 hwnd = create_monthcal_control(MCS_DAYSTATE); 1977 1978 ret = SendMessageA(hwnd, MCM_GETMONTHRANGE, GMR_DAYSTATE, 0); 1979 expect(4, ret); 1980 1981 ret = SendMessageA(hwnd, MCM_SETDAYSTATE, 4, (LPARAM)&state); 1982 expect(1, ret); 1983 1984 ret = SendMessageA(hwnd, MCM_SETDAYSTATE, 2, (LPARAM)&state); 1985 expect(0, ret); 1986 1987 ret = SendMessageA(hwnd, MCM_SETDAYSTATE, 0, 0); 1988 expect(0, ret); 1989 1990 /* try to switch off */ 1991 SetWindowLongA(hwnd, GWL_STYLE, GetWindowLongA(hwnd, GWL_STYLE) & ~MCS_DAYSTATE); 1992 style = GetWindowLongA(hwnd, GWL_STYLE); 1993 ok((style & MCS_DAYSTATE) == MCS_DAYSTATE, "got 0x%08x\n", style); 1994 1995 DestroyWindow(hwnd); 1996 } 1997 1998 static void test_sel_notify(void) 1999 { 2000 typedef struct 2001 { 2002 DWORD val; 2003 const char* name; 2004 } Monthcal_style; 2005 2006 HWND hwnd; 2007 RECT rc; 2008 MCHITTESTINFO mchit = {sizeof(MCHITTESTINFO)}; 2009 SYSTEMTIME st; 2010 Monthcal_style styles[] = { 2011 {MCS_NOTODAY, "MCS_NOTODAY"}, 2012 {MCS_NOTODAY | MCS_MULTISELECT, "MCS_NOTODAY | MCS_MULTISELECT"}, 2013 {MCS_DAYSTATE, "MCS_DAYSTATE"}, 2014 {MCS_DAYSTATE | MCS_MULTISELECT, "MCS_DAYSTATE | MCS_MULTISELECT"} 2015 }; 2016 int i; 2017 2018 for(i = 0; i < ARRAY_SIZE(styles); i++) 2019 { 2020 hwnd = create_monthcal_control(styles[i].val); 2021 SetWindowLongPtrA(hwnd, GWLP_ID, SEL_NOTIFY_TEST_ID); 2022 SendMessageA(hwnd, MCM_GETMINREQRECT, 0, (LPARAM)&rc); 2023 MoveWindow(hwnd, 0, 0, rc.right, rc.bottom, FALSE); 2024 /* Simulate mouse click on some unselected day to generate 2025 MCN_SELECT and MCN_SELCHANGE notifications */ 2026 mchit.pt.x = rc.right / 2; 2027 mchit.pt.y = rc.bottom / 2; 2028 SendMessageA(hwnd, MCM_HITTEST, 0, (LPARAM)&mchit); 2029 SendMessageA(hwnd, MCM_GETCURSEL, 0, (LPARAM)&st); 2030 while(st.wDay == mchit.st.wDay) /* Ensure that mchit.pt points to unselected day */ 2031 { 2032 mchit.pt.y++; 2033 SendMessageA(hwnd, MCM_HITTEST, 0, (LPARAM)&mchit); 2034 } 2035 SendMessageA(hwnd, WM_LBUTTONDOWN, 0, MAKELPARAM(mchit.pt.x, mchit.pt.y)); 2036 SendMessageA(hwnd, WM_LBUTTONUP, 0, MAKELPARAM(mchit.pt.x, mchit.pt.y)); 2037 DestroyWindow(hwnd); 2038 } 2039 } 2040 2041 static void init_functions(void) 2042 { 2043 HMODULE hComCtl32 = LoadLibraryA("comctl32.dll"); 2044 2045 #define X(f) p##f = (void*)GetProcAddress(hComCtl32, #f); 2046 X(InitCommonControlsEx); 2047 #undef X 2048 } 2049 2050 START_TEST(monthcal) 2051 { 2052 INITCOMMONCONTROLSEX iccex; 2053 ULONG_PTR ctx_cookie; 2054 HANDLE hCtx; 2055 2056 init_functions(); 2057 2058 iccex.dwSize = sizeof(iccex); 2059 iccex.dwICC = ICC_DATE_CLASSES; 2060 pInitCommonControlsEx(&iccex); 2061 2062 test_monthcal(); 2063 2064 init_msg_sequences(sequences, NUM_MSG_SEQUENCES); 2065 2066 parent_wnd = create_parent_window(); 2067 2068 test_create(); 2069 test_destroy(); 2070 test_color(); 2071 test_currdate(); 2072 test_firstDay(); 2073 test_unicode(); 2074 test_today(); 2075 test_scroll(); 2076 test_monthrange(); 2077 test_hittest(); 2078 test_todaylink(); 2079 test_size(); 2080 test_maxselday(); 2081 test_selrange(); 2082 test_killfocus(); 2083 test_daystate(); 2084 test_sel_notify(); 2085 2086 if (!load_v6_module(&ctx_cookie, &hCtx)) 2087 { 2088 DestroyWindow(parent_wnd); 2089 return; 2090 } 2091 2092 test_hittest_v6(); 2093 test_get_set_border(); 2094 test_MCM_SIZERECTTOMIN(); 2095 test_MCM_GETCALENDARCOUNT(); 2096 2097 unload_v6_module(ctx_cookie, hCtx); 2098 2099 DestroyWindow(parent_wnd); 2100 } 2101