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
Test_TextMargin()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
Test_Imagelist()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
Test_GetIdealSizeNoThemes()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
get_iwnd(HWND hWnd)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
subclass_proc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam,UINT_PTR id,DWORD_PTR ref_data)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
TestProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)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
FlushMessages()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
Test_MessagesNonThemed()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
Test_MessagesThemed()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
START_TEST(button)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