1 /* 2 * PROJECT: ReactOS api tests 3 * LICENSE: GPL - See COPYING in the top level directory 4 * PURPOSE: Test for Button window class v6 5 * PROGRAMMERS: Giannis Adamopoulos 6 */ 7 8 #include "wine/test.h" 9 #include <stdio.h> 10 #include <windows.h> 11 #include <commctrl.h> 12 #include <uxtheme.h> 13 #include <undocuser.h> 14 #include <msgtrace.h> 15 #include <user32testhelpers.h> 16 17 #define ok_rect(rc, l,r,t,b) ok((rc.left == (l)) && (rc.right == (r)) && (rc.top == (t)) && (rc.bottom == (b)), "Wrong rect. expected %d, %d, %d, %d got %ld, %ld, %ld, %ld\n", l,t,r,b, rc.left, rc.top, rc.right, rc.bottom) 18 #define ok_size(s, width, height) ok((s.cx == (width) && s.cy == (height)), "Expected size (%lu,%lu) got (%lu,%lu)\n", (LONG)width, (LONG)height, s.cx, s.cy) 19 20 void Test_TextMargin() 21 { 22 RECT rc; 23 BOOL ret; 24 HWND hwnd1; 25 26 hwnd1 = CreateWindowW(L"Button", L"Test1", 0, 10, 10, 100, 100, 0, NULL, NULL, NULL); 27 ok (hwnd1 != NULL, "Expected CreateWindowW to succeed\n"); 28 SetWindowTheme(hwnd1, L"", L""); 29 30 ret = SendMessageW(hwnd1, BCM_GETTEXTMARGIN, 0, (LPARAM)&rc); 31 ok (ret == TRUE, "Expected BCM_GETTEXTMARGIN to succeed\n"); 32 ok_rect(rc, 1, 1, 1, 1); 33 34 SetRect(&rc, 0,0,0,0); 35 ret = SendMessageW(hwnd1, BCM_SETTEXTMARGIN, 0, (LPARAM)&rc); 36 ok (ret == TRUE, "Expected BCM_SETTEXTMARGIN to succeed\n"); 37 38 ret = SendMessageW(hwnd1, BCM_GETTEXTMARGIN, 0, (LPARAM)&rc); 39 ok (ret == TRUE, "Expected BCM_GETTEXTMARGIN to succeed\n"); 40 ok_rect(rc, 0, 0, 0, 0); 41 42 SetRect(&rc, -1,-1,-1,-1); 43 ret = SendMessageW(hwnd1, BCM_SETTEXTMARGIN, 0, (LPARAM)&rc); 44 ok (ret == TRUE, "Expected BCM_SETTEXTMARGIN to succeed\n"); 45 46 ret = SendMessageW(hwnd1, BCM_GETTEXTMARGIN, 0, (LPARAM)&rc); 47 ok (ret == TRUE, "Expected BCM_GETTEXTMARGIN to succeed\n"); 48 ok_rect(rc, -1, -1, -1, -1); 49 50 SetRect(&rc, 1000,1000,1000,1000); 51 ret = SendMessageW(hwnd1, BCM_SETTEXTMARGIN, 0, (LPARAM)&rc); 52 ok (ret == TRUE, "Expected BCM_SETTEXTMARGIN to succeed\n"); 53 54 ret = SendMessageW(hwnd1, BCM_GETTEXTMARGIN, 0, (LPARAM)&rc); 55 ok (ret == TRUE, "Expected BCM_GETTEXTMARGIN to succeed\n"); 56 ok_rect(rc, 1000, 1000, 1000, 1000); 57 58 DestroyWindow(hwnd1); 59 60 hwnd1 = CreateWindowW(L"Button", L"Test1", BS_DEFPUSHBUTTON, 10, 10, 100, 100, 0, NULL, NULL, NULL); 61 ok (hwnd1 != NULL, "Expected CreateWindowW to succeed\n"); 62 SetWindowTheme(hwnd1, L"", L""); 63 64 ret = SendMessageW(hwnd1, BCM_GETTEXTMARGIN, 0, (LPARAM)&rc); 65 ok (ret == TRUE, "Expected BCM_GETTEXTMARGIN to succeed\n"); 66 ok_rect(rc, 1, 1, 1, 1); 67 68 DestroyWindow(hwnd1); 69 70 } 71 72 void Test_Imagelist() 73 { 74 HWND hwnd1; 75 BOOL ret; 76 BUTTON_IMAGELIST imlData; 77 78 hwnd1 = CreateWindowW(L"Button", L"Test2", 0, 10, 10, 100, 100, 0, NULL, NULL, NULL); 79 ok (hwnd1 != NULL, "Expected CreateWindowW to succeed\n"); 80 81 ret = SendMessageW(hwnd1, BCM_GETIMAGELIST, 0, (LPARAM)&imlData); 82 ok (ret == TRUE, "Expected BCM_GETIMAGELIST to succeed\n"); 83 ok (imlData.himl == 0, "Expected 0 himl\n"); 84 ok (imlData.uAlign == 0, "Expected 0 uAlign\n"); 85 ok_rect(imlData.margin, 0, 0, 0, 0); 86 87 SetRect(&imlData.margin, 0,0,0,1); 88 ret = SendMessageW(hwnd1, BCM_SETIMAGELIST, 0, (LPARAM)&imlData); 89 ok (ret == FALSE, "Expected BCM_SETIMAGELIST to fail\n"); /* This works in win10 */ 90 91 imlData.himl = (HIMAGELIST)0xdead; 92 ret = SendMessageW(hwnd1, BCM_SETIMAGELIST, 0, (LPARAM)&imlData); 93 ok (ret == TRUE, "Expected BCM_SETIMAGELIST to fail\n"); 94 95 ret = SendMessageW(hwnd1, BCM_GETIMAGELIST, 0, (LPARAM)&imlData); 96 ok (ret == TRUE, "Expected BCM_GETIMAGELIST to succeed\n"); 97 ok (imlData.himl == (HIMAGELIST)0xdead, "Expected 0 himl\n"); 98 ok (imlData.uAlign == 0, "Expected 0 uAlign\n"); 99 ok_rect(imlData.margin, 0, 0, 0, 1); 100 101 imlData.himl = 0; 102 ret = SendMessageW(hwnd1, BCM_SETIMAGELIST, 0, (LPARAM)&imlData); 103 ok (ret == FALSE, "Expected BCM_SETIMAGELIST to fail\n"); /* This works in win10 */ 104 105 DestroyWindow(hwnd1); 106 } 107 108 void Test_GetIdealSizeNoThemes() 109 { 110 HWND hwnd1, hwnd2; 111 BOOL ret; 112 SIZE s, textent; 113 HFONT font; 114 HDC hdc; 115 HANDLE hbmp; 116 HIMAGELIST himl; 117 BUTTON_IMAGELIST imlData; 118 RECT rc; 119 LOGFONTW lf; 120 DWORD i; 121 122 hwnd2 = CreateWindowW(L"Static", L"", 0, 0, 0, 100, 100, 0, NULL, NULL, NULL); 123 ok (hwnd2 != NULL, "Expected CreateWindowW to succeed\n"); 124 125 hwnd1 = CreateWindowW(L"Button", L" ", WS_CHILD, 10, 10, 100, 100, hwnd2, NULL, NULL, NULL); 126 ok (hwnd1 != NULL, "Expected CreateWindowW to succeed\n"); 127 SetWindowTheme(hwnd1, L"", L""); 128 129 font = (HFONT)SendMessageW(hwnd1, WM_GETFONT, 0, 0); 130 hdc = GetDC(hwnd1); 131 SelectObject(hdc, font); 132 GetTextExtentPoint32W(hdc, L" ", 1, &textent); 133 134 memset(&s, 0, sizeof(s)); 135 ret = SendMessageW(hwnd1, BCM_GETIDEALSIZE, 0, (LPARAM)&s); 136 ok (ret == TRUE, "Expected BCM_GETIDEALSIZE to succeed\n"); 137 ok_size(s, textent.cx + 5 + 2, 138 textent.cy + 7 + 2); /* the last +2 is the text margin */ 139 140 DestroyWindow(hwnd1); 141 142 143 hwnd1 = CreateWindowW(L"Button", L" ", BS_USERBUTTON | WS_CHILD, 10, 10, 100, 100, hwnd2, NULL, NULL, NULL); 144 ok (hwnd1 != NULL, "Expected CreateWindowW to succeed\n"); 145 SetWindowTheme(hwnd1, L"", L""); 146 147 memset(&s, 0, sizeof(s)); 148 ret = SendMessageW(hwnd1, BCM_GETIDEALSIZE, 0, (LPARAM)&s); 149 ok (ret == TRUE, "Expected BCM_GETIDEALSIZE to succeed\n"); 150 ok_size(s, textent.cx + 5 + 2, 151 textent.cy + 7 + 2); /* the last +2 is the text margin */ 152 153 DestroyWindow(hwnd1); 154 155 156 157 hwnd1 = CreateWindowW(L"Button", L"", WS_CHILD, 10, 10, 100, 100, hwnd2, NULL, NULL, NULL); 158 ok (hwnd1 != NULL, "Expected CreateWindowW to succeed\n"); 159 SetWindowTheme(hwnd1, L"", L""); 160 161 s.cx = 1; 162 s.cy = 1; 163 ret = SendMessageW(hwnd1, BCM_GETIDEALSIZE, 0, (LPARAM)&s); 164 ok (ret == TRUE, "Expected BCM_GETIDEALSIZE to succeed\n"); 165 ok_size(s, 100, 100); 166 167 hbmp = LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(5), IMAGE_BITMAP, 0, 0, 0); 168 ok (hbmp != 0, "Expected LoadImage to succeed\n"); 169 170 SendMessageW(hwnd1, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hbmp); 171 172 memset(&s, 0, sizeof(s)); 173 ret = SendMessageW(hwnd1, BCM_GETIDEALSIZE, 0, (LPARAM)&s); 174 ok (ret == TRUE, "Expected BCM_GETIDEALSIZE to succeed\n"); 175 ok_size(s, 100, 100); 176 177 himl = ImageList_LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(5), 1, 1, 0, IMAGE_BITMAP, 0); 178 ok (himl != 0, "Expected ImageList_LoadImage to succeed\n"); 179 180 memset(&imlData, 0, sizeof(imlData)); 181 imlData.himl = himl; 182 ret = SendMessageW(hwnd1, BCM_SETIMAGELIST, 0, (LPARAM)&imlData); 183 ok (ret == TRUE, "Expected BCM_SETIMAGELIST to fail\n"); /* This works in win10 */ 184 185 memset(&s, 0, sizeof(s)); 186 ret = SendMessageW(hwnd1, BCM_GETIDEALSIZE, 0, (LPARAM)&s); 187 ok (ret == TRUE, "Expected BCM_GETIDEALSIZE to succeed\n"); 188 ok_size(s, 100, 100); 189 190 DestroyWindow(hwnd1); 191 192 193 194 195 196 hwnd1 = CreateWindowW(L"Button", L"", WS_CHILD, 10, 10, 5, 5, hwnd2, NULL, NULL, NULL); 197 ok (hwnd1 != NULL, "Expected CreateWindowW to succeed\n"); 198 SetWindowTheme(hwnd1, L"", L""); 199 200 memset(&s, 0, sizeof(s)); 201 ret = SendMessageW(hwnd1, BCM_GETIDEALSIZE, 0, (LPARAM)&s); 202 ok (ret == TRUE, "Expected BCM_GETIDEALSIZE to succeed\n"); 203 ok_size(s, 5, 5); 204 205 DestroyWindow(hwnd1); 206 207 208 209 210 hwnd1 = CreateWindowW(L"Button", L" ", BS_BITMAP | WS_CHILD, 10, 10, 100, 100, hwnd2, NULL, NULL, NULL); 211 ok (hwnd1 != NULL, "Expected CreateWindowW to succeed\n"); 212 SetWindowTheme(hwnd1, L"", L""); 213 214 SendMessageW(hwnd1, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hbmp); 215 216 memset(&s, 0, sizeof(s)); 217 ret = SendMessageW(hwnd1, BCM_GETIDEALSIZE, 0, (LPARAM)&s); 218 ok (ret == TRUE, "Expected BCM_GETIDEALSIZE to succeed\n"); 219 220 /* In xp and 2k3 the image is ignored, in vista+ its width is added to the text width */ 221 ok_size(s, textent.cx + 5 + 2, 222 textent.cy + 7 + 2); /* the last +2 is the text margin */ 223 224 DestroyWindow(hwnd1); 225 226 227 228 hwnd1 = CreateWindowW(L"Button", L" ", WS_CHILD, 10, 10, 100, 100, hwnd2, NULL, NULL, NULL); 229 ok (hwnd1 != NULL, "Expected CreateWindowW to succeed\n"); 230 SetWindowTheme(hwnd1, L"", L""); 231 232 SetRect(&rc, 0,0,0,0); 233 ret = SendMessageW(hwnd1, BCM_SETTEXTMARGIN, 0, (LPARAM)&rc); 234 ok (ret == TRUE, "Expected BCM_SETTEXTMARGIN to succeed\n"); 235 236 memset(&s, 0, sizeof(s)); 237 ret = SendMessageW(hwnd1, BCM_GETIDEALSIZE, 0, (LPARAM)&s); 238 ok (ret == TRUE, "Expected BCM_GETIDEALSIZE to succeed\n"); 239 ok_size(s, textent.cx + 5, 240 textent.cy + 7); 241 242 SetRect(&rc, 50,50,50,50); 243 ret = SendMessageW(hwnd1, BCM_SETTEXTMARGIN, 0, (LPARAM)&rc); 244 ok (ret == TRUE, "Expected BCM_SETTEXTMARGIN to succeed\n"); 245 246 memset(&s, 0, sizeof(s)); 247 ret = SendMessageW(hwnd1, BCM_GETIDEALSIZE, 0, (LPARAM)&s); 248 ok (ret == TRUE, "Expected BCM_GETIDEALSIZE to succeed\n"); 249 ok_size(s, textent.cx + 5 + 100, 250 textent.cy + 7 + 100); 251 252 SetRect(&rc, 1,1,1,1); 253 ret = SendMessageW(hwnd1, BCM_SETTEXTMARGIN, 0, (LPARAM)&rc); 254 ok (ret == TRUE, "Expected BCM_SETTEXTMARGIN to succeed\n"); 255 256 ret = SendMessageW(hwnd1, BCM_SETIMAGELIST, 0, (LPARAM)&imlData); 257 ok (ret == TRUE, "Expected BCM_SETIMAGELIST to fail\n"); 258 259 memset(&s, 0, sizeof(s)); 260 ret = SendMessageW(hwnd1, BCM_GETIDEALSIZE, 0, (LPARAM)&s); 261 ok (ret == TRUE, "Expected BCM_GETIDEALSIZE to succeed\n"); 262 ok_size(s, textent.cx + 5 + 2 + 1, /* we get an extra pixel due to the iml */ 263 textent.cy + 7 + 2); 264 265 s.cx = 1; 266 s.cy = 1; 267 ret = SendMessageW(hwnd1, BCM_GETIDEALSIZE, 0, (LPARAM)&s); 268 ok (ret == TRUE, "Expected BCM_GETIDEALSIZE to succeed\n"); 269 ok_size(s, textent.cx + 5 + 2 + 1, 270 textent.cy + 7 + 2); 271 272 s.cx = 100; 273 s.cy = 100; 274 ret = SendMessageW(hwnd1, BCM_GETIDEALSIZE, 0, (LPARAM)&s); 275 ok (ret == TRUE, "Expected BCM_GETIDEALSIZE to succeed\n"); 276 ok_size(s, textent.cx + 5 + 2 + 1, 277 textent.cy + 7 + 2); 278 279 SetRect(&imlData.margin, 1,1,1,1); 280 ret = SendMessageW(hwnd1, BCM_SETIMAGELIST, 0, (LPARAM)&imlData); 281 ok (ret == TRUE, "Expected BCM_SETIMAGELIST to fail\n"); 282 283 memset(&s, 0, sizeof(s)); 284 ret = SendMessageW(hwnd1, BCM_GETIDEALSIZE, 0, (LPARAM)&s); 285 ok (ret == TRUE, "Expected BCM_GETIDEALSIZE to succeed\n"); 286 /* expected width = text width + hardcoded value + text margins + image width + image margins */ 287 ok_size(s, textent.cx + 5 + 2 + 1 + 2, 288 textent.cy + 7 + 2); 289 290 SetRect(&imlData.margin, 50,50,50,50); 291 ret = SendMessageW(hwnd1, BCM_SETIMAGELIST, 0, (LPARAM)&imlData); 292 ok (ret == TRUE, "Expected BCM_SETIMAGELIST to fail\n"); 293 294 memset(&s, 0, sizeof(s)); 295 ret = SendMessageW(hwnd1, BCM_GETIDEALSIZE, 0, (LPARAM)&s); 296 ok (ret == TRUE, "Expected BCM_GETIDEALSIZE to succeed\n"); 297 /* image + its margins is so big that the height is dictated by them */ 298 ok_size(s, textent.cx + 5 + 2 + 1 + 100, (LONG)101); 299 300 DestroyWindow(hwnd1); 301 302 303 304 305 306 307 hwnd1 = CreateWindowW(L"Button", L"Start", BS_VCENTER | WS_CHILD, 0, 0, 0, 0, hwnd2, NULL, NULL, NULL); 308 ok (hwnd1 != NULL, "Expected CreateWindowW to succeed\n"); 309 SetWindowTheme(hwnd1, L"", L""); 310 311 font = (HFONT)SendMessageW(hwnd1, WM_GETFONT, 0, 0); 312 hdc = GetDC(hwnd1); 313 SelectObject(hdc, font); 314 GetTextExtentPoint32W(hdc, L"Start", 5, &textent); 315 316 SetRect(&rc, 0,0,0,0); 317 ret = SendMessageW(hwnd1, BCM_SETTEXTMARGIN, 0, (LPARAM)&rc); 318 ok (ret == TRUE, "Expected BCM_SETTEXTMARGIN to succeed\n"); 319 320 memset(&s, 0, sizeof(s)); 321 ret = SendMessageW(hwnd1, BCM_GETIDEALSIZE, 0, (LPARAM)&s); 322 ok (ret == TRUE, "Expected BCM_GETIDEALSIZE to succeed\n"); 323 ok_size(s, textent.cx + 5, textent.cy + 7); 324 325 DestroyWindow(hwnd1); 326 327 328 329 330 /* Test again with some real text to see if the formula is correct */ 331 hwnd1 = CreateWindowW(L"Button", L"Some test text", WS_CHILD, 10, 10, 100, 100, hwnd2, NULL, NULL, NULL); 332 ok (hwnd1 != NULL, "Expected CreateWindowW to succeed\n"); 333 SetWindowTheme(hwnd1, L"", L""); 334 335 font = (HFONT)SendMessageW(hwnd1, WM_GETFONT, 0, 0); 336 hdc = GetDC(hwnd1); 337 SelectObject(hdc, font); 338 GetTextExtentPoint32W(hdc, L"Some test text", 14, &textent); 339 340 memset(&s, 0, sizeof(s)); 341 ret = SendMessageW(hwnd1, BCM_GETIDEALSIZE, 0, (LPARAM)&s); 342 ok (ret == TRUE, "Expected BCM_GETIDEALSIZE to succeed\n"); 343 ok_size(s, textent.cx + 5 + 2, /* the last +2 is the text margin */ 344 textent.cy + 7 + 2); 345 346 /* The hardcoded values are independent of the margin */ 347 lf.lfHeight = 200; 348 lf.lfWidth = 200; 349 lf.lfWeight = FW_BOLD; 350 wcscpy(lf.lfFaceName, L"Arial"); 351 font = CreateFontIndirectW(&lf); 352 ok(font != NULL, "\n"); 353 SendMessageW(hwnd1, WM_SETFONT, (WPARAM)font, FALSE); 354 355 SelectObject(hdc, font); 356 GetTextExtentPoint32W(hdc, L"Some test text", 14, &textent); 357 358 memset(&s, 0, sizeof(s)); 359 ret = SendMessageW(hwnd1, BCM_GETIDEALSIZE, 0, (LPARAM)&s); 360 ok (ret == TRUE, "Expected BCM_GETIDEALSIZE to succeed\n"); 361 ok_size(s, textent.cx + 5 + 2, /* the last +2 is the text margin */ 362 textent.cy + 7 + 2); 363 364 DestroyWindow(hwnd1); 365 366 for (i = BS_PUSHBUTTON; i <= BS_OWNERDRAW; i++) 367 { 368 if (i == BS_USERBUTTON) 369 continue; 370 371 if (i >= BS_CHECKBOX) 372 { 373 hwnd1 = CreateWindowW(L"Button", L" ", i|WS_CHILD, 0, 0, 72, 72, hwnd2, NULL, NULL, NULL); 374 ok (hwnd1 != NULL, "Expected CreateWindowW to succeed\n"); 375 memset(&s, 0, sizeof(s)); 376 ret = SendMessageW(hwnd1, BCM_GETIDEALSIZE, 0, (LPARAM)&s); 377 ok (ret == TRUE, "Expected BCM_GETIDEALSIZE to succeed\n"); 378 ok_size(s, 72, 72); 379 380 SetWindowTheme(hwnd1, L"", L""); 381 memset(&s, 0, sizeof(s)); 382 ret = SendMessageW(hwnd1, BCM_GETIDEALSIZE, 0, (LPARAM)&s); 383 ok (ret == TRUE, "Expected BCM_GETIDEALSIZE to succeed\n"); 384 ok_size(s, 72, 72); 385 DestroyWindow(hwnd1); 386 387 hwnd1 = CreateWindowW(L"Button", L" ", i|WS_CHILD, 0, 0, 12, 12, hwnd2, NULL, NULL, NULL); 388 ok (hwnd1 != NULL, "Expected CreateWindowW to succeed\n"); 389 memset(&s, 0, sizeof(s)); 390 ret = SendMessageW(hwnd1, BCM_GETIDEALSIZE, 0, (LPARAM)&s); 391 ok (ret == TRUE, "Expected BCM_GETIDEALSIZE to succeed\n"); 392 ok_size(s, 12, 12); 393 DestroyWindow(hwnd1); 394 } 395 396 hwnd1 = CreateWindowW(L"Button", L"", i|WS_CHILD, 0, 0, 72, 72, hwnd2, NULL, NULL, NULL); 397 ok (hwnd1 != NULL, "Expected CreateWindowW to succeed\n"); 398 memset(&s, 0, sizeof(s)); 399 ret = SendMessageW(hwnd1, BCM_GETIDEALSIZE, 0, (LPARAM)&s); 400 ok (ret == TRUE, "Expected BCM_GETIDEALSIZE to succeed\n"); 401 ok_size(s, 72, 72); 402 DestroyWindow(hwnd1); 403 404 hwnd1 = CreateWindowW(L"Button", L"", i|WS_CHILD, 0, 0, 150, 72, hwnd2, NULL, NULL, NULL); 405 ok (hwnd1 != NULL, "Expected CreateWindowW to succeed\n"); 406 memset(&s, 0, sizeof(s)); 407 ret = SendMessageW(hwnd1, BCM_GETIDEALSIZE, 0, (LPARAM)&s); 408 ok (ret == TRUE, "Expected BCM_GETIDEALSIZE to succeed\n"); 409 ok_size(s, 150, 72); 410 DestroyWindow(hwnd1); 411 } 412 DestroyWindow(hwnd2); 413 } 414 415 416 HWND hWnd1, hWnd2; 417 418 #define MOVE_CURSOR(x,y) mouse_event(MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE , \ 419 x*(65535/GetSystemMetrics(SM_CXVIRTUALSCREEN)), \ 420 y*(65535/GetSystemMetrics(SM_CYVIRTUALSCREEN)) , 0,0); 421 422 static int get_iwnd(HWND hWnd) 423 { 424 if(hWnd == hWnd1) return 1; 425 else if(hWnd == hWnd2) return 2; 426 else return 0; 427 } 428 429 static LRESULT CALLBACK subclass_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, UINT_PTR id, DWORD_PTR ref_data) 430 { 431 int iwnd = get_iwnd(hwnd); 432 433 if(message > WM_USER || !iwnd ) 434 return DefSubclassProc(hwnd, message, wParam, lParam); 435 436 switch(message) 437 { 438 case WM_IME_SETCONTEXT: 439 case WM_IME_NOTIFY : 440 case WM_GETICON : 441 case WM_GETTEXT: 442 case WM_GETTEXTLENGTH: 443 break; 444 case WM_NOTIFY: 445 { 446 NMHDR* pnmhdr = (NMHDR*)lParam; 447 if (pnmhdr->code == NM_CUSTOMDRAW) 448 { 449 NMCUSTOMDRAW* pnmcd = (NMCUSTOMDRAW*)lParam; 450 RECORD_MESSAGE(iwnd, message, SENT, pnmhdr->code, pnmcd->dwDrawStage); 451 } 452 else 453 { 454 RECORD_MESSAGE(iwnd, message, SENT, pnmhdr->idFrom,pnmhdr->code); 455 } 456 break; 457 } 458 default: 459 RECORD_MESSAGE(iwnd, message, SENT, 0,0); 460 } 461 return DefSubclassProc(hwnd, message, wParam, lParam); 462 } 463 464 static LRESULT CALLBACK TestProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 465 { 466 int iwnd = get_iwnd(hwnd); 467 468 if (iwnd != 0 && message == WM_NOTIFY) 469 { 470 NMHDR* pnmhdr = (NMHDR*)lParam; 471 if (pnmhdr->code == NM_CUSTOMDRAW) 472 { 473 NMCUSTOMDRAW* pnmcd = (NMCUSTOMDRAW*)lParam; 474 RECORD_MESSAGE(iwnd, message, SENT, pnmhdr->code, pnmcd->dwDrawStage); 475 } 476 else 477 { 478 RECORD_MESSAGE(iwnd, message, SENT, pnmhdr->idFrom,pnmhdr->code); 479 } 480 } 481 else if (iwnd != 0 && message < WM_USER && message != WM_GETICON) 482 { 483 RECORD_MESSAGE(iwnd, message, SENT, 0,0); 484 } 485 486 return DefWindowProc(hwnd, message, wParam, lParam); 487 } 488 489 static void FlushMessages() 490 { 491 MSG msg; 492 493 while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) 494 { 495 int iwnd = get_iwnd(msg.hwnd); 496 if(iwnd) 497 { 498 if(msg.message <= WM_USER && iwnd != 0) 499 RECORD_MESSAGE(iwnd, msg.message, POST,0,0); 500 } 501 DispatchMessageW( &msg ); 502 } 503 } 504 505 MSG_ENTRY paint_sequence[]={ 506 {2, WM_PAINT, POST}, 507 {1, WM_ERASEBKGND}, 508 {1, WM_PRINTCLIENT}, 509 {1, WM_CTLCOLORBTN}, 510 {1, WM_NOTIFY, SENT, NM_CUSTOMDRAW, CDDS_PREERASE}, 511 {1, WM_NOTIFY, SENT, NM_CUSTOMDRAW, CDDS_PREPAINT}, 512 {0,0}}; 513 514 MSG_ENTRY paint_nonthemed_sequence[]={ 515 {2, WM_PAINT, POST}, 516 {1, WM_CTLCOLORBTN}, 517 {1, WM_NOTIFY, SENT, NM_CUSTOMDRAW, CDDS_PREERASE}, 518 {1, WM_NOTIFY, SENT, NM_CUSTOMDRAW, CDDS_PREPAINT}, 519 {0,0}}; 520 521 MSG_ENTRY redraw_sequence[]={ 522 {2, WM_PAINT, POST}, 523 {2, WM_ERASEBKGND}, 524 {1, WM_ERASEBKGND}, 525 {1, WM_PRINTCLIENT}, 526 {1, WM_CTLCOLORBTN}, 527 {1, WM_NOTIFY, SENT, NM_CUSTOMDRAW, CDDS_PREERASE}, 528 {1, WM_NOTIFY, SENT, NM_CUSTOMDRAW, CDDS_PREPAINT}, 529 {0,0}}; 530 531 MSG_ENTRY redraw_nonthemed_sequence[]={ 532 {2, WM_PAINT, POST}, 533 {2, WM_ERASEBKGND}, 534 {1, WM_CTLCOLORBTN}, 535 {1, WM_NOTIFY, SENT, NM_CUSTOMDRAW, CDDS_PREERASE}, 536 {1, WM_NOTIFY, SENT, NM_CUSTOMDRAW, CDDS_PREPAINT}, 537 {0,0}}; 538 539 MSG_ENTRY printclnt_nonthemed_sequence[]={ 540 {2, WM_PRINTCLIENT}, 541 {1, WM_CTLCOLORBTN}, 542 {1, WM_NOTIFY, SENT, NM_CUSTOMDRAW, CDDS_PREERASE}, 543 {1, WM_NOTIFY, SENT, NM_CUSTOMDRAW, CDDS_PREPAINT}, 544 {0,0}}; 545 546 MSG_ENTRY printclnt_sequence[]={ 547 {2, WM_PRINTCLIENT}, 548 {1, WM_CTLCOLORBTN}, 549 {1, WM_NOTIFY, SENT, NM_CUSTOMDRAW, CDDS_PREERASE}, 550 {0,0}}; 551 552 MSG_ENTRY pseudomove_sequence[]={ 553 {2, WM_MOUSEMOVE}, 554 {1, WM_NOTIFY, SENT, 0, BCN_HOTITEMCHANGE}, 555 {2, WM_MOUSELEAVE, POST}, 556 {1, WM_NOTIFY, SENT, 0, BCN_HOTITEMCHANGE}, 557 {2, WM_PAINT, POST}, 558 {2, WM_ERASEBKGND}, 559 {1, WM_ERASEBKGND}, 560 {1, WM_PRINTCLIENT}, 561 {1, WM_CTLCOLORBTN}, 562 {1, WM_NOTIFY, SENT, NM_CUSTOMDRAW, CDDS_PREERASE}, 563 {1, WM_NOTIFY, SENT, NM_CUSTOMDRAW, CDDS_PREPAINT}, 564 {0,0}}; 565 566 MSG_ENTRY pseudomove_nonthemed_sequence[]={ 567 {2, WM_MOUSEMOVE}, 568 {1, WM_NOTIFY, SENT, 0, BCN_HOTITEMCHANGE}, 569 {2, WM_MOUSELEAVE, POST}, 570 {1, WM_NOTIFY, SENT, 0, BCN_HOTITEMCHANGE}, 571 {2, WM_PAINT, POST}, 572 {2, WM_ERASEBKGND}, 573 {1, WM_CTLCOLORBTN}, 574 {1, WM_NOTIFY, SENT, NM_CUSTOMDRAW, CDDS_PREERASE}, 575 {1, WM_NOTIFY, SENT, NM_CUSTOMDRAW, CDDS_PREPAINT}, 576 {0,0}}; 577 578 MSG_ENTRY pseudohover_sequence[]={ 579 {2, WM_MOUSEHOVER}, 580 {0,0}}; 581 582 MSG_ENTRY pseudoleave_sequence[]={ 583 {2, WM_MOUSELEAVE}, 584 {0,0}}; 585 586 MSG_ENTRY mouseenter_sequence[]={ 587 {2, WM_NCHITTEST}, 588 {2, WM_SETCURSOR}, 589 {1, WM_SETCURSOR}, 590 {2, WM_MOUSEMOVE, POST}, 591 {1, WM_NOTIFY, SENT, 0, BCN_HOTITEMCHANGE}, 592 {2, WM_PAINT, POST}, 593 {2, WM_ERASEBKGND}, 594 {1, WM_ERASEBKGND}, 595 {1, WM_PRINTCLIENT}, 596 {1, WM_CTLCOLORBTN}, 597 {1, WM_NOTIFY, SENT, NM_CUSTOMDRAW, CDDS_PREERASE}, 598 {1, WM_NOTIFY, SENT, NM_CUSTOMDRAW, CDDS_PREPAINT}, 599 {0,0}}; 600 601 MSG_ENTRY mouseenter_nonthemed_sequence[]={ 602 {2, WM_NCHITTEST}, 603 {2, WM_SETCURSOR}, 604 {1, WM_SETCURSOR}, 605 {2, WM_MOUSEMOVE, POST}, 606 {1, WM_NOTIFY, SENT, 0, BCN_HOTITEMCHANGE}, 607 {2, WM_PAINT, POST}, 608 {2, WM_ERASEBKGND}, 609 {1, WM_CTLCOLORBTN}, 610 {1, WM_NOTIFY, SENT, NM_CUSTOMDRAW, CDDS_PREERASE}, 611 {1, WM_NOTIFY, SENT, NM_CUSTOMDRAW, CDDS_PREPAINT}, 612 {0,0}}; 613 614 MSG_ENTRY mousemove_sequence[]={ 615 {2, WM_NCHITTEST}, 616 {2, WM_SETCURSOR}, 617 {1, WM_SETCURSOR}, 618 {2, WM_MOUSEMOVE, POST}, 619 {0,0}}; 620 621 MSG_ENTRY mouseleave_sequence[]={ 622 {2, WM_MOUSELEAVE, POST}, 623 {1, WM_NOTIFY, SENT, 0, BCN_HOTITEMCHANGE}, 624 {2, WM_PAINT, POST}, 625 {2, WM_ERASEBKGND}, 626 {1, WM_ERASEBKGND}, 627 {1, WM_PRINTCLIENT}, 628 {1, WM_CTLCOLORBTN}, 629 {1, WM_NOTIFY, SENT, NM_CUSTOMDRAW, CDDS_PREERASE}, 630 {1, WM_NOTIFY, SENT, NM_CUSTOMDRAW, CDDS_PREPAINT}, 631 {0,0}}; 632 633 MSG_ENTRY mouseleave_nonthemed_sequence[]={ 634 {2, WM_MOUSELEAVE, POST}, 635 {1, WM_NOTIFY, SENT, 0, BCN_HOTITEMCHANGE}, 636 {2, WM_PAINT, POST}, 637 {2, WM_ERASEBKGND}, 638 {1, WM_CTLCOLORBTN}, 639 {1, WM_NOTIFY, SENT, NM_CUSTOMDRAW, CDDS_PREERASE}, 640 {1, WM_NOTIFY, SENT, NM_CUSTOMDRAW, CDDS_PREPAINT}, 641 {0,0}}; 642 643 void Test_MessagesNonThemed() 644 { 645 DWORD state; 646 647 MOVE_CURSOR(0,0); 648 EMPTY_CACHE(); 649 650 RegisterSimpleClass(TestProc, L"testClass"); 651 hWnd1 = CreateWindowW(L"testClass", L"Test parent", WS_POPUP | WS_VISIBLE, 100, 100, 200, 200, 0, NULL, NULL, NULL); 652 ok (hWnd1 != NULL, "Expected CreateWindowW to succeed\n"); 653 SetWindowTheme(hWnd1, L"", L""); 654 UpdateWindow(hWnd1); 655 656 hWnd2 = CreateWindowW(L"Button", L"test button", /*BS_RADIOBUTTON | */WS_CHILD | WS_VISIBLE, 0, 0, 100, 100, hWnd1, NULL, NULL, NULL); 657 ok (hWnd2 != NULL, "Expected CreateWindowW to succeed\n"); 658 SetWindowTheme(hWnd2, L"", L""); 659 SetWindowSubclass(hWnd2, subclass_proc, 0, 0); 660 UpdateWindow(hWnd2); 661 662 FlushMessages(); 663 EMPTY_CACHE(); 664 665 RedrawWindow(hWnd2, NULL, NULL, RDW_ERASE); 666 FlushMessages(); 667 COMPARE_CACHE(empty_chain); 668 FlushMessages(); 669 COMPARE_CACHE(empty_chain); 670 671 RedrawWindow(hWnd2, NULL, NULL, RDW_FRAME); 672 FlushMessages(); 673 COMPARE_CACHE(empty_chain); 674 675 RedrawWindow(hWnd2, NULL, NULL, RDW_INTERNALPAINT); 676 FlushMessages(); 677 COMPARE_CACHE(paint_nonthemed_sequence); 678 679 RedrawWindow(hWnd2, NULL, NULL, RDW_INVALIDATE); 680 FlushMessages(); 681 COMPARE_CACHE(paint_nonthemed_sequence); 682 683 RedrawWindow(hWnd2, NULL, NULL, RDW_ERASE | RDW_INVALIDATE); 684 FlushMessages(); 685 COMPARE_CACHE(redraw_nonthemed_sequence); 686 687 SendMessageW(hWnd2, WM_PRINTCLIENT, 0, PRF_ERASEBKGND); 688 FlushMessages(); 689 COMPARE_CACHE(printclnt_nonthemed_sequence); 690 691 SendMessageW(hWnd2, WM_MOUSEMOVE, 0, 0); 692 FlushMessages(); 693 COMPARE_CACHE(pseudomove_nonthemed_sequence); 694 695 SendMessageW(hWnd2, WM_MOUSEHOVER, 0, 0); 696 FlushMessages(); 697 COMPARE_CACHE(pseudohover_sequence); 698 699 SendMessageW(hWnd2, WM_MOUSELEAVE, 0, 0); 700 FlushMessages(); 701 COMPARE_CACHE(pseudoleave_sequence); 702 703 state = SendMessageW(hWnd2, BM_GETSTATE,0,0); 704 ok(state == 0, "Expected state 0, got %lu", state); 705 EMPTY_CACHE(); 706 707 MOVE_CURSOR(150,150); 708 FlushMessages(); 709 COMPARE_CACHE(mouseenter_nonthemed_sequence); 710 711 state = SendMessageW(hWnd2, BM_GETSTATE,0,0); 712 ok(state == BST_HOT, "Expected state BST_HOT, got %lu", state); 713 EMPTY_CACHE(); 714 715 MOVE_CURSOR(151,151); 716 FlushMessages(); 717 COMPARE_CACHE(mousemove_sequence); 718 719 state = SendMessageW(hWnd2, BM_GETSTATE,0,0); 720 ok(state == BST_HOT, "Expected state BST_HOT, got %lu", state); 721 EMPTY_CACHE(); 722 723 MOVE_CURSOR(0,0); 724 FlushMessages(); 725 COMPARE_CACHE(empty_chain); 726 FlushMessages(); 727 COMPARE_CACHE(mouseleave_nonthemed_sequence); 728 729 state = SendMessageW(hWnd2, BM_GETSTATE,0,0); 730 ok(state == 0, "Expected state 0, got %lu", state); 731 EMPTY_CACHE(); 732 733 DestroyWindow(hWnd1); 734 DestroyWindow(hWnd2); 735 } 736 737 void Test_MessagesThemed() 738 { 739 DWORD state; 740 741 MOVE_CURSOR(0,0); 742 EMPTY_CACHE(); 743 744 RegisterSimpleClass(TestProc, L"testClass"); 745 hWnd1 = CreateWindowW(L"testClass", L"Test parent", WS_POPUP | WS_VISIBLE, 100, 100, 200, 200, 0, NULL, NULL, NULL); 746 ok (hWnd1 != NULL, "Expected CreateWindowW to succeed\n"); 747 UpdateWindow(hWnd1); 748 749 hWnd2 = CreateWindowW(L"Button", L"test button", /*BS_RADIOBUTTON | */WS_CHILD | WS_VISIBLE, 0, 0, 100, 100, hWnd1, NULL, NULL, NULL); 750 ok (hWnd2 != NULL, "Expected CreateWindowW to succeed\n"); 751 SetWindowSubclass(hWnd2, subclass_proc, 0, 0); 752 UpdateWindow(hWnd2); 753 754 FlushMessages(); 755 EMPTY_CACHE(); 756 757 RedrawWindow(hWnd2, NULL, NULL, RDW_ERASE); 758 FlushMessages(); 759 COMPARE_CACHE(empty_chain); 760 FlushMessages(); 761 COMPARE_CACHE(empty_chain); 762 763 RedrawWindow(hWnd2, NULL, NULL, RDW_FRAME); 764 FlushMessages(); 765 COMPARE_CACHE(empty_chain); 766 767 RedrawWindow(hWnd2, NULL, NULL, RDW_INTERNALPAINT); 768 FlushMessages(); 769 COMPARE_CACHE(paint_sequence); 770 771 RedrawWindow(hWnd2, NULL, NULL, RDW_INVALIDATE); 772 FlushMessages(); 773 COMPARE_CACHE(paint_sequence); 774 775 RedrawWindow(hWnd2, NULL, NULL, RDW_ERASE | RDW_INVALIDATE); 776 FlushMessages(); 777 COMPARE_CACHE(redraw_sequence); 778 779 SendMessageW(hWnd2, WM_PRINTCLIENT, 0, PRF_ERASEBKGND); 780 FlushMessages(); 781 COMPARE_CACHE(printclnt_sequence); 782 783 SendMessageW(hWnd2, WM_PRINTCLIENT, 0, PRF_CLIENT); 784 FlushMessages(); 785 COMPARE_CACHE(printclnt_sequence); 786 787 SendMessageW(hWnd2, WM_MOUSEMOVE, 0, 0); 788 FlushMessages(); 789 COMPARE_CACHE(pseudomove_sequence); 790 791 SendMessageW(hWnd2, WM_MOUSEHOVER, 0, 0); 792 FlushMessages(); 793 COMPARE_CACHE(pseudohover_sequence); 794 795 SendMessageW(hWnd2, WM_MOUSELEAVE, 0, 0); 796 FlushMessages(); 797 COMPARE_CACHE(pseudoleave_sequence); 798 799 state = SendMessageW(hWnd2, BM_GETSTATE,0,0); 800 ok(state == 0, "Expected state 0, got %lu", state); 801 EMPTY_CACHE(); 802 803 MOVE_CURSOR(150,150); 804 FlushMessages(); 805 COMPARE_CACHE(mouseenter_sequence); 806 807 state = SendMessageW(hWnd2, BM_GETSTATE,0,0); 808 ok(state == BST_HOT, "Expected state BST_HOT, got %lu", state); 809 EMPTY_CACHE(); 810 811 MOVE_CURSOR(151,151); 812 FlushMessages(); 813 COMPARE_CACHE(mousemove_sequence); 814 815 state = SendMessageW(hWnd2, BM_GETSTATE,0,0); 816 ok(state == BST_HOT, "Expected state BST_HOT, got %lu", state); 817 EMPTY_CACHE(); 818 819 MOVE_CURSOR(0,0); 820 FlushMessages(); 821 COMPARE_CACHE(empty_chain); 822 FlushMessages(); 823 COMPARE_CACHE(mouseleave_sequence); 824 825 state = SendMessageW(hWnd2, BM_GETSTATE,0,0); 826 ok(state == 0, "Expected state 0, got %lu", state); 827 EMPTY_CACHE(); 828 829 DestroyWindow(hWnd1); 830 DestroyWindow(hWnd2); 831 } 832 833 START_TEST(button) 834 { 835 LoadLibraryW(L"comctl32.dll"); /* same as statically linking to comctl32 and doing InitCommonControls */ 836 Test_TextMargin(); 837 Test_Imagelist(); 838 Test_GetIdealSizeNoThemes(); 839 840 Test_MessagesNonThemed(); 841 if (IsThemeActive()) 842 Test_MessagesThemed(); 843 else 844 skip("No active theme, skipping Test_MessagesThemed\n"); 845 846 } 847 848