[RAPPS] Stopped GCC whining (fixed GCC build)
[reactos.git] / rostests / apitests / comctl32 / button.c
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