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 MSG_ENTRY themechanged_sequence[]={ 644 {2, WM_THEMECHANGED, SENT}, 645 {1, WM_NOTIFY, SENT, 0, NM_THEMECHANGED }, 646 {2, WM_PAINT, POST}, 647 {2, WM_ERASEBKGND}, 648 {1, WM_CTLCOLORBTN}, 649 {1, WM_NOTIFY, SENT, NM_CUSTOMDRAW, CDDS_PREERASE}, 650 {1, WM_NOTIFY, SENT, NM_CUSTOMDRAW, CDDS_PREPAINT}, 651 {0,0}}; 652 653 MSG_ENTRY enable_nonthemed_sequence[]={ 654 {2, WM_ENABLE, SENT}, 655 {1, WM_CTLCOLORBTN}, 656 {1, WM_CTLCOLORBTN}, 657 {1, WM_NOTIFY, SENT, NM_CUSTOMDRAW, CDDS_PREERASE}, 658 {1, WM_NOTIFY, SENT, NM_CUSTOMDRAW, CDDS_PREPAINT}, 659 {0,0}}; 660 661 MSG_ENTRY btndown_nonthemed_sequence[]={ 662 {2, WM_LBUTTONDOWN, SENT}, 663 {1, WM_KILLFOCUS, SENT}, 664 {1, WM_IME_SETCONTEXT, SENT}, 665 {2, WM_SETFOCUS, SENT}, 666 {2, BM_SETSTATE, SENT}, 667 {2, WM_PAINT, POST}, 668 {1, WM_CTLCOLORBTN}, 669 {1, WM_NOTIFY, SENT, NM_CUSTOMDRAW, CDDS_PREERASE}, 670 {1, WM_NOTIFY, SENT, NM_CUSTOMDRAW, CDDS_PREPAINT}, 671 {0,0}}; 672 673 MSG_ENTRY btndown_repeat_nonthemed_sequence[]={ 674 {2, WM_LBUTTONDOWN, SENT}, 675 {2, BM_SETSTATE, SENT}, 676 {0,0}}; 677 678 MSG_ENTRY btnclick_nonthemed_sequence[]={ 679 {2, BM_CLICK, SENT}, 680 {2, WM_LBUTTONDOWN, SENT}, 681 {2, BM_SETSTATE, SENT}, 682 {2, WM_LBUTTONUP, SENT}, 683 {2, BM_SETSTATE , SENT}, 684 {2, WM_CAPTURECHANGED, SENT}, 685 {1, WM_COMMAND, SENT}, 686 {2, WM_PAINT, POST}, 687 {1, WM_CTLCOLORBTN}, 688 {1, WM_NOTIFY, SENT, NM_CUSTOMDRAW, CDDS_PREERASE}, 689 {1, WM_NOTIFY, SENT, NM_CUSTOMDRAW, CDDS_PREPAINT}, 690 {0,0}}; 691 692 MSG_ENTRY btnup_stray_sequence[]={ 693 {2, WM_LBUTTONUP, SENT}, 694 {0,0}}; 695 696 void Test_MessagesNonThemed() 697 { 698 DWORD state; 699 700 MOVE_CURSOR(0,0); 701 EMPTY_CACHE(); 702 703 RegisterSimpleClass(TestProc, L"testClass"); 704 hWnd1 = CreateWindowW(L"testClass", L"Test parent", WS_POPUP | WS_VISIBLE, 100, 100, 200, 200, 0, NULL, NULL, NULL); 705 ok (hWnd1 != NULL, "Expected CreateWindowW to succeed\n"); 706 SetWindowTheme(hWnd1, L"", L""); 707 UpdateWindow(hWnd1); 708 709 hWnd2 = CreateWindowW(L"Button", L"test button", /*BS_RADIOBUTTON | */WS_CHILD | WS_VISIBLE, 0, 0, 100, 100, hWnd1, NULL, NULL, NULL); 710 ok (hWnd2 != NULL, "Expected CreateWindowW to succeed\n"); 711 SetWindowTheme(hWnd2, L"", L""); 712 SetWindowSubclass(hWnd2, subclass_proc, 0, 0); 713 UpdateWindow(hWnd2); 714 715 FlushMessages(); 716 EMPTY_CACHE(); 717 718 RedrawWindow(hWnd2, NULL, NULL, RDW_ERASE); 719 FlushMessages(); 720 COMPARE_CACHE(empty_chain); 721 FlushMessages(); 722 COMPARE_CACHE(empty_chain); 723 724 RedrawWindow(hWnd2, NULL, NULL, RDW_FRAME); 725 FlushMessages(); 726 COMPARE_CACHE(empty_chain); 727 728 RedrawWindow(hWnd2, NULL, NULL, RDW_INTERNALPAINT); 729 FlushMessages(); 730 COMPARE_CACHE(paint_nonthemed_sequence); 731 732 RedrawWindow(hWnd2, NULL, NULL, RDW_INVALIDATE); 733 FlushMessages(); 734 COMPARE_CACHE(paint_nonthemed_sequence); 735 736 RedrawWindow(hWnd2, NULL, NULL, RDW_ERASE | RDW_INVALIDATE); 737 FlushMessages(); 738 COMPARE_CACHE(redraw_nonthemed_sequence); 739 740 SendMessageW(hWnd2, WM_PRINTCLIENT, 0, PRF_ERASEBKGND); 741 FlushMessages(); 742 COMPARE_CACHE(printclnt_nonthemed_sequence); 743 744 SendMessageW(hWnd2, WM_MOUSEMOVE, 0, 0); 745 FlushMessages(); 746 COMPARE_CACHE(pseudomove_nonthemed_sequence); 747 748 SendMessageW(hWnd2, WM_MOUSEHOVER, 0, 0); 749 FlushMessages(); 750 COMPARE_CACHE(pseudohover_sequence); 751 752 SendMessageW(hWnd2, WM_MOUSELEAVE, 0, 0); 753 FlushMessages(); 754 COMPARE_CACHE(pseudoleave_sequence); 755 756 state = SendMessageW(hWnd2, BM_GETSTATE,0,0); 757 ok_hex(state, 0); 758 EMPTY_CACHE(); 759 760 MOVE_CURSOR(150,150); 761 FlushMessages(); 762 COMPARE_CACHE(mouseenter_nonthemed_sequence); 763 764 state = SendMessageW(hWnd2, BM_GETSTATE,0,0); 765 ok_hex(state, BST_HOT); 766 EMPTY_CACHE(); 767 768 MOVE_CURSOR(151,151); 769 FlushMessages(); 770 COMPARE_CACHE(mousemove_sequence); 771 772 state = SendMessageW(hWnd2, BM_GETSTATE,0,0); 773 ok_hex(state, BST_HOT); 774 EMPTY_CACHE(); 775 776 MOVE_CURSOR(0,0); 777 FlushMessages(); 778 COMPARE_CACHE(empty_chain); 779 FlushMessages(); 780 COMPARE_CACHE(mouseleave_nonthemed_sequence); 781 782 state = SendMessageW(hWnd2, BM_GETSTATE,0,0); 783 ok(state == 0, "Expected state 0, got %lu\n", state); 784 EMPTY_CACHE(); 785 786 SendMessageW(hWnd2, WM_THEMECHANGED, 1, 0); 787 FlushMessages(); 788 COMPARE_CACHE(themechanged_sequence); 789 790 SendMessageW(hWnd2, WM_ENABLE, TRUE, 0); 791 FlushMessages(); 792 COMPARE_CACHE(enable_nonthemed_sequence); 793 794 SendMessageW(hWnd2, WM_LBUTTONDOWN, 0, 0); 795 FlushMessages(); 796 COMPARE_CACHE(btndown_nonthemed_sequence); 797 798 state = SendMessageW(hWnd2, BM_GETSTATE,0,0); 799 ok_hex(state, BST_PUSHED | BST_FOCUS | 0x20 | 0x40); 800 EMPTY_CACHE(); 801 802 SendMessageW(hWnd2, WM_LBUTTONDOWN, 0, 0); 803 FlushMessages(); 804 COMPARE_CACHE(btndown_repeat_nonthemed_sequence); 805 806 state = SendMessageW(hWnd2, BM_GETSTATE,0,0); 807 ok_hex(state, BST_PUSHED | BST_FOCUS | 0x20 | 0x40); 808 EMPTY_CACHE(); 809 810 SendMessageW(hWnd2, BM_CLICK, 0, 0); 811 FlushMessages(); 812 COMPARE_CACHE(btnclick_nonthemed_sequence); 813 814 state = SendMessageW(hWnd2, BM_GETSTATE,0,0); 815 ok_hex(state, BST_FOCUS); 816 EMPTY_CACHE(); 817 818 SendMessageW(hWnd2, WM_LBUTTONUP, 0, 0); 819 FlushMessages(); 820 COMPARE_CACHE(btnup_stray_sequence); 821 822 state = SendMessageW(hWnd2, BM_GETSTATE,0,0); 823 ok_hex(state, BST_FOCUS); 824 EMPTY_CACHE(); 825 826 DestroyWindow(hWnd1); 827 DestroyWindow(hWnd2); 828 } 829 830 void Test_MessagesThemed() 831 { 832 DWORD state; 833 834 MOVE_CURSOR(0,0); 835 EMPTY_CACHE(); 836 837 RegisterSimpleClass(TestProc, L"testClass"); 838 hWnd1 = CreateWindowW(L"testClass", L"Test parent", WS_POPUP | WS_VISIBLE, 100, 100, 200, 200, 0, NULL, NULL, NULL); 839 ok (hWnd1 != NULL, "Expected CreateWindowW to succeed\n"); 840 UpdateWindow(hWnd1); 841 842 hWnd2 = CreateWindowW(L"Button", L"test button", /*BS_RADIOBUTTON | */WS_CHILD | WS_VISIBLE, 0, 0, 100, 100, hWnd1, NULL, NULL, NULL); 843 ok (hWnd2 != NULL, "Expected CreateWindowW to succeed\n"); 844 SetWindowSubclass(hWnd2, subclass_proc, 0, 0); 845 UpdateWindow(hWnd2); 846 847 FlushMessages(); 848 EMPTY_CACHE(); 849 850 RedrawWindow(hWnd2, NULL, NULL, RDW_ERASE); 851 FlushMessages(); 852 COMPARE_CACHE(empty_chain); 853 FlushMessages(); 854 COMPARE_CACHE(empty_chain); 855 856 RedrawWindow(hWnd2, NULL, NULL, RDW_FRAME); 857 FlushMessages(); 858 COMPARE_CACHE(empty_chain); 859 860 RedrawWindow(hWnd2, NULL, NULL, RDW_INTERNALPAINT); 861 FlushMessages(); 862 COMPARE_CACHE(paint_sequence); 863 864 RedrawWindow(hWnd2, NULL, NULL, RDW_INVALIDATE); 865 FlushMessages(); 866 COMPARE_CACHE(paint_sequence); 867 868 RedrawWindow(hWnd2, NULL, NULL, RDW_ERASE | RDW_INVALIDATE); 869 FlushMessages(); 870 COMPARE_CACHE(redraw_sequence); 871 872 SendMessageW(hWnd2, WM_PRINTCLIENT, 0, PRF_ERASEBKGND); 873 FlushMessages(); 874 COMPARE_CACHE(printclnt_sequence); 875 876 SendMessageW(hWnd2, WM_PRINTCLIENT, 0, PRF_CLIENT); 877 FlushMessages(); 878 COMPARE_CACHE(printclnt_sequence); 879 880 SendMessageW(hWnd2, WM_MOUSEMOVE, 0, 0); 881 FlushMessages(); 882 COMPARE_CACHE(pseudomove_sequence); 883 884 SendMessageW(hWnd2, WM_MOUSEHOVER, 0, 0); 885 FlushMessages(); 886 COMPARE_CACHE(pseudohover_sequence); 887 888 SendMessageW(hWnd2, WM_MOUSELEAVE, 0, 0); 889 FlushMessages(); 890 COMPARE_CACHE(pseudoleave_sequence); 891 892 state = SendMessageW(hWnd2, BM_GETSTATE,0,0); 893 ok(state == 0, "Expected state 0, got %lu", state); 894 EMPTY_CACHE(); 895 896 MOVE_CURSOR(150,150); 897 FlushMessages(); 898 COMPARE_CACHE(mouseenter_sequence); 899 900 state = SendMessageW(hWnd2, BM_GETSTATE,0,0); 901 ok(state == BST_HOT, "Expected state BST_HOT, got %lu", state); 902 EMPTY_CACHE(); 903 904 MOVE_CURSOR(151,151); 905 FlushMessages(); 906 COMPARE_CACHE(mousemove_sequence); 907 908 state = SendMessageW(hWnd2, BM_GETSTATE,0,0); 909 ok(state == BST_HOT, "Expected state BST_HOT, got %lu", state); 910 EMPTY_CACHE(); 911 912 MOVE_CURSOR(0,0); 913 FlushMessages(); 914 COMPARE_CACHE(empty_chain); 915 FlushMessages(); 916 COMPARE_CACHE(mouseleave_sequence); 917 918 state = SendMessageW(hWnd2, BM_GETSTATE,0,0); 919 ok(state == 0, "Expected state 0, got %lu", state); 920 EMPTY_CACHE(); 921 922 DestroyWindow(hWnd1); 923 DestroyWindow(hWnd2); 924 } 925 926 START_TEST(button) 927 { 928 LoadLibraryW(L"comctl32.dll"); /* same as statically linking to comctl32 and doing InitCommonControls */ 929 Test_TextMargin(); 930 Test_Imagelist(); 931 Test_GetIdealSizeNoThemes(); 932 933 Test_MessagesNonThemed(); 934 if (IsThemeActive()) 935 Test_MessagesThemed(); 936 else 937 skip("No active theme, skipping Test_MessagesThemed\n"); 938 939 } 940 941