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_LOADIMAGE 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 = sizeof(REBARBANDINFO);
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_ITEMRECT\n"); \
314 if (!(res->bands[i].fStyle & RBBS_HIDDEN)) \
315 check_rect("band", rc, res->bands[i].rc); \
316 rbi.cbSize = sizeof(REBARBANDINFO); \
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 = sizeof(rbi);
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 = sizeof(rbi);
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);
508 #if 0 /* use this to generate more tests */
510 static void dump_client(HWND hRebar)
514 GetWindowRect(hRebar, &r);
515 MapWindowPoints(HWND_DESKTOP, hMainWnd, (LPPOINT)&r, 2);
516 if (height_change_notify_rect.top != -1)
519 GetClientRect(hRebar, &rcClient);
520 assert(EqualRect(&rcClient, &height_change_notify_rect));
525 printf(" {{%d, %d, %d, %d}, %d, %s},\n", r.left, r.top, r.right, r.bottom, SendMessage(hRebar, RB_GETROWCOUNT, 0, 0),
526 notify ? "TRUE" : "FALSE");
527 SetRect(&height_change_notify_rect, -1, -1, -1, -1);
530 #define comment(fmt, arg1) printf("/* " fmt " */\n", arg1);
531 #define check_client() dump_client(hRebar)
539 } rbresize_test_result_t;
541 rbresize_test_result_t resize_results[] = {
543 {{0, 2, 672, 2}, 0, FALSE},
544 {{0, 2, 672, 22}, 1, TRUE},
545 {{0, 2, 672, 22}, 1, FALSE},
546 {{0, 2, 672, 22}, 1, FALSE},
547 {{0, 2, 672, 22}, 1, FALSE},
548 {{0, 2, 672, 22}, 0, FALSE},
550 {{0, 0, 672, 0}, 0, FALSE},
551 {{0, 0, 672, 20}, 1, TRUE},
552 {{0, 0, 672, 20}, 1, FALSE},
553 {{0, 0, 672, 20}, 1, FALSE},
554 {{0, 0, 672, 20}, 1, FALSE},
555 {{0, 0, 672, 20}, 0, FALSE},
557 {{0, 226, 672, 226}, 0, FALSE},
558 {{0, 206, 672, 226}, 1, TRUE},
559 {{0, 206, 672, 226}, 1, FALSE},
560 {{0, 206, 672, 226}, 1, FALSE},
561 {{0, 206, 672, 226}, 1, FALSE},
562 {{0, 206, 672, 226}, 0, FALSE},
564 {{0, 226, 672, 226}, 0, FALSE},
565 {{0, 206, 672, 226}, 1, TRUE},
566 {{0, 206, 672, 226}, 1, FALSE},
567 {{0, 206, 672, 226}, 1, FALSE},
568 {{0, 206, 672, 226}, 1, FALSE},
569 {{0, 206, 672, 226}, 0, FALSE},
571 {{2, 0, 2, 226}, 0, FALSE},
572 {{2, 0, 22, 226}, 1, TRUE},
573 {{2, 0, 22, 226}, 1, FALSE},
574 {{2, 0, 22, 226}, 1, FALSE},
575 {{2, 0, 22, 226}, 1, FALSE},
576 {{2, 0, 22, 226}, 0, FALSE},
578 {{672, 0, 672, 226}, 0, FALSE},
579 {{652, 0, 672, 226}, 1, TRUE},
580 {{652, 0, 672, 226}, 1, FALSE},
581 {{652, 0, 672, 226}, 1, FALSE},
582 {{652, 0, 672, 226}, 1, FALSE},
583 {{652, 0, 672, 226}, 0, FALSE},
585 {{10, 11, 510, 11}, 0, FALSE},
586 {{10, 15, 510, 35}, 1, TRUE},
587 {{10, 17, 510, 37}, 1, FALSE},
588 {{10, 14, 110, 54}, 2, TRUE},
589 {{0, 4, 0, 44}, 2, FALSE},
590 {{0, 6, 0, 46}, 2, FALSE},
591 {{0, 8, 0, 48}, 2, FALSE},
592 {{0, 12, 0, 32}, 1, TRUE},
593 {{0, 4, 100, 24}, 0, FALSE},
595 {{10, 5, 510, 5}, 0, FALSE},
596 {{10, 5, 510, 25}, 1, TRUE},
597 {{10, 5, 510, 25}, 1, FALSE},
598 {{10, 10, 110, 50}, 2, TRUE},
599 {{0, 0, 0, 40}, 2, FALSE},
600 {{0, 0, 0, 40}, 2, FALSE},
601 {{0, 0, 0, 40}, 2, FALSE},
602 {{0, 0, 0, 20}, 1, TRUE},
603 {{0, 0, 100, 20}, 0, FALSE},
605 {{10, 5, 510, 20}, 0, FALSE},
606 {{10, 5, 510, 20}, 1, TRUE},
607 {{10, 10, 110, 110}, 2, TRUE},
608 {{0, 0, 0, 0}, 2, FALSE},
609 {{0, 0, 0, 0}, 2, FALSE},
610 {{0, 0, 0, 0}, 2, FALSE},
611 {{0, 0, 0, 0}, 1, TRUE},
612 {{0, 0, 100, 100}, 0, FALSE},
614 {{0, 5, 672, 5}, 0, FALSE},
615 {{0, 5, 672, 25}, 1, TRUE},
616 {{0, 10, 672, 30}, 1, FALSE},
617 {{0, 0, 672, 20}, 1, FALSE},
618 {{0, 0, 672, 20}, 1, FALSE},
619 {{0, 0, 672, 20}, 0, FALSE},
621 {{10, 0, 10, 226}, 0, FALSE},
622 {{10, 0, 30, 226}, 1, TRUE},
623 {{10, 0, 30, 226}, 1, FALSE},
624 {{0, 0, 20, 226}, 1, FALSE},
625 {{0, 0, 20, 226}, 1, FALSE},
626 {{0, 0, 20, 226}, 0, FALSE},
628 {{-2, 0, 674, 4}, 0, FALSE},
629 {{-2, 0, 674, 24}, 1, TRUE},
630 {{-2, 0, 674, 24}, 1, FALSE},
631 {{-2, 0, 674, 24}, 1, FALSE},
632 {{-2, 0, 674, 24}, 1, FALSE},
633 {{-2, 0, 674, 24}, 0, FALSE},
635 {{10, 5, 510, 9}, 0, FALSE},
636 {{10, 5, 510, 29}, 1, TRUE},
637 {{10, 5, 510, 29}, 1, FALSE},
638 {{10, 10, 110, 54}, 2, TRUE},
639 {{0, 0, 0, 44}, 2, FALSE},
640 {{0, 0, 0, 44}, 2, FALSE},
641 {{0, 0, 0, 44}, 2, FALSE},
642 {{0, 0, 0, 24}, 1, TRUE},
643 {{0, 0, 100, 24}, 0, FALSE},
645 {{10, 5, 510, 20}, 0, FALSE},
646 {{10, 5, 510, 20}, 1, TRUE},
647 {{10, 10, 110, 110}, 2, TRUE},
648 {{0, 0, 0, 0}, 2, FALSE},
649 {{0, 0, 0, 0}, 2, FALSE},
650 {{0, 0, 0, 0}, 2, FALSE},
651 {{0, 0, 0, 0}, 1, TRUE},
652 {{0, 0, 100, 100}, 0, FALSE},
654 {{-2, 5, 674, 9}, 0, FALSE},
655 {{-2, 5, 674, 29}, 1, TRUE},
656 {{-2, 10, 674, 34}, 1, FALSE},
657 {{-2, 0, 674, 24}, 1, FALSE},
658 {{-2, 0, 674, 24}, 1, FALSE},
659 {{-2, 0, 674, 24}, 0, FALSE},
662 static int resize_numtests = 0;
664 #define comment(fmt, arg1)
665 #define check_client() { \
667 rbresize_test_result_t *res = &resize_results[resize_numtests++]; \
668 assert(resize_numtests <= sizeof(resize_results)/sizeof(resize_results[0])); \
669 GetWindowRect(hRebar, &r); \
670 MapWindowPoints(HWND_DESKTOP, hMainWnd, (LPPOINT)&r, 2); \
671 if ((dwStyles[i] & (CCS_NOPARENTALIGN|CCS_NODIVIDER)) == CCS_NOPARENTALIGN) {\
672 check_rect_no_top("client", r, res->rc); /* the top coordinate changes after every layout and is very implementation-dependent */ \
674 check_rect("client", r, res->rc); \
676 expect_eq((int)SendMessage(hRebar, RB_GETROWCOUNT, 0, 0), res->iNumRows, int, "%d"); \
677 if (res->heightNotify) { \
679 GetClientRect(hRebar, &rcClient); \
680 check_rect("notify", height_change_notify_rect, rcClient); \
681 } else ok(height_change_notify_rect.top == -1, "Unexpected RBN_HEIGHTCHANGE received\n"); \
682 SetRect(&height_change_notify_rect, -1, -1, -1, -1); \
687 static void resize_test(void)
689 DWORD dwStyles[] = {CCS_TOP, CCS_TOP | CCS_NODIVIDER, CCS_BOTTOM, CCS_BOTTOM | CCS_NODIVIDER, CCS_VERT, CCS_RIGHT,
690 CCS_NOPARENTALIGN, CCS_NOPARENTALIGN | CCS_NODIVIDER, CCS_NORESIZE, CCS_NOMOVEY, CCS_NOMOVEY | CCS_VERT,
691 CCS_TOP | WS_BORDER, CCS_NOPARENTALIGN | CCS_NODIVIDER | WS_BORDER, CCS_NORESIZE | WS_BORDER,
692 CCS_NOMOVEY | WS_BORDER};
694 const int styles_count = sizeof(dwStyles) / sizeof(dwStyles[0]);
697 for (i = 0; i < styles_count; i++)
699 comment("style %08x", dwStyles[i]);
700 SetRect(&height_change_notify_rect, -1, -1, -1, -1);
701 hRebar = CreateWindow(REBARCLASSNAME, "A", dwStyles[i] | WS_CHILD | WS_VISIBLE, 10, 5, 500, 15, hMainWnd, NULL, GetModuleHandle(NULL), 0);
703 add_band_w(hRebar, NULL, 70, 100, 0);
704 if (dwStyles[i] & CCS_NOPARENTALIGN) /* the window drifts downward for CCS_NOPARENTALIGN without CCS_NODIVIDER */
706 add_band_w(hRebar, NULL, 70, 100, 0);
708 MoveWindow(hRebar, 10, 10, 100, 100, TRUE);
710 MoveWindow(hRebar, 0, 0, 0, 0, TRUE);
712 /* try to fool the rebar by sending invalid width/height - won't work */
713 if (dwStyles[i] & (CCS_NORESIZE | CCS_NOPARENTALIGN))
717 pos.hwndInsertAfter = NULL;
723 SendMessage(hRebar, WM_WINDOWPOSCHANGING, 0, (LPARAM)&pos);
724 SendMessage(hRebar, WM_WINDOWPOSCHANGED, 0, (LPARAM)&pos);
726 SendMessage(hRebar, WM_SIZE, SIZE_RESTORED, MAKELONG(500, 500));
729 SendMessage(hRebar, RB_DELETEBAND, 0, 0);
731 SendMessage(hRebar, RB_DELETEBAND, 0, 0);
732 MoveWindow(hRebar, 0, 0, 100, 100, TRUE);
734 DestroyWindow(hRebar);
738 static void expect_band_content(UINT uBand, INT fStyle, COLORREF clrFore,
739 COLORREF clrBack, LPCSTR lpText, int iImage, HWND hwndChild,
740 INT cxMinChild, INT cyMinChild, INT cx, HBITMAP hbmBack, INT wID,
741 INT cyChild, INT cyMaxChild, INT cyIntegral, INT cxIdeal, LPARAM lParam,
744 CHAR buf[MAX_PATH] = "abc";
747 memset(&rb, 0xdd, sizeof(rb));
748 rb.cbSize = sizeof(rb);
749 rb.fMask = RBBIM_BACKGROUND | RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_COLORS
750 | RBBIM_HEADERSIZE | RBBIM_ID | RBBIM_IDEALSIZE | RBBIM_IMAGE | RBBIM_LPARAM
751 | RBBIM_SIZE | RBBIM_STYLE | RBBIM_TEXT;
754 ok(SendMessageA(hRebar, RB_GETBANDINFOA, uBand, (LPARAM)&rb), "RB_GETBANDINFO failed\n");
755 expect_eq(rb.fStyle, fStyle, int, "%x");
756 todo_wine expect_eq(rb.clrFore, clrFore, COLORREF, "%x");
757 todo_wine expect_eq(rb.clrBack, clrBack, unsigned, "%x");
758 expect_eq(strcmp(rb.lpText, lpText), 0, int, "%d");
759 expect_eq(rb.iImage, iImage, int, "%x");
760 expect_eq(rb.hwndChild, hwndChild, HWND, "%p");
761 expect_eq(rb.cxMinChild, cxMinChild, int, "%d");
762 expect_eq(rb.cyMinChild, cyMinChild, int, "%d");
763 expect_eq(rb.cx, cx, int, "%d");
764 expect_eq(rb.hbmBack, hbmBack, HBITMAP, "%p");
765 expect_eq(rb.wID, wID, int, "%d");
766 /* the values of cyChild, cyMaxChild and cyIntegral can't be read unless the band is RBBS_VARIABLEHEIGHT */
767 expect_eq(rb.cyChild, cyChild, int, "%x");
768 expect_eq(rb.cyMaxChild, cyMaxChild, int, "%x");
769 expect_eq(rb.cyIntegral, cyIntegral, int, "%x");
770 expect_eq(rb.cxIdeal, cxIdeal, int, "%d");
771 expect_eq(rb.lParam, lParam, LPARAM, "%ld");
772 expect_eq(rb.cxHeader, cxHeader, int, "%d");
775 static void bandinfo_test(void)
778 CHAR szABC[] = "ABC";
779 CHAR szABCD[] = "ABCD";
781 rebuild_rebar(&hRebar);
782 rb.cbSize = sizeof(REBARBANDINFO);
784 ok(SendMessageA(hRebar, RB_INSERTBANDA, 0, (LPARAM)&rb), "RB_INSERTBAND failed\n");
785 expect_band_content(0, 0, 0, GetSysColor(COLOR_3DFACE), "", -1, NULL, 0, 0, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 0);
787 rb.fMask = RBBIM_CHILDSIZE;
793 ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_INSERTBAND failed\n");
794 expect_band_content(0, 0, 0, GetSysColor(COLOR_3DFACE), "", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 0);
796 rb.fMask = RBBIM_TEXT;
798 ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_INSERTBAND failed\n");
799 expect_band_content(0, 0, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 35);
801 rb.cbSize = sizeof(REBARBANDINFO);
803 ok(SendMessageA(hRebar, RB_INSERTBANDA, 1, (LPARAM)&rb), "RB_INSERTBAND failed\n");
804 expect_band_content(1, 0, 0, GetSysColor(COLOR_3DFACE), "", -1, NULL, 0, 0, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 9);
805 expect_band_content(0, 0, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 40);
807 rb.fMask = RBBIM_HEADERSIZE;
809 ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_INSERTBAND failed\n");
810 expect_band_content(0, 0x40000000, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 50);
813 ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_INSERTBAND failed\n");
814 expect_band_content(0, 0x40000000, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 5);
816 rb.fMask = RBBIM_TEXT;
818 ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_INSERTBAND failed\n");
819 expect_band_content(0, 0x40000000, 0, GetSysColor(COLOR_3DFACE), "ABCD", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 5);
820 rb.fMask = RBBIM_STYLE | RBBIM_TEXT;
821 rb.fStyle = RBBS_VARIABLEHEIGHT;
823 ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_INSERTBAND failed\n");
824 expect_band_content(0, RBBS_VARIABLEHEIGHT, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 20, 0x7fffffff, 0, 0, 0, 40);
826 DestroyWindow(hRebar);
832 BOOL (WINAPI *pInitCommonControlsEx)(const INITCOMMONCONTROLSEX*);
833 INITCOMMONCONTROLSEX iccex;
838 /* LoadLibrary is needed. This file has no references to functions in comctl32 */
839 hComctl32 = LoadLibraryA("comctl32.dll");
840 pInitCommonControlsEx = (void*)GetProcAddress(hComctl32, "InitCommonControlsEx");
841 if (!pInitCommonControlsEx)
843 skip("InitCommonControlsEx() is missing. Skipping the tests\n");
846 iccex.dwSize = sizeof(iccex);
847 iccex.dwICC = ICC_COOL_CLASSES;
848 pInitCommonControlsEx(&iccex);
850 wc.style = CS_HREDRAW | CS_VREDRAW;
853 wc.hInstance = GetModuleHandleA(NULL);
855 wc.hCursor = LoadCursorA(NULL, IDC_IBEAM);
856 wc.hbrBackground = GetSysColorBrush(COLOR_WINDOW);
857 wc.lpszMenuName = NULL;
858 wc.lpszClassName = "MyTestWnd";
859 wc.lpfnWndProc = MyWndProc;
861 hMainWnd = CreateWindowExA(0, "MyTestWnd", "Blah", WS_OVERLAPPEDWINDOW,
862 CW_USEDEFAULT, CW_USEDEFAULT, 672+2*GetSystemMetrics(SM_CXSIZEFRAME),
863 226+GetSystemMetrics(SM_CYCAPTION)+2*GetSystemMetrics(SM_CYSIZEFRAME),
864 NULL, NULL, GetModuleHandleA(NULL), 0);
865 GetClientRect(hMainWnd, &rc);
866 ShowWindow(hMainWnd, SW_SHOW);
870 if(is_font_installed("System") && is_font_installed("Tahoma"))
875 skip("Missing System or Tahoma font\n");
878 while(GetMessageA(&msg,0,0,0)) {
879 TranslateMessage(&msg);
880 DispatchMessageA(&msg);
882 DestroyWindow(hMainWnd);
884 FreeLibrary(hComctl32);