1 /* Unit tests for rebar.
3 * Copyright 2007 Mikolaj Zalewski
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 /* make sure the structures work with a comctl32 v5.x */
21 #define _WIN32_WINNT 0x500
22 #define _WIN32_IE 0x500
31 #include "wine/test.h"
33 RECT height_change_notify_rect;
38 #define check_rect(name, val, exp) ok(val.top == exp.top && val.bottom == exp.bottom && \
39 val.left == exp.left && val.right == exp.right, "invalid rect (" name ") (%d,%d) (%d,%d) - expected (%d,%d) (%d,%d)\n", \
40 val.left, val.top, val.right, val.bottom, exp.left, exp.top, exp.right, exp.bottom);
42 #define check_rect_no_top(name, val, exp) { \
43 ok((val.bottom - val.top == exp.bottom - exp.top) && \
44 val.left == exp.left && val.right == exp.right, "invalid rect (" name ") (%d,%d) (%d,%d) - expected (%d,%d) (%d,%d), ignoring top\n", \
45 val.left, val.top, val.right, val.bottom, exp.left, exp.top, exp.right, exp.bottom); \
48 #define compare(val, exp, format) ok((val) == (exp), #val " value " format " expected " format "\n", (val), (exp));
50 #define expect_eq(expr, value, type, format) { type ret = expr; ok((value) == ret, #expr " expected " format " got " format "\n", (value), (ret)); }
52 static INT CALLBACK is_font_installed_proc(const LOGFONT *elf, const TEXTMETRIC *ntm, DWORD type, LPARAM lParam)
57 static BOOL is_font_installed(const char *name)
62 if(!EnumFontFamiliesA(hdc, name, is_font_installed_proc, 0))
69 static void rebuild_rebar(HWND *hRebar)
72 DestroyWindow(*hRebar);
74 *hRebar = CreateWindow(REBARCLASSNAME, NULL, WS_CHILD | WS_VISIBLE, 0, 0, 0, 0,
75 hMainWnd, (HMENU)17, GetModuleHandle(NULL), NULL);
76 SendMessageA(*hRebar, WM_SETFONT, (WPARAM)GetStockObject(SYSTEM_FONT), 0);
79 static HWND build_toolbar(int nr, HWND hParent)
82 HWND hToolbar = CreateWindowEx(0, TOOLBARCLASSNAME, NULL, WS_CHILD | WS_VISIBLE | CCS_NORESIZE, 0, 0, 0, 0,
83 hParent, (HMENU)5, GetModuleHandle(NULL), NULL);
87 ok(hToolbar != NULL, "Toolbar creation problem\n");
88 ok(SendMessage(hToolbar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0) == 0, "TB_BUTTONSTRUCTSIZE failed\n");
89 ok(SendMessage(hToolbar, TB_AUTOSIZE, 0, 0) == 0, "TB_AUTOSIZE failed\n");
90 ok(SendMessage(hToolbar, WM_SETFONT, (WPARAM)GetStockObject(SYSTEM_FONT), 0)==1, "WM_SETFONT\n");
92 for (i=0; i<5+nr; i++)
95 btns[i].idCommand = i;
96 btns[i].fsStyle = BTNS_BUTTON;
97 btns[i].fsState = TBSTATE_ENABLED;
103 case 0: iBitmapId = IDB_HIST_SMALL_COLOR; break;
104 case 1: iBitmapId = IDB_VIEW_SMALL_COLOR; break;
105 case 2: iBitmapId = IDB_STD_SMALL_COLOR; break;
107 ok(SendMessage(hToolbar, TB_LOADIMAGES, iBitmapId, (LPARAM)HINST_COMMCTRL) == 0, "TB_LOADIMAGES failed\n");
108 ok(SendMessage(hToolbar, TB_ADDBUTTONS, 5+nr, (LPARAM)btns), "TB_ADDBUTTONS failed\n");
112 static LRESULT CALLBACK MyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
118 NMHDR *lpnm = (NMHDR *)lParam;
119 if (lpnm->code == RBN_HEIGHTCHANGE)
120 GetClientRect(hRebar, &height_change_notify_rect);
124 return DefWindowProcA(hWnd, msg, wParam, lParam);
127 #if 0 /* use this to generate more tests*/
129 static void dump_sizes(HWND hRebar)
136 GetClientRect(hRebar, &r);
137 count = SendMessageA(hRebar, RB_GETROWCOUNT, 0, 0);
138 printf(" { {%d, %d, %d, %d}, %d, %d, {", r.left, r.top, r.right, r.bottom,
139 SendMessageA(hRebar, RB_GETBARHEIGHT, 0, 0), count);
142 for (i = 0; i < count; i++) /* rows */
143 printf("%d, ", SendMessageA(hRebar, RB_GETROWHEIGHT, i, 0));
146 count = SendMessageA(hRebar, RB_GETBANDCOUNT, 0, 0);
147 printf("%d, {", count);
149 printf("{{0, 0, 0, 0}, 0, 0},");
150 for (i=0; i<count; i++)
153 rbi.cbSize = REBARBANDINFOA_V6_SIZE;
154 rbi.fMask = RBBIM_SIZE | RBBIM_CHILDSIZE | RBBIM_STYLE;
155 ok(SendMessageA(hRebar, RB_GETBANDINFOA, i, (LPARAM)&rbi), "RB_GETBANDINFO failed\n");
156 ok(SendMessageA(hRebar, RB_GETRECT, i, (LPARAM)&r), "RB_GETRECT failed\n");
157 printf("%s{ {%3d, %3d, %3d, %3d}, 0x%02x, %d}, ", (i%2==0 ? "\n " : ""), r.left, r.top, r.right, r.bottom,
160 printf("\n }, },\n");
163 #define check_sizes() dump_sizes(hRebar);
164 #define check_sizes_todo(todomask) dump_sizes(hRebar);
178 int cyRowHeights[50];
180 rbband_result_t bands[50];
183 rbsize_result_t rbsize_results[] = {
184 { {0, 0, 672, 0}, 0, 0, {0, }, 0, {{{0, 0, 0, 0}, 0, 0},
186 { {0, 0, 672, 4}, 4, 1, {4, }, 1, {
187 { { 0, 0, 672, 4}, 0x00, 200},
189 { {0, 0, 672, 4}, 4, 1, {4, }, 2, {
190 { { 0, 0, 200, 4}, 0x00, 200}, { {200, 0, 672, 4}, 0x04, 200},
192 { {0, 0, 672, 30}, 30, 1, {30, }, 3, {
193 { { 0, 0, 200, 30}, 0x00, 200}, { {200, 0, 400, 30}, 0x04, 200},
194 { {400, 0, 672, 30}, 0x00, 200},
196 { {0, 0, 672, 34}, 34, 1, {34, }, 4, {
197 { { 0, 0, 200, 34}, 0x00, 200}, { {200, 0, 400, 34}, 0x04, 200},
198 { {400, 0, 604, 34}, 0x00, 200}, { {604, 0, 672, 34}, 0x04, 68},
200 { {0, 0, 672, 34}, 34, 1, {34, }, 4, {
201 { { 0, 0, 200, 34}, 0x00, 200}, { {200, 0, 400, 34}, 0x04, 200},
202 { {400, 0, 604, 34}, 0x00, 200}, { {604, 0, 672, 34}, 0x04, 68},
204 { {0, 0, 672, 34}, 34, 1, {34, }, 4, {
205 { { 0, 0, 200, 34}, 0x00, 200}, { {202, 0, 402, 34}, 0x04, 200},
206 { {404, 0, 604, 34}, 0x00, 200}, { {606, 0, 672, 34}, 0x04, 66},
208 { {0, 0, 672, 70}, 70, 2, {34, 34, }, 5, {
209 { { 0, 0, 142, 34}, 0x00, 200}, { {144, 0, 557, 34}, 0x00, 200},
210 { {559, 0, 672, 34}, 0x04, 200}, { { 0, 36, 200, 70}, 0x00, 200},
211 { {202, 36, 672, 70}, 0x04, 66},
213 { {0, 0, 672, 34}, 34, 1, {34, }, 5, {
214 { { 0, 0, 167, 34}, 0x00, 200}, { {169, 0, 582, 34}, 0x00, 200},
215 { {559, 0, 759, 34}, 0x08, 200}, { {584, 0, 627, 34}, 0x00, 200},
216 { {629, 0, 672, 34}, 0x04, 66},
218 { {0, 0, 672, 34}, 34, 1, {34, }, 4, {
219 { { 0, 0, 167, 34}, 0x00, 200}, { {169, 0, 582, 34}, 0x00, 200},
220 { {584, 0, 627, 34}, 0x00, 200}, { {629, 0, 672, 34}, 0x04, 66},
222 { {0, 0, 672, 34}, 34, 1, {34, }, 3, {
223 { { 0, 0, 413, 34}, 0x00, 200}, { {415, 0, 615, 34}, 0x00, 200},
224 { {617, 0, 672, 34}, 0x04, 66},
226 { {0, 0, 672, 34}, 34, 1, {34, }, 2, {
227 { { 0, 0, 604, 34}, 0x00, 200}, { {606, 0, 672, 34}, 0x04, 66},
229 { {0, 0, 672, 40}, 40, 2, {20, 20, }, 5, {
230 { { 0, 0, 114, 20}, 0x00, 40}, { {114, 0, 184, 20}, 0x00, 70},
231 { {184, 0, 424, 20}, 0x00, 240}, { {424, 0, 672, 20}, 0x00, 60},
232 { { 0, 20, 672, 40}, 0x00, 200},
234 { {0, 0, 672, 40}, 40, 2, {20, 20, }, 5, {
235 { { 0, 0, 114, 20}, 0x00, 40}, { {114, 0, 227, 20}, 0x00, 113},
236 { {227, 0, 424, 20}, 0x00, 197}, { {424, 0, 672, 20}, 0x00, 60},
237 { { 0, 20, 672, 40}, 0x00, 200},
239 { {0, 0, 672, 40}, 40, 2, {20, 20, }, 5, {
240 { { 0, 0, 114, 20}, 0x00, 40}, { {114, 0, 328, 20}, 0x00, 214},
241 { {328, 0, 511, 20}, 0x00, 183}, { {511, 0, 672, 20}, 0x00, 161},
242 { { 0, 20, 672, 40}, 0x00, 200},
244 { {0, 0, 672, 40}, 40, 2, {20, 20, }, 5, {
245 { { 0, 0, 114, 20}, 0x00, 40}, { {114, 0, 167, 20}, 0x00, 53},
246 { {167, 0, 511, 20}, 0x00, 344}, { {511, 0, 672, 20}, 0x00, 161},
247 { { 0, 20, 672, 40}, 0x00, 200},
249 { {0, 0, 672, 40}, 40, 2, {20, 20, }, 5, {
250 { { 0, 0, 114, 20}, 0x00, 40}, { {114, 0, 328, 20}, 0x00, 214},
251 { {328, 0, 511, 20}, 0x00, 183}, { {511, 0, 672, 20}, 0x00, 161},
252 { { 0, 20, 672, 40}, 0x00, 200},
254 { {0, 0, 672, 40}, 40, 2, {20, 20, }, 5, {
255 { { 0, 0, 114, 20}, 0x00, 40}, { {114, 0, 328, 20}, 0x00, 214},
256 { {328, 0, 511, 20}, 0x00, 183}, { {511, 0, 672, 20}, 0x00, 161},
257 { { 0, 20, 672, 40}, 0x00, 200},
259 { {0, 0, 672, 56}, 56, 2, {28, 28, }, 5, {
260 { { 0, 0, 114, 28}, 0x00, 40}, { {114, 0, 328, 28}, 0x00, 214},
261 { {328, 0, 511, 28}, 0x00, 183}, { {511, 0, 672, 28}, 0x00, 161},
262 { { 0, 28, 672, 56}, 0x00, 200},
264 { {0, 0, 672, 40}, 40, 2, {20, 20, }, 5, {
265 { { 0, 0, 114, 20}, 0x00, 40}, { {114, 0, 328, 20}, 0x00, 214},
266 { {328, 0, 511, 20}, 0x00, 183}, { {511, 0, 672, 20}, 0x00, 161},
267 { { 0, 20, 672, 40}, 0x00, 200},
269 { {0, 0, 672, 56}, 56, 2, {28, 28, }, 5, {
270 { { 0, 0, 114, 28}, 0x00, 40}, { {114, 0, 328, 28}, 0x00, 214},
271 { {328, 0, 511, 28}, 0x00, 183}, { {511, 0, 672, 28}, 0x00, 161},
272 { { 0, 28, 672, 56}, 0x00, 200},
274 { {0, 0, 672, 0}, 0, 0, {0, }, 0, {{{0, 0, 0, 0}, 0, 0},
276 { {0, 0, 672, 65}, 65, 1, {65, }, 3, {
277 { { 0, 0, 90, 65}, 0x40, 90}, { { 90, 0, 180, 65}, 0x40, 90},
278 { {180, 0, 672, 65}, 0x40, 90},
280 { {0, 0, 0, 226}, 0, 0, {0, }, 0, {{{0, 0, 0, 0}, 0, 0},
282 { {0, 0, 65, 226}, 65, 1, {65, }, 1, {
283 { { 0, 0, 226, 65}, 0x40, 90},
285 { {0, 0, 65, 226}, 65, 1, {65, }, 2, {
286 { { 0, 0, 90, 65}, 0x40, 90}, { { 90, 0, 226, 65}, 0x40, 90},
288 { {0, 0, 65, 226}, 65, 1, {65, }, 3, {
289 { { 0, 0, 90, 65}, 0x40, 90}, { { 90, 0, 163, 65}, 0x40, 90},
290 { {163, 0, 226, 65}, 0x40, 90},
294 static int rbsize_numtests = 0;
296 #define check_sizes_todo(todomask) { \
299 int count, i/*, mask=(todomask)*/; \
300 rbsize_result_t *res = &rbsize_results[rbsize_numtests]; \
301 assert(rbsize_numtests < sizeof(rbsize_results)/sizeof(rbsize_results[0])); \
302 GetClientRect(hRebar, &rc); \
303 check_rect("client", rc, res->rcClient); \
304 count = SendMessage(hRebar, RB_GETROWCOUNT, 0, 0); \
305 compare(count, res->nRows, "%d"); \
306 for (i=0; i<min(count, res->nRows); i++) { \
307 int height = SendMessageA(hRebar, RB_GETROWHEIGHT, 0, 0);\
308 ok(height == res->cyRowHeights[i], "Height mismatch for row %d - %d vs %d\n", i, res->cyRowHeights[i], height); \
310 count = SendMessage(hRebar, RB_GETBANDCOUNT, 0, 0); \
311 compare(count, res->nBands, "%d"); \
312 for (i=0; i<min(count, res->nBands); i++) { \
313 ok(SendMessageA(hRebar, RB_GETRECT, i, (LPARAM)&rc) == 1, "RB_GETRECT\n"); \
314 if (!(res->bands[i].fStyle & RBBS_HIDDEN)) \
315 check_rect("band", rc, res->bands[i].rc); \
316 rbi.cbSize = REBARBANDINFOA_V6_SIZE; \
317 rbi.fMask = RBBIM_STYLE | RBBIM_SIZE; \
318 ok(SendMessageA(hRebar, RB_GETBANDINFO, i, (LPARAM)&rbi) == 1, "RB_GETBANDINFO\n"); \
319 compare(rbi.fStyle, res->bands[i].fStyle, "%x"); \
320 compare(rbi.cx, res->bands[i].cx, "%d"); \
325 #define check_sizes() check_sizes_todo(0)
329 static void add_band_w(HWND hRebar, LPCSTR lpszText, int cxMinChild, int cx, int cxIdeal)
331 CHAR buffer[MAX_PATH];
334 if (lpszText != NULL)
335 strcpy(buffer, lpszText);
336 rbi.cbSize = REBARBANDINFOA_V6_SIZE;
337 rbi.fMask = RBBIM_SIZE | RBBIM_CHILDSIZE | RBBIM_CHILD | RBBIM_IDEALSIZE | RBBIM_TEXT;
339 rbi.cxMinChild = cxMinChild;
340 rbi.cxIdeal = cxIdeal;
342 rbi.hwndChild = build_toolbar(1, hRebar);
343 rbi.lpText = (lpszText ? buffer : NULL);
344 SendMessage(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
347 static void layout_test(void)
354 rebuild_rebar(&hRebar);
356 rbi.cbSize = REBARBANDINFOA_V6_SIZE;
357 rbi.fMask = RBBIM_SIZE | RBBIM_CHILDSIZE | RBBIM_CHILD;
359 rbi.cxMinChild = 100;
361 rbi.hwndChild = NULL;
362 SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
365 rbi.fMask |= RBBIM_STYLE;
366 rbi.fStyle = RBBS_CHILDEDGE;
367 SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
374 rbi.hwndChild = build_toolbar(0, hRebar);
375 SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
378 rbi.fStyle = RBBS_CHILDEDGE;
380 rbi.hwndChild = build_toolbar(0, hRebar);
381 SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
384 SetWindowLong(hRebar, GWL_STYLE, GetWindowLong(hRebar, GWL_STYLE) | RBS_BANDBORDERS);
385 check_sizes(); /* a style change won't start a relayout */
386 rbi.fMask = RBBIM_SIZE;
388 SendMessageA(hRebar, RB_SETBANDINFO, 3, (LPARAM)&rbi);
389 check_sizes(); /* here it will be relayouted */
391 /* this will force a new row */
392 rbi.fMask = RBBIM_SIZE | RBBIM_CHILDSIZE | RBBIM_CHILD;
394 rbi.cxMinChild = 400;
396 rbi.hwndChild = build_toolbar(0, hRebar);
397 SendMessageA(hRebar, RB_INSERTBAND, 1, (LPARAM)&rbi);
400 rbi.fMask = RBBIM_STYLE;
401 rbi.fStyle = RBBS_HIDDEN;
402 SendMessageA(hRebar, RB_SETBANDINFO, 2, (LPARAM)&rbi);
405 SendMessageA(hRebar, RB_DELETEBAND, 2, 0);
407 SendMessageA(hRebar, RB_DELETEBAND, 0, 0);
409 SendMessageA(hRebar, RB_DELETEBAND, 1, 0);
412 rebuild_rebar(&hRebar);
413 add_band_w(hRebar, "ABC", 70, 40, 100);
414 add_band_w(hRebar, NULL, 40, 70, 100);
415 add_band_w(hRebar, NULL, 170, 240, 100);
416 add_band_w(hRebar, "MMMMMMM", 60, 60, 100);
417 add_band_w(hRebar, NULL, 200, 200, 100);
419 SendMessageA(hRebar, RB_MAXIMIZEBAND, 1, TRUE);
421 SendMessageA(hRebar, RB_MAXIMIZEBAND, 1, TRUE);
423 SendMessageA(hRebar, RB_MAXIMIZEBAND, 2, FALSE);
425 SendMessageA(hRebar, RB_MINIMIZEBAND, 2, 0);
427 SendMessageA(hRebar, RB_MINIMIZEBAND, 0, 0);
430 /* an image will increase the band height */
431 himl = ImageList_LoadImage(LoadLibrary("comctl32"), MAKEINTRESOURCE(121), 24, 2, CLR_NONE, IMAGE_BITMAP, LR_DEFAULTCOLOR);
432 ri.cbSize = sizeof(ri);
433 ri.fMask = RBIM_IMAGELIST;
435 ok(SendMessage(hRebar, RB_SETBARINFO, 0, (LPARAM)&ri), "RB_SETBARINFO failed\n");
436 rbi.fMask = RBBIM_IMAGE;
438 SendMessage(hRebar, RB_SETBANDINFO, 1, (LPARAM)&rbi);
441 /* after removing it everything is back to normal*/
443 SendMessage(hRebar, RB_SETBANDINFO, 1, (LPARAM)&rbi);
446 /* Only -1 means that the image is not present. Other invalid values increase the height */
448 SendMessage(hRebar, RB_SETBANDINFO, 1, (LPARAM)&rbi);
451 /* VARHEIGHT resizing test on a horizontal rebar */
452 rebuild_rebar(&hRebar);
453 SetWindowLong(hRebar, GWL_STYLE, GetWindowLong(hRebar, GWL_STYLE) | RBS_AUTOSIZE);
455 rbi.fMask = RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_SIZE | RBBIM_STYLE;
456 rbi.fStyle = RBBS_VARIABLEHEIGHT;
461 rbi.cyMaxChild = 200;
463 rbi.hwndChild = build_toolbar(0, hRebar);
464 SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
467 rbi.hwndChild = build_toolbar(0, hRebar);
468 SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
473 rbi.hwndChild = build_toolbar(0, hRebar);
474 SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
477 /* VARHEIGHT resizing on a vertical rebar */
478 rebuild_rebar(&hRebar);
479 SetWindowLong(hRebar, GWL_STYLE, GetWindowLong(hRebar, GWL_STYLE) | CCS_VERT | RBS_AUTOSIZE);
481 rbi.fMask = RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_SIZE | RBBIM_STYLE;
482 rbi.fStyle = RBBS_VARIABLEHEIGHT;
489 rbi.hwndChild = build_toolbar(0, hRebar);
490 SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
494 rbi.hwndChild = build_toolbar(0, hRebar);
495 SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
501 rbi.hwndChild = build_toolbar(0, hRebar);
502 SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
505 DestroyWindow(hRebar);
506 ImageList_Destroy(himl);
509 #if 0 /* use this to generate more tests */
511 static void dump_client(HWND hRebar)
515 GetWindowRect(hRebar, &r);
516 MapWindowPoints(HWND_DESKTOP, hMainWnd, &r, 2);
517 if (height_change_notify_rect.top != -1)
520 GetClientRect(hRebar, &rcClient);
521 assert(EqualRect(&rcClient, &height_change_notify_rect));
526 printf(" {{%d, %d, %d, %d}, %d, %s},\n", r.left, r.top, r.right, r.bottom, SendMessage(hRebar, RB_GETROWCOUNT, 0, 0),
527 notify ? "TRUE" : "FALSE");
528 SetRect(&height_change_notify_rect, -1, -1, -1, -1);
531 #define comment(fmt, arg1) printf("/* " fmt " */\n", arg1);
532 #define check_client() dump_client(hRebar)
540 } rbresize_test_result_t;
542 rbresize_test_result_t resize_results[] = {
544 {{0, 2, 672, 2}, 0, FALSE},
545 {{0, 2, 672, 22}, 1, TRUE},
546 {{0, 2, 672, 22}, 1, FALSE},
547 {{0, 2, 672, 22}, 1, FALSE},
548 {{0, 2, 672, 22}, 1, FALSE},
549 {{0, 2, 672, 22}, 0, FALSE},
551 {{0, 0, 672, 0}, 0, FALSE},
552 {{0, 0, 672, 20}, 1, TRUE},
553 {{0, 0, 672, 20}, 1, FALSE},
554 {{0, 0, 672, 20}, 1, FALSE},
555 {{0, 0, 672, 20}, 1, FALSE},
556 {{0, 0, 672, 20}, 0, FALSE},
558 {{0, 226, 672, 226}, 0, FALSE},
559 {{0, 206, 672, 226}, 1, TRUE},
560 {{0, 206, 672, 226}, 1, FALSE},
561 {{0, 206, 672, 226}, 1, FALSE},
562 {{0, 206, 672, 226}, 1, FALSE},
563 {{0, 206, 672, 226}, 0, FALSE},
565 {{0, 226, 672, 226}, 0, FALSE},
566 {{0, 206, 672, 226}, 1, TRUE},
567 {{0, 206, 672, 226}, 1, FALSE},
568 {{0, 206, 672, 226}, 1, FALSE},
569 {{0, 206, 672, 226}, 1, FALSE},
570 {{0, 206, 672, 226}, 0, FALSE},
572 {{2, 0, 2, 226}, 0, FALSE},
573 {{2, 0, 22, 226}, 1, TRUE},
574 {{2, 0, 22, 226}, 1, FALSE},
575 {{2, 0, 22, 226}, 1, FALSE},
576 {{2, 0, 22, 226}, 1, FALSE},
577 {{2, 0, 22, 226}, 0, FALSE},
579 {{672, 0, 672, 226}, 0, FALSE},
580 {{652, 0, 672, 226}, 1, TRUE},
581 {{652, 0, 672, 226}, 1, FALSE},
582 {{652, 0, 672, 226}, 1, FALSE},
583 {{652, 0, 672, 226}, 1, FALSE},
584 {{652, 0, 672, 226}, 0, FALSE},
586 {{10, 11, 510, 11}, 0, FALSE},
587 {{10, 15, 510, 35}, 1, TRUE},
588 {{10, 17, 510, 37}, 1, FALSE},
589 {{10, 14, 110, 54}, 2, TRUE},
590 {{0, 4, 0, 44}, 2, FALSE},
591 {{0, 6, 0, 46}, 2, FALSE},
592 {{0, 8, 0, 48}, 2, FALSE},
593 {{0, 12, 0, 32}, 1, TRUE},
594 {{0, 4, 100, 24}, 0, FALSE},
596 {{10, 5, 510, 5}, 0, FALSE},
597 {{10, 5, 510, 25}, 1, TRUE},
598 {{10, 5, 510, 25}, 1, FALSE},
599 {{10, 10, 110, 50}, 2, TRUE},
600 {{0, 0, 0, 40}, 2, FALSE},
601 {{0, 0, 0, 40}, 2, FALSE},
602 {{0, 0, 0, 40}, 2, FALSE},
603 {{0, 0, 0, 20}, 1, TRUE},
604 {{0, 0, 100, 20}, 0, FALSE},
606 {{10, 5, 510, 20}, 0, FALSE},
607 {{10, 5, 510, 20}, 1, TRUE},
608 {{10, 10, 110, 110}, 2, TRUE},
609 {{0, 0, 0, 0}, 2, FALSE},
610 {{0, 0, 0, 0}, 2, FALSE},
611 {{0, 0, 0, 0}, 2, FALSE},
612 {{0, 0, 0, 0}, 1, TRUE},
613 {{0, 0, 100, 100}, 0, FALSE},
615 {{0, 5, 672, 5}, 0, FALSE},
616 {{0, 5, 672, 25}, 1, TRUE},
617 {{0, 10, 672, 30}, 1, FALSE},
618 {{0, 0, 672, 20}, 1, FALSE},
619 {{0, 0, 672, 20}, 1, FALSE},
620 {{0, 0, 672, 20}, 0, FALSE},
622 {{10, 0, 10, 226}, 0, FALSE},
623 {{10, 0, 30, 226}, 1, TRUE},
624 {{10, 0, 30, 226}, 1, FALSE},
625 {{0, 0, 20, 226}, 1, FALSE},
626 {{0, 0, 20, 226}, 1, FALSE},
627 {{0, 0, 20, 226}, 0, FALSE},
629 {{-2, 0, 674, 4}, 0, FALSE},
630 {{-2, 0, 674, 24}, 1, TRUE},
631 {{-2, 0, 674, 24}, 1, FALSE},
632 {{-2, 0, 674, 24}, 1, FALSE},
633 {{-2, 0, 674, 24}, 1, FALSE},
634 {{-2, 0, 674, 24}, 0, FALSE},
636 {{10, 5, 510, 9}, 0, FALSE},
637 {{10, 5, 510, 29}, 1, TRUE},
638 {{10, 5, 510, 29}, 1, FALSE},
639 {{10, 10, 110, 54}, 2, TRUE},
640 {{0, 0, 0, 44}, 2, FALSE},
641 {{0, 0, 0, 44}, 2, FALSE},
642 {{0, 0, 0, 44}, 2, FALSE},
643 {{0, 0, 0, 24}, 1, TRUE},
644 {{0, 0, 100, 24}, 0, FALSE},
646 {{10, 5, 510, 20}, 0, FALSE},
647 {{10, 5, 510, 20}, 1, TRUE},
648 {{10, 10, 110, 110}, 2, TRUE},
649 {{0, 0, 0, 0}, 2, FALSE},
650 {{0, 0, 0, 0}, 2, FALSE},
651 {{0, 0, 0, 0}, 2, FALSE},
652 {{0, 0, 0, 0}, 1, TRUE},
653 {{0, 0, 100, 100}, 0, FALSE},
655 {{-2, 5, 674, 9}, 0, FALSE},
656 {{-2, 5, 674, 29}, 1, TRUE},
657 {{-2, 10, 674, 34}, 1, FALSE},
658 {{-2, 0, 674, 24}, 1, FALSE},
659 {{-2, 0, 674, 24}, 1, FALSE},
660 {{-2, 0, 674, 24}, 0, FALSE},
663 static int resize_numtests = 0;
665 #define comment(fmt, arg1)
666 #define check_client() { \
668 rbresize_test_result_t *res = &resize_results[resize_numtests++]; \
669 assert(resize_numtests <= sizeof(resize_results)/sizeof(resize_results[0])); \
670 GetWindowRect(hRebar, &r); \
671 MapWindowPoints(HWND_DESKTOP, hMainWnd, (LPPOINT)&r, 2); \
672 if ((dwStyles[i] & (CCS_NOPARENTALIGN|CCS_NODIVIDER)) == CCS_NOPARENTALIGN) {\
673 check_rect_no_top("client", r, res->rc); /* the top coordinate changes after every layout and is very implementation-dependent */ \
675 check_rect("client", r, res->rc); \
677 expect_eq((int)SendMessage(hRebar, RB_GETROWCOUNT, 0, 0), res->iNumRows, int, "%d"); \
678 if (res->heightNotify) { \
680 GetClientRect(hRebar, &rcClient); \
681 check_rect("notify", height_change_notify_rect, rcClient); \
682 } else ok(height_change_notify_rect.top == -1, "Unexpected RBN_HEIGHTCHANGE received\n"); \
683 SetRect(&height_change_notify_rect, -1, -1, -1, -1); \
688 static void resize_test(void)
690 DWORD dwStyles[] = {CCS_TOP, CCS_TOP | CCS_NODIVIDER, CCS_BOTTOM, CCS_BOTTOM | CCS_NODIVIDER, CCS_VERT, CCS_RIGHT,
691 CCS_NOPARENTALIGN, CCS_NOPARENTALIGN | CCS_NODIVIDER, CCS_NORESIZE, CCS_NOMOVEY, CCS_NOMOVEY | CCS_VERT,
692 CCS_TOP | WS_BORDER, CCS_NOPARENTALIGN | CCS_NODIVIDER | WS_BORDER, CCS_NORESIZE | WS_BORDER,
693 CCS_NOMOVEY | WS_BORDER};
695 const int styles_count = sizeof(dwStyles) / sizeof(dwStyles[0]);
698 for (i = 0; i < styles_count; i++)
700 comment("style %08x", dwStyles[i]);
701 SetRect(&height_change_notify_rect, -1, -1, -1, -1);
702 hRebar = CreateWindow(REBARCLASSNAME, "A", dwStyles[i] | WS_CHILD | WS_VISIBLE, 10, 5, 500, 15, hMainWnd, NULL, GetModuleHandle(NULL), 0);
704 add_band_w(hRebar, NULL, 70, 100, 0);
705 if (dwStyles[i] & CCS_NOPARENTALIGN) /* the window drifts downward for CCS_NOPARENTALIGN without CCS_NODIVIDER */
707 add_band_w(hRebar, NULL, 70, 100, 0);
709 MoveWindow(hRebar, 10, 10, 100, 100, TRUE);
711 MoveWindow(hRebar, 0, 0, 0, 0, TRUE);
713 /* try to fool the rebar by sending invalid width/height - won't work */
714 if (dwStyles[i] & (CCS_NORESIZE | CCS_NOPARENTALIGN))
718 pos.hwndInsertAfter = NULL;
724 SendMessage(hRebar, WM_WINDOWPOSCHANGING, 0, (LPARAM)&pos);
725 SendMessage(hRebar, WM_WINDOWPOSCHANGED, 0, (LPARAM)&pos);
727 SendMessage(hRebar, WM_SIZE, SIZE_RESTORED, MAKELONG(500, 500));
730 SendMessage(hRebar, RB_DELETEBAND, 0, 0);
732 SendMessage(hRebar, RB_DELETEBAND, 0, 0);
733 MoveWindow(hRebar, 0, 0, 100, 100, TRUE);
735 DestroyWindow(hRebar);
739 static void expect_band_content(UINT uBand, INT fStyle, COLORREF clrFore,
740 COLORREF clrBack, LPCSTR lpText, int iImage, HWND hwndChild,
741 INT cxMinChild, INT cyMinChild, INT cx, HBITMAP hbmBack, INT wID,
742 INT cyChild, INT cyMaxChild, INT cyIntegral, INT cxIdeal, LPARAM lParam,
743 INT cxHeader, INT cxHeader_broken)
745 CHAR buf[MAX_PATH] = "abc";
748 memset(&rb, 0xdd, sizeof(rb));
749 rb.cbSize = REBARBANDINFOA_V6_SIZE;
750 rb.fMask = RBBIM_BACKGROUND | RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_COLORS
751 | RBBIM_HEADERSIZE | RBBIM_ID | RBBIM_IDEALSIZE | RBBIM_IMAGE | RBBIM_LPARAM
752 | RBBIM_SIZE | RBBIM_STYLE | RBBIM_TEXT;
755 ok(SendMessageA(hRebar, RB_GETBANDINFOA, uBand, (LPARAM)&rb), "RB_GETBANDINFO failed\n");
756 expect_eq(rb.fStyle, fStyle, int, "%x");
757 todo_wine expect_eq(rb.clrFore, clrFore, COLORREF, "%x");
758 todo_wine expect_eq(rb.clrBack, clrBack, unsigned, "%x");
759 expect_eq(strcmp(rb.lpText, lpText), 0, int, "%d");
760 expect_eq(rb.iImage, iImage, int, "%x");
761 expect_eq(rb.hwndChild, hwndChild, HWND, "%p");
762 expect_eq(rb.cxMinChild, cxMinChild, int, "%d");
763 expect_eq(rb.cyMinChild, cyMinChild, int, "%d");
764 expect_eq(rb.cx, cx, int, "%d");
765 expect_eq(rb.hbmBack, hbmBack, HBITMAP, "%p");
766 expect_eq(rb.wID, wID, int, "%d");
767 /* the values of cyChild, cyMaxChild and cyIntegral can't be read unless the band is RBBS_VARIABLEHEIGHT */
768 expect_eq(rb.cyChild, cyChild, int, "%x");
769 expect_eq(rb.cyMaxChild, cyMaxChild, int, "%x");
770 expect_eq(rb.cyIntegral, cyIntegral, int, "%x");
771 expect_eq(rb.cxIdeal, cxIdeal, int, "%d");
772 expect_eq(rb.lParam, lParam, LPARAM, "%ld");
773 ok( rb.cxHeader == cxHeader || broken(rb.cxHeader == cxHeader_broken),
774 "expected %d for %d\n", cxHeader, rb.cxHeader );
777 static void bandinfo_test(void)
780 CHAR szABC[] = "ABC";
781 CHAR szABCD[] = "ABCD";
783 rebuild_rebar(&hRebar);
784 rb.cbSize = REBARBANDINFOA_V6_SIZE;
786 if (!SendMessageA(hRebar, RB_INSERTBANDA, 0, (LPARAM)&rb))
788 win_skip( "V6 info not supported\n" );
789 DestroyWindow(hRebar);
792 expect_band_content(0, 0, 0, GetSysColor(COLOR_3DFACE), "", -1, NULL, 0, 0, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 0, -1);
794 rb.fMask = RBBIM_CHILDSIZE;
800 ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_SETBANDINFO failed\n");
801 expect_band_content(0, 0, 0, GetSysColor(COLOR_3DFACE), "", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 0, -1);
803 rb.fMask = RBBIM_TEXT;
805 ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_SETBANDINFO failed\n");
806 expect_band_content(0, 0, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 35, -1);
808 rb.cbSize = REBARBANDINFOA_V6_SIZE;
810 ok(SendMessageA(hRebar, RB_INSERTBANDA, 1, (LPARAM)&rb), "RB_INSERTBAND failed\n");
811 expect_band_content(1, 0, 0, GetSysColor(COLOR_3DFACE), "", -1, NULL, 0, 0, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 9, -1);
812 expect_band_content(0, 0, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 40, -1);
814 rb.fMask = RBBIM_HEADERSIZE;
816 ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_SETBANDINFO failed\n");
817 expect_band_content(0, 0x40000000, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 50, -1);
820 ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_SETBANDINFO failed\n");
821 expect_band_content(0, 0x40000000, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 5, -1);
823 rb.fMask = RBBIM_TEXT;
825 ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_SETBANDINFO failed\n");
826 expect_band_content(0, 0x40000000, 0, GetSysColor(COLOR_3DFACE), "ABCD", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 5, -1);
827 rb.fMask = RBBIM_STYLE | RBBIM_TEXT;
828 rb.fStyle = RBBS_VARIABLEHEIGHT;
830 ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_SETBANDINFO failed\n");
831 expect_band_content(0, RBBS_VARIABLEHEIGHT, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 20, 0x7fffffff, 0, 0, 0, 40, 5);
833 DestroyWindow(hRebar);
839 BOOL (WINAPI *pInitCommonControlsEx)(const INITCOMMONCONTROLSEX*);
840 INITCOMMONCONTROLSEX iccex;
845 /* LoadLibrary is needed. This file has no references to functions in comctl32 */
846 hComctl32 = LoadLibraryA("comctl32.dll");
847 pInitCommonControlsEx = (void*)GetProcAddress(hComctl32, "InitCommonControlsEx");
848 if (!pInitCommonControlsEx)
850 skip("InitCommonControlsEx() is missing. Skipping the tests\n");
853 iccex.dwSize = sizeof(iccex);
854 iccex.dwICC = ICC_COOL_CLASSES;
855 pInitCommonControlsEx(&iccex);
857 wc.style = CS_HREDRAW | CS_VREDRAW;
860 wc.hInstance = GetModuleHandleA(NULL);
862 wc.hCursor = LoadCursorA(NULL, IDC_IBEAM);
863 wc.hbrBackground = GetSysColorBrush(COLOR_WINDOW);
864 wc.lpszMenuName = NULL;
865 wc.lpszClassName = "MyTestWnd";
866 wc.lpfnWndProc = MyWndProc;
868 hMainWnd = CreateWindowExA(0, "MyTestWnd", "Blah", WS_OVERLAPPEDWINDOW,
869 CW_USEDEFAULT, CW_USEDEFAULT, 672+2*GetSystemMetrics(SM_CXSIZEFRAME),
870 226+GetSystemMetrics(SM_CYCAPTION)+2*GetSystemMetrics(SM_CYSIZEFRAME),
871 NULL, NULL, GetModuleHandleA(NULL), 0);
872 GetClientRect(hMainWnd, &rc);
873 ShowWindow(hMainWnd, SW_SHOW);
877 if(is_font_installed("System") && is_font_installed("Tahoma"))
882 skip("Missing System or Tahoma font\n");
885 while(GetMessageA(&msg,0,0,0)) {
886 TranslateMessage(&msg);
887 DispatchMessageA(&msg);
889 DestroyWindow(hMainWnd);
891 FreeLibrary(hComctl32);