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, 0}, 0, 0, {0, }, 0, {{{0, 0, 0, 0}, 0, 0},
266 { {0, 0, 672, 65}, 65, 1, {65, }, 3, {
267 { { 0, 0, 90, 65}, 0x40, 90}, { { 90, 0, 180, 65}, 0x40, 90},
268 { {180, 0, 672, 65}, 0x40, 90},
270 { {0, 0, 0, 226}, 0, 0, {0, }, 0, {{{0, 0, 0, 0}, 0, 0},
272 { {0, 0, 65, 226}, 65, 1, {65, }, 1, {
273 { { 0, 0, 226, 65}, 0x40, 90},
275 { {0, 0, 65, 226}, 65, 1, {65, }, 2, {
276 { { 0, 0, 90, 65}, 0x40, 90}, { { 90, 0, 226, 65}, 0x40, 90},
278 { {0, 0, 65, 226}, 65, 1, {65, }, 3, {
279 { { 0, 0, 90, 65}, 0x40, 90}, { { 90, 0, 163, 65}, 0x40, 90},
280 { {163, 0, 226, 65}, 0x40, 90},
284 static int rbsize_numtests = 0;
286 #define check_sizes_todo(todomask) { \
289 int count, i/*, mask=(todomask)*/; \
290 rbsize_result_t *res = &rbsize_results[rbsize_numtests]; \
291 assert(rbsize_numtests < sizeof(rbsize_results)/sizeof(rbsize_results[0])); \
292 GetClientRect(hRebar, &rc); \
293 check_rect("client", rc, res->rcClient); \
294 count = SendMessage(hRebar, RB_GETROWCOUNT, 0, 0); \
295 compare(count, res->nRows, "%d"); \
296 for (i=0; i<min(count, res->nRows); i++) { \
297 int height = SendMessageA(hRebar, RB_GETROWHEIGHT, 0, 0);\
298 ok(height == res->cyRowHeights[i], "Height mismatch for row %d - %d vs %d\n", i, res->cyRowHeights[i], height); \
300 count = SendMessage(hRebar, RB_GETBANDCOUNT, 0, 0); \
301 compare(count, res->nBands, "%d"); \
302 for (i=0; i<min(count, res->nBands); i++) { \
303 ok(SendMessageA(hRebar, RB_GETRECT, i, (LPARAM)&rc) == 1, "RB_ITEMRECT\n"); \
304 if (!(res->bands[i].fStyle & RBBS_HIDDEN)) \
305 check_rect("band", rc, res->bands[i].rc); \
306 rbi.cbSize = sizeof(REBARBANDINFO); \
307 rbi.fMask = RBBIM_STYLE | RBBIM_SIZE; \
308 ok(SendMessageA(hRebar, RB_GETBANDINFO, i, (LPARAM)&rbi) == 1, "RB_GETBANDINFO\n"); \
309 compare(rbi.fStyle, res->bands[i].fStyle, "%x"); \
310 compare(rbi.cx, res->bands[i].cx, "%d"); \
315 #define check_sizes() check_sizes_todo(0)
319 static void add_band_w(HWND hRebar, LPCSTR lpszText, int cxMinChild, int cx, int cxIdeal)
321 CHAR buffer[MAX_PATH];
324 if (lpszText != NULL)
325 strcpy(buffer, lpszText);
326 rbi.cbSize = sizeof(rbi);
327 rbi.fMask = RBBIM_SIZE | RBBIM_CHILDSIZE | RBBIM_CHILD | RBBIM_IDEALSIZE | RBBIM_TEXT;
329 rbi.cxMinChild = cxMinChild;
330 rbi.cxIdeal = cxIdeal;
332 rbi.hwndChild = build_toolbar(1, hRebar);
333 rbi.lpText = (lpszText ? buffer : NULL);
334 SendMessage(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
337 static void layout_test(void)
344 rebuild_rebar(&hRebar);
346 rbi.cbSize = sizeof(rbi);
347 rbi.fMask = RBBIM_SIZE | RBBIM_CHILDSIZE | RBBIM_CHILD;
349 rbi.cxMinChild = 100;
351 rbi.hwndChild = NULL;
352 SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
355 rbi.fMask |= RBBIM_STYLE;
356 rbi.fStyle = RBBS_CHILDEDGE;
357 SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
364 rbi.hwndChild = build_toolbar(0, hRebar);
365 SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
368 rbi.fStyle = RBBS_CHILDEDGE;
370 rbi.hwndChild = build_toolbar(0, hRebar);
371 SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
374 SetWindowLong(hRebar, GWL_STYLE, GetWindowLong(hRebar, GWL_STYLE) | RBS_BANDBORDERS);
375 check_sizes(); /* a style change won't start a relayout */
376 rbi.fMask = RBBIM_SIZE;
378 SendMessageA(hRebar, RB_SETBANDINFO, 3, (LPARAM)&rbi);
379 check_sizes(); /* here it will be relayouted */
381 /* this will force a new row */
382 rbi.fMask = RBBIM_SIZE | RBBIM_CHILDSIZE | RBBIM_CHILD;
384 rbi.cxMinChild = 400;
386 rbi.hwndChild = build_toolbar(0, hRebar);
387 SendMessageA(hRebar, RB_INSERTBAND, 1, (LPARAM)&rbi);
390 rbi.fMask = RBBIM_STYLE;
391 rbi.fStyle = RBBS_HIDDEN;
392 SendMessageA(hRebar, RB_SETBANDINFO, 2, (LPARAM)&rbi);
395 SendMessageA(hRebar, RB_DELETEBAND, 2, 0);
397 SendMessageA(hRebar, RB_DELETEBAND, 0, 0);
399 SendMessageA(hRebar, RB_DELETEBAND, 1, 0);
402 rebuild_rebar(&hRebar);
403 add_band_w(hRebar, "ABC", 70, 40, 100);
404 add_band_w(hRebar, NULL, 40, 70, 100);
405 add_band_w(hRebar, NULL, 170, 240, 100);
406 add_band_w(hRebar, "MMMMMMM", 60, 60, 100);
407 add_band_w(hRebar, NULL, 200, 200, 100);
409 SendMessageA(hRebar, RB_MAXIMIZEBAND, 1, TRUE);
411 SendMessageA(hRebar, RB_MAXIMIZEBAND, 1, TRUE);
413 SendMessageA(hRebar, RB_MAXIMIZEBAND, 2, FALSE);
415 SendMessageA(hRebar, RB_MINIMIZEBAND, 2, 0);
417 SendMessageA(hRebar, RB_MINIMIZEBAND, 0, 0);
420 /* an image will increase the band height */
421 himl = ImageList_LoadImage(LoadLibrary("comctl32"), MAKEINTRESOURCE(121), 24, 2, CLR_NONE, IMAGE_BITMAP, LR_DEFAULTCOLOR);
422 ri.cbSize = sizeof(ri);
423 ri.fMask = RBIM_IMAGELIST;
425 ok(SendMessage(hRebar, RB_SETBARINFO, 0, (LPARAM)&ri), "RB_SETBARINFO failed\n");
426 rbi.fMask = RBBIM_IMAGE;
428 SendMessage(hRebar, RB_SETBANDINFO, 1, (LPARAM)&rbi);
431 /* VARHEIGHT resizing test on a horizontal rebar */
432 rebuild_rebar(&hRebar);
433 SetWindowLong(hRebar, GWL_STYLE, GetWindowLong(hRebar, GWL_STYLE) | RBS_AUTOSIZE);
435 rbi.fMask = RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_SIZE | RBBIM_STYLE;
436 rbi.fStyle = RBBS_VARIABLEHEIGHT;
441 rbi.cyMaxChild = 200;
443 rbi.hwndChild = build_toolbar(0, hRebar);
444 SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
447 rbi.hwndChild = build_toolbar(0, hRebar);
448 SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
453 rbi.hwndChild = build_toolbar(0, hRebar);
454 SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
457 /* VARHEIGHT resizing on a vertical rebar */
458 rebuild_rebar(&hRebar);
459 SetWindowLong(hRebar, GWL_STYLE, GetWindowLong(hRebar, GWL_STYLE) | CCS_VERT | RBS_AUTOSIZE);
461 rbi.fMask = RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_SIZE | RBBIM_STYLE;
462 rbi.fStyle = RBBS_VARIABLEHEIGHT;
469 rbi.hwndChild = build_toolbar(0, hRebar);
470 SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
474 rbi.hwndChild = build_toolbar(0, hRebar);
475 SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
481 rbi.hwndChild = build_toolbar(0, hRebar);
482 SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
485 DestroyWindow(hRebar);
488 #if 0 /* use this to generate more tests */
490 static void dump_client(HWND hRebar)
494 GetWindowRect(hRebar, &r);
495 MapWindowPoints(HWND_DESKTOP, hMainWnd, (LPPOINT)&r, 2);
496 if (height_change_notify_rect.top != -1)
499 GetClientRect(hRebar, &rcClient);
500 assert(EqualRect(&rcClient, &height_change_notify_rect));
505 printf(" {{%d, %d, %d, %d}, %d, %s},\n", r.left, r.top, r.right, r.bottom, SendMessage(hRebar, RB_GETROWCOUNT, 0, 0),
506 notify ? "TRUE" : "FALSE");
507 SetRect(&height_change_notify_rect, -1, -1, -1, -1);
510 #define comment(fmt, arg1) printf("/* " fmt " */\n", arg1);
511 #define check_client() dump_client(hRebar)
519 } rbresize_test_result_t;
521 rbresize_test_result_t resize_results[] = {
523 {{0, 2, 672, 2}, 0, FALSE},
524 {{0, 2, 672, 22}, 1, TRUE},
525 {{0, 2, 672, 22}, 1, FALSE},
526 {{0, 2, 672, 22}, 1, FALSE},
527 {{0, 2, 672, 22}, 1, FALSE},
528 {{0, 2, 672, 22}, 0, FALSE},
530 {{0, 0, 672, 0}, 0, FALSE},
531 {{0, 0, 672, 20}, 1, TRUE},
532 {{0, 0, 672, 20}, 1, FALSE},
533 {{0, 0, 672, 20}, 1, FALSE},
534 {{0, 0, 672, 20}, 1, FALSE},
535 {{0, 0, 672, 20}, 0, FALSE},
537 {{0, 226, 672, 226}, 0, FALSE},
538 {{0, 206, 672, 226}, 1, TRUE},
539 {{0, 206, 672, 226}, 1, FALSE},
540 {{0, 206, 672, 226}, 1, FALSE},
541 {{0, 206, 672, 226}, 1, FALSE},
542 {{0, 206, 672, 226}, 0, FALSE},
544 {{0, 226, 672, 226}, 0, FALSE},
545 {{0, 206, 672, 226}, 1, TRUE},
546 {{0, 206, 672, 226}, 1, FALSE},
547 {{0, 206, 672, 226}, 1, FALSE},
548 {{0, 206, 672, 226}, 1, FALSE},
549 {{0, 206, 672, 226}, 0, FALSE},
551 {{2, 0, 2, 226}, 0, FALSE},
552 {{2, 0, 22, 226}, 1, TRUE},
553 {{2, 0, 22, 226}, 1, FALSE},
554 {{2, 0, 22, 226}, 1, FALSE},
555 {{2, 0, 22, 226}, 1, FALSE},
556 {{2, 0, 22, 226}, 0, FALSE},
558 {{672, 0, 672, 226}, 0, FALSE},
559 {{652, 0, 672, 226}, 1, TRUE},
560 {{652, 0, 672, 226}, 1, FALSE},
561 {{652, 0, 672, 226}, 1, FALSE},
562 {{652, 0, 672, 226}, 1, FALSE},
563 {{652, 0, 672, 226}, 0, FALSE},
565 {{10, 11, 510, 11}, 0, FALSE},
566 {{10, 15, 510, 35}, 1, TRUE},
567 {{10, 17, 510, 37}, 1, FALSE},
568 {{10, 14, 110, 54}, 2, TRUE},
569 {{0, 4, 0, 44}, 2, FALSE},
570 {{0, 6, 0, 46}, 2, FALSE},
571 {{0, 8, 0, 48}, 2, FALSE},
572 {{0, 12, 0, 32}, 1, TRUE},
573 {{0, 4, 100, 24}, 0, FALSE},
575 {{10, 5, 510, 5}, 0, FALSE},
576 {{10, 5, 510, 25}, 1, TRUE},
577 {{10, 5, 510, 25}, 1, FALSE},
578 {{10, 10, 110, 50}, 2, TRUE},
579 {{0, 0, 0, 40}, 2, FALSE},
580 {{0, 0, 0, 40}, 2, FALSE},
581 {{0, 0, 0, 40}, 2, FALSE},
582 {{0, 0, 0, 20}, 1, TRUE},
583 {{0, 0, 100, 20}, 0, FALSE},
585 {{10, 5, 510, 20}, 0, FALSE},
586 {{10, 5, 510, 20}, 1, TRUE},
587 {{10, 10, 110, 110}, 2, TRUE},
588 {{0, 0, 0, 0}, 2, FALSE},
589 {{0, 0, 0, 0}, 2, FALSE},
590 {{0, 0, 0, 0}, 2, FALSE},
591 {{0, 0, 0, 0}, 1, TRUE},
592 {{0, 0, 100, 100}, 0, FALSE},
594 {{0, 5, 672, 5}, 0, FALSE},
595 {{0, 5, 672, 25}, 1, TRUE},
596 {{0, 10, 672, 30}, 1, FALSE},
597 {{0, 0, 672, 20}, 1, FALSE},
598 {{0, 0, 672, 20}, 1, FALSE},
599 {{0, 0, 672, 20}, 0, FALSE},
601 {{10, 0, 10, 226}, 0, FALSE},
602 {{10, 0, 30, 226}, 1, TRUE},
603 {{10, 0, 30, 226}, 1, FALSE},
604 {{0, 0, 20, 226}, 1, FALSE},
605 {{0, 0, 20, 226}, 1, FALSE},
606 {{0, 0, 20, 226}, 0, FALSE},
608 {{-2, 0, 674, 4}, 0, FALSE},
609 {{-2, 0, 674, 24}, 1, TRUE},
610 {{-2, 0, 674, 24}, 1, FALSE},
611 {{-2, 0, 674, 24}, 1, FALSE},
612 {{-2, 0, 674, 24}, 1, FALSE},
613 {{-2, 0, 674, 24}, 0, FALSE},
615 {{10, 5, 510, 9}, 0, FALSE},
616 {{10, 5, 510, 29}, 1, TRUE},
617 {{10, 5, 510, 29}, 1, FALSE},
618 {{10, 10, 110, 54}, 2, TRUE},
619 {{0, 0, 0, 44}, 2, FALSE},
620 {{0, 0, 0, 44}, 2, FALSE},
621 {{0, 0, 0, 44}, 2, FALSE},
622 {{0, 0, 0, 24}, 1, TRUE},
623 {{0, 0, 100, 24}, 0, FALSE},
625 {{10, 5, 510, 20}, 0, FALSE},
626 {{10, 5, 510, 20}, 1, TRUE},
627 {{10, 10, 110, 110}, 2, TRUE},
628 {{0, 0, 0, 0}, 2, FALSE},
629 {{0, 0, 0, 0}, 2, FALSE},
630 {{0, 0, 0, 0}, 2, FALSE},
631 {{0, 0, 0, 0}, 1, TRUE},
632 {{0, 0, 100, 100}, 0, FALSE},
634 {{-2, 5, 674, 9}, 0, FALSE},
635 {{-2, 5, 674, 29}, 1, TRUE},
636 {{-2, 10, 674, 34}, 1, FALSE},
637 {{-2, 0, 674, 24}, 1, FALSE},
638 {{-2, 0, 674, 24}, 1, FALSE},
639 {{-2, 0, 674, 24}, 0, FALSE},
642 static int resize_numtests = 0;
644 #define comment(fmt, arg1)
645 #define check_client() { \
647 rbresize_test_result_t *res = &resize_results[resize_numtests++]; \
648 assert(resize_numtests <= sizeof(resize_results)/sizeof(resize_results[0])); \
649 GetWindowRect(hRebar, &r); \
650 MapWindowPoints(HWND_DESKTOP, hMainWnd, (LPPOINT)&r, 2); \
651 if ((dwStyles[i] & (CCS_NOPARENTALIGN|CCS_NODIVIDER)) == CCS_NOPARENTALIGN) {\
652 check_rect_no_top("client", r, res->rc); /* the top coordinate changes after every layout and is very implementation-dependent */ \
654 check_rect("client", r, res->rc); \
656 expect_eq((int)SendMessage(hRebar, RB_GETROWCOUNT, 0, 0), res->iNumRows, int, "%d"); \
657 if (res->heightNotify) { \
659 GetClientRect(hRebar, &rcClient); \
660 check_rect("notify", height_change_notify_rect, rcClient); \
661 } else ok(height_change_notify_rect.top == -1, "Unexpected RBN_HEIGHTCHANGE received\n"); \
662 SetRect(&height_change_notify_rect, -1, -1, -1, -1); \
667 static void resize_test(void)
669 DWORD dwStyles[] = {CCS_TOP, CCS_TOP | CCS_NODIVIDER, CCS_BOTTOM, CCS_BOTTOM | CCS_NODIVIDER, CCS_VERT, CCS_RIGHT,
670 CCS_NOPARENTALIGN, CCS_NOPARENTALIGN | CCS_NODIVIDER, CCS_NORESIZE, CCS_NOMOVEY, CCS_NOMOVEY | CCS_VERT,
671 CCS_TOP | WS_BORDER, CCS_NOPARENTALIGN | CCS_NODIVIDER | WS_BORDER, CCS_NORESIZE | WS_BORDER,
672 CCS_NOMOVEY | WS_BORDER};
674 const int styles_count = sizeof(dwStyles) / sizeof(dwStyles[0]);
677 for (i = 0; i < styles_count; i++)
679 comment("style %08x", dwStyles[i]);
680 SetRect(&height_change_notify_rect, -1, -1, -1, -1);
681 hRebar = CreateWindow(REBARCLASSNAME, "A", dwStyles[i] | WS_CHILD | WS_VISIBLE, 10, 5, 500, 15, hMainWnd, NULL, GetModuleHandle(NULL), 0);
683 add_band_w(hRebar, NULL, 70, 100, 0);
684 if (dwStyles[i] & CCS_NOPARENTALIGN) /* the window drifts downward for CCS_NOPARENTALIGN without CCS_NODIVIDER */
686 add_band_w(hRebar, NULL, 70, 100, 0);
688 MoveWindow(hRebar, 10, 10, 100, 100, TRUE);
690 MoveWindow(hRebar, 0, 0, 0, 0, TRUE);
692 /* try to fool the rebar by sending invalid width/height - won't work */
693 if (dwStyles[i] & (CCS_NORESIZE | CCS_NOPARENTALIGN))
697 pos.hwndInsertAfter = NULL;
703 SendMessage(hRebar, WM_WINDOWPOSCHANGING, 0, (LPARAM)&pos);
704 SendMessage(hRebar, WM_WINDOWPOSCHANGED, 0, (LPARAM)&pos);
706 SendMessage(hRebar, WM_SIZE, SIZE_RESTORED, MAKELONG(500, 500));
709 SendMessage(hRebar, RB_DELETEBAND, 0, 0);
711 SendMessage(hRebar, RB_DELETEBAND, 0, 0);
712 MoveWindow(hRebar, 0, 0, 100, 100, TRUE);
714 DestroyWindow(hRebar);
718 static void expect_band_content(UINT uBand, INT fStyle, COLORREF clrFore,
719 COLORREF clrBack, LPCSTR lpText, int iImage, HWND hwndChild,
720 INT cxMinChild, INT cyMinChild, INT cx, HBITMAP hbmBack, INT wID,
721 INT cyChild, INT cyMaxChild, INT cyIntegral, INT cxIdeal, LPARAM lParam,
724 CHAR buf[MAX_PATH] = "abc";
727 memset(&rb, 0xdd, sizeof(rb));
728 rb.cbSize = sizeof(rb);
729 rb.fMask = RBBIM_BACKGROUND | RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_COLORS
730 | RBBIM_HEADERSIZE | RBBIM_ID | RBBIM_IDEALSIZE | RBBIM_IMAGE | RBBIM_LPARAM
731 | RBBIM_SIZE | RBBIM_STYLE | RBBIM_TEXT;
734 ok(SendMessageA(hRebar, RB_GETBANDINFOA, uBand, (LPARAM)&rb), "RB_GETBANDINFO failed\n");
735 expect_eq(rb.fStyle, fStyle, int, "%x");
736 todo_wine expect_eq(rb.clrFore, clrFore, COLORREF, "%x");
737 todo_wine expect_eq(rb.clrBack, clrBack, unsigned, "%x");
738 expect_eq(strcmp(rb.lpText, lpText), 0, int, "%d");
739 expect_eq(rb.iImage, iImage, int, "%x");
740 expect_eq(rb.hwndChild, hwndChild, HWND, "%p");
741 expect_eq(rb.cxMinChild, cxMinChild, int, "%d");
742 expect_eq(rb.cyMinChild, cyMinChild, int, "%d");
743 expect_eq(rb.cx, cx, int, "%d");
744 expect_eq(rb.hbmBack, hbmBack, HBITMAP, "%p");
745 expect_eq(rb.wID, wID, int, "%d");
746 /* the values of cyChild, cyMaxChild and cyIntegral can't be read unless the band is RBBS_VARIABLEHEIGHT */
747 expect_eq(rb.cyChild, cyChild, int, "%x");
748 expect_eq(rb.cyMaxChild, cyMaxChild, int, "%x");
749 expect_eq(rb.cyIntegral, cyIntegral, int, "%x");
750 expect_eq(rb.cxIdeal, cxIdeal, int, "%d");
751 expect_eq(rb.lParam, lParam, LPARAM, "%ld");
752 expect_eq(rb.cxHeader, cxHeader, int, "%d");
755 static void bandinfo_test(void)
758 CHAR szABC[] = "ABC";
759 CHAR szABCD[] = "ABCD";
761 rebuild_rebar(&hRebar);
762 rb.cbSize = sizeof(REBARBANDINFO);
764 ok(SendMessageA(hRebar, RB_INSERTBANDA, 0, (LPARAM)&rb), "RB_INSERTBAND failed\n");
765 expect_band_content(0, 0, 0, GetSysColor(COLOR_3DFACE), "", -1, NULL, 0, 0, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 0);
767 rb.fMask = RBBIM_CHILDSIZE;
773 ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_INSERTBAND failed\n");
774 expect_band_content(0, 0, 0, GetSysColor(COLOR_3DFACE), "", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 0);
776 rb.fMask = RBBIM_TEXT;
778 ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_INSERTBAND failed\n");
779 expect_band_content(0, 0, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 35);
781 rb.cbSize = sizeof(REBARBANDINFO);
783 ok(SendMessageA(hRebar, RB_INSERTBANDA, 1, (LPARAM)&rb), "RB_INSERTBAND failed\n");
784 expect_band_content(1, 0, 0, GetSysColor(COLOR_3DFACE), "", -1, NULL, 0, 0, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 9);
785 expect_band_content(0, 0, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 40);
787 rb.fMask = RBBIM_HEADERSIZE;
789 ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_INSERTBAND failed\n");
790 expect_band_content(0, 0x40000000, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 50);
793 ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_INSERTBAND failed\n");
794 expect_band_content(0, 0x40000000, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 5);
796 rb.fMask = RBBIM_TEXT;
798 ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_INSERTBAND failed\n");
799 expect_band_content(0, 0x40000000, 0, GetSysColor(COLOR_3DFACE), "ABCD", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 5);
800 rb.fMask = RBBIM_STYLE | RBBIM_TEXT;
801 rb.fStyle = RBBS_VARIABLEHEIGHT;
803 ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_INSERTBAND failed\n");
804 expect_band_content(0, RBBS_VARIABLEHEIGHT, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 20, 0x7fffffff, 0, 0, 0, 40);
806 DestroyWindow(hRebar);
812 BOOL (WINAPI *pInitCommonControlsEx)(const INITCOMMONCONTROLSEX*);
813 INITCOMMONCONTROLSEX iccex;
818 hComctl32 = LoadLibraryA("comctl32.dll");
819 pInitCommonControlsEx = (void*)GetProcAddress(hComctl32, "InitCommonControlsEx");
820 if (!pInitCommonControlsEx)
822 skip("InitCommonControlsEx() is missing. Skipping the tests\n");
825 iccex.dwSize = sizeof(iccex);
826 iccex.dwICC = ICC_COOL_CLASSES;
827 pInitCommonControlsEx(&iccex);
829 wc.style = CS_HREDRAW | CS_VREDRAW;
832 wc.hInstance = GetModuleHandleA(NULL);
834 wc.hCursor = LoadCursorA(NULL, IDC_IBEAM);
835 wc.hbrBackground = GetSysColorBrush(COLOR_WINDOW);
836 wc.lpszMenuName = NULL;
837 wc.lpszClassName = "MyTestWnd";
838 wc.lpfnWndProc = MyWndProc;
840 hMainWnd = CreateWindowExA(0, "MyTestWnd", "Blah", WS_OVERLAPPEDWINDOW,
841 CW_USEDEFAULT, CW_USEDEFAULT, 672+2*GetSystemMetrics(SM_CXSIZEFRAME),
842 226+GetSystemMetrics(SM_CYCAPTION)+2*GetSystemMetrics(SM_CYSIZEFRAME),
843 NULL, NULL, GetModuleHandleA(NULL), 0);
844 GetClientRect(hMainWnd, &rc);
845 ShowWindow(hMainWnd, SW_SHOW);
849 if(is_font_installed("System") && is_font_installed("Tahoma"))
854 skip("Missing System or Tahoma font\n");
857 while(GetMessageA(&msg,0,0,0)) {
858 TranslateMessage(&msg);
859 DispatchMessageA(&msg);
861 DestroyWindow(hMainWnd);