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
27 #include "wine/test.h"
29 RECT height_change_notify_rect;
34 #define check_rect(name, val, exp) ok(val.top == exp.top && val.bottom == exp.bottom && \
35 val.left == exp.left && val.right == exp.right, "invalid rect (" name ") (%d,%d) (%d,%d) - expected (%d,%d) (%d,%d)\n", \
36 val.left, val.top, val.right, val.bottom, exp.left, exp.top, exp.right, exp.bottom);
38 #define check_rect_no_top(name, val, exp) { \
39 ok((val.bottom - val.top == exp.bottom - exp.top) && \
40 val.left == exp.left && val.right == exp.right, "invalid rect (" name ") (%d,%d) (%d,%d) - expected (%d,%d) (%d,%d), ignoring top\n", \
41 val.left, val.top, val.right, val.bottom, exp.left, exp.top, exp.right, exp.bottom); \
44 #define compare(val, exp, format) ok((val) == (exp), #val " value " format " expected " format "\n", (val), (exp));
46 #define expect_eq(expr, value, type, format) { type ret = expr; ok((value) == ret, #expr " expected " format " got " format "\n", (value), (ret)); }
48 static INT CALLBACK is_font_installed_proc(const LOGFONT *elf, const TEXTMETRIC *ntm, DWORD type, LPARAM lParam)
53 static BOOL is_font_installed(const char *name)
58 if(!EnumFontFamiliesA(hdc, name, is_font_installed_proc, 0))
65 static void rebuild_rebar(HWND *hRebar)
68 DestroyWindow(*hRebar);
70 *hRebar = CreateWindow(REBARCLASSNAME, NULL, WS_CHILD | WS_VISIBLE, 0, 0, 0, 0,
71 hMainWnd, (HMENU)17, GetModuleHandle(NULL), NULL);
72 SendMessageA(*hRebar, WM_SETFONT, (WPARAM)GetStockObject(SYSTEM_FONT), 0);
75 static HWND build_toolbar(int nr, HWND hParent)
78 HWND hToolbar = CreateWindowEx(0, TOOLBARCLASSNAME, NULL, WS_CHILD | WS_VISIBLE | CCS_NORESIZE, 0, 0, 0, 0,
79 hParent, (HMENU)5, GetModuleHandle(NULL), NULL);
83 ok(hToolbar != NULL, "Toolbar creation problem\n");
84 ok(SendMessage(hToolbar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0) == 0, "TB_BUTTONSTRUCTSIZE failed\n");
85 ok(SendMessage(hToolbar, TB_AUTOSIZE, 0, 0) == 0, "TB_AUTOSIZE failed\n");
86 ok(SendMessage(hToolbar, WM_SETFONT, (WPARAM)GetStockObject(SYSTEM_FONT), 0)==1, "WM_SETFONT\n");
88 for (i=0; i<5+nr; i++)
91 btns[i].idCommand = i;
92 btns[i].fsStyle = BTNS_BUTTON;
93 btns[i].fsState = TBSTATE_ENABLED;
99 case 0: iBitmapId = IDB_HIST_SMALL_COLOR; break;
100 case 1: iBitmapId = IDB_VIEW_SMALL_COLOR; break;
101 case 2: iBitmapId = IDB_STD_SMALL_COLOR; break;
103 ok(SendMessage(hToolbar, TB_LOADIMAGES, iBitmapId, (LPARAM)HINST_COMMCTRL) == 0, "TB_LOADIMAGE failed\n");
104 ok(SendMessage(hToolbar, TB_ADDBUTTONS, 5+nr, (LPARAM)btns), "TB_ADDBUTTONS failed\n");
108 static LRESULT CALLBACK MyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
114 NMHDR *lpnm = (NMHDR *)lParam;
115 if (lpnm->code == RBN_HEIGHTCHANGE)
116 GetClientRect(hRebar, &height_change_notify_rect);
120 return DefWindowProcA(hWnd, msg, wParam, lParam);
123 #if 0 /* use this to generate more tests*/
125 static void dump_sizes(HWND hRebar)
132 GetClientRect(hRebar, &r);
133 count = SendMessageA(hRebar, RB_GETROWCOUNT, 0, 0);
134 printf(" { {%d, %d, %d, %d}, %d, %d, {", r.left, r.top, r.right, r.bottom,
135 SendMessageA(hRebar, RB_GETBARHEIGHT, 0, 0), count);
138 for (i = 0; i < count; i++) /* rows */
139 printf("%d, ", SendMessageA(hRebar, RB_GETROWHEIGHT, i, 0));
142 count = SendMessageA(hRebar, RB_GETBANDCOUNT, 0, 0);
143 printf("%d, {", count);
145 printf("{{0, 0, 0, 0}, 0, 0},");
146 for (i=0; i<count; i++)
149 rbi.cbSize = sizeof(REBARBANDINFO);
150 rbi.fMask = RBBIM_SIZE | RBBIM_CHILDSIZE | RBBIM_STYLE;
151 ok(SendMessageA(hRebar, RB_GETBANDINFOA, i, (LPARAM)&rbi), "RB_GETBANDINFO failed\n");
152 ok(SendMessageA(hRebar, RB_GETRECT, i, (LPARAM)&r), "RB_GETRECT failed\n");
153 printf("%s{ {%3d, %3d, %3d, %3d}, 0x%02x, %d}, ", (i%2==0 ? "\n " : ""), r.left, r.top, r.right, r.bottom,
156 printf("\n }, }, \n");
159 #define check_sizes() dump_sizes(hRebar);
160 #define check_sizes_todo(todomask) dump_sizes(hRebar);
174 int cyRowHeights[50];
176 rbband_result_t bands[50];
179 rbsize_result_t rbsize_results[] = {
180 { {0, 0, 672, 0}, 0, 0, {0, }, 0, {{{0, 0, 0, 0}, 0, 0},
182 { {0, 0, 672, 4}, 4, 1, {4, }, 1, {
183 { { 0, 0, 672, 4}, 0x00, 200},
185 { {0, 0, 672, 4}, 4, 1, {4, }, 2, {
186 { { 0, 0, 200, 4}, 0x00, 200}, { {200, 0, 672, 4}, 0x04, 200},
188 { {0, 0, 672, 30}, 30, 1, {30, }, 3, {
189 { { 0, 0, 200, 30}, 0x00, 200}, { {200, 0, 400, 30}, 0x04, 200},
190 { {400, 0, 672, 30}, 0x00, 200},
192 { {0, 0, 672, 34}, 34, 1, {34, }, 4, {
193 { { 0, 0, 200, 34}, 0x00, 200}, { {200, 0, 400, 34}, 0x04, 200},
194 { {400, 0, 604, 34}, 0x00, 200}, { {604, 0, 672, 34}, 0x04, 68},
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}, { {202, 0, 402, 34}, 0x04, 200},
202 { {404, 0, 604, 34}, 0x00, 200}, { {606, 0, 672, 34}, 0x04, 66},
204 { {0, 0, 672, 70}, 70, 2, {34, 34, }, 5, {
205 { { 0, 0, 142, 34}, 0x00, 200}, { {144, 0, 557, 34}, 0x00, 200},
206 { {559, 0, 672, 34}, 0x04, 200}, { { 0, 36, 200, 70}, 0x00, 200},
207 { {202, 36, 672, 70}, 0x04, 66},
209 { {0, 0, 672, 34}, 34, 1, {34, }, 5, {
210 { { 0, 0, 167, 34}, 0x00, 200}, { {169, 0, 582, 34}, 0x00, 200},
211 { {559, 0, 759, 34}, 0x08, 200}, { {584, 0, 627, 34}, 0x00, 200},
212 { {629, 0, 672, 34}, 0x04, 66},
214 { {0, 0, 672, 34}, 34, 1, {34, }, 4, {
215 { { 0, 0, 167, 34}, 0x00, 200}, { {169, 0, 582, 34}, 0x00, 200},
216 { {584, 0, 627, 34}, 0x00, 200}, { {629, 0, 672, 34}, 0x04, 66},
218 { {0, 0, 672, 34}, 34, 1, {34, }, 3, {
219 { { 0, 0, 413, 34}, 0x00, 200}, { {415, 0, 615, 34}, 0x00, 200},
220 { {617, 0, 672, 34}, 0x04, 66},
222 { {0, 0, 672, 34}, 34, 1, {34, }, 2, {
223 { { 0, 0, 604, 34}, 0x00, 200}, { {606, 0, 672, 34}, 0x04, 66},
225 { {0, 0, 672, 40}, 40, 2, {20, 20, }, 5, {
226 { { 0, 0, 114, 20}, 0x00, 40}, { {114, 0, 184, 20}, 0x00, 70},
227 { {184, 0, 424, 20}, 0x00, 240}, { {424, 0, 672, 20}, 0x00, 60},
228 { { 0, 20, 672, 40}, 0x00, 200},
230 { {0, 0, 672, 40}, 40, 2, {20, 20, }, 5, {
231 { { 0, 0, 114, 20}, 0x00, 40}, { {114, 0, 227, 20}, 0x00, 113},
232 { {227, 0, 424, 20}, 0x00, 197}, { {424, 0, 672, 20}, 0x00, 60},
233 { { 0, 20, 672, 40}, 0x00, 200},
235 { {0, 0, 672, 40}, 40, 2, {20, 20, }, 5, {
236 { { 0, 0, 114, 20}, 0x00, 40}, { {114, 0, 328, 20}, 0x00, 214},
237 { {328, 0, 511, 20}, 0x00, 183}, { {511, 0, 672, 20}, 0x00, 161},
238 { { 0, 20, 672, 40}, 0x00, 200},
240 { {0, 0, 672, 40}, 40, 2, {20, 20, }, 5, {
241 { { 0, 0, 114, 20}, 0x00, 40}, { {114, 0, 167, 20}, 0x00, 53},
242 { {167, 0, 511, 20}, 0x00, 344}, { {511, 0, 672, 20}, 0x00, 161},
243 { { 0, 20, 672, 40}, 0x00, 200},
245 { {0, 0, 672, 40}, 40, 2, {20, 20, }, 5, {
246 { { 0, 0, 114, 20}, 0x00, 40}, { {114, 0, 328, 20}, 0x00, 214},
247 { {328, 0, 511, 20}, 0x00, 183}, { {511, 0, 672, 20}, 0x00, 161},
248 { { 0, 20, 672, 40}, 0x00, 200},
250 { {0, 0, 672, 40}, 40, 2, {20, 20, }, 5, {
251 { { 0, 0, 114, 20}, 0x00, 40}, { {114, 0, 328, 20}, 0x00, 214},
252 { {328, 0, 511, 20}, 0x00, 183}, { {511, 0, 672, 20}, 0x00, 161},
253 { { 0, 20, 672, 40}, 0x00, 200},
255 { {0, 0, 672, 0}, 0, 0, {0, }, 0, {{{0, 0, 0, 0}, 0, 0},
257 { {0, 0, 672, 65}, 65, 1, {65, }, 3, {
258 { { 0, 0, 90, 65}, 0x40, 90}, { { 90, 0, 180, 65}, 0x40, 90},
259 { {180, 0, 672, 65}, 0x40, 90},
261 { {0, 0, 0, 226}, 0, 0, {0, }, 0, {{{0, 0, 0, 0}, 0, 0},
263 { {0, 0, 65, 226}, 65, 1, {65, }, 1, {
264 { { 0, 0, 226, 65}, 0x40, 90},
266 { {0, 0, 65, 226}, 65, 1, {65, }, 2, {
267 { { 0, 0, 90, 65}, 0x40, 90}, { { 90, 0, 226, 65}, 0x40, 90},
269 { {0, 0, 65, 226}, 65, 1, {65, }, 3, {
270 { { 0, 0, 90, 65}, 0x40, 90}, { { 90, 0, 163, 65}, 0x40, 90},
271 { {163, 0, 226, 65}, 0x40, 90},
275 static int rbsize_numtests = 0;
277 #define check_sizes_todo(todomask) { \
280 int count, i/*, mask=(todomask)*/; \
281 rbsize_result_t *res = &rbsize_results[rbsize_numtests]; \
282 assert(rbsize_numtests < sizeof(rbsize_results)/sizeof(rbsize_results[0])); \
283 GetClientRect(hRebar, &rc); \
284 check_rect("client", rc, res->rcClient); \
285 count = SendMessage(hRebar, RB_GETROWCOUNT, 0, 0); \
286 compare(count, res->nRows, "%d"); \
287 for (i=0; i<min(count, res->nRows); i++) { \
288 int height = SendMessageA(hRebar, RB_GETROWHEIGHT, 0, 0);\
289 ok(height == res->cyRowHeights[i], "Height mismatch for row %d - %d vs %d\n", i, res->cyRowHeights[i], height); \
291 count = SendMessage(hRebar, RB_GETBANDCOUNT, 0, 0); \
292 compare(count, res->nBands, "%d"); \
293 for (i=0; i<min(count, res->nBands); i++) { \
294 ok(SendMessageA(hRebar, RB_GETRECT, i, (LPARAM)&rc) == 1, "RB_ITEMRECT\n"); \
295 if (!(res->bands[i].fStyle & RBBS_HIDDEN)) \
296 check_rect("band", rc, res->bands[i].rc); \
297 rbi.cbSize = sizeof(REBARBANDINFO); \
298 rbi.fMask = RBBIM_STYLE | RBBIM_SIZE; \
299 ok(SendMessageA(hRebar, RB_GETBANDINFO, i, (LPARAM)&rbi) == 1, "RB_GETBANDINFO\n"); \
300 compare(rbi.fStyle, res->bands[i].fStyle, "%x"); \
301 compare(rbi.cx, res->bands[i].cx, "%d"); \
306 #define check_sizes() check_sizes_todo(0)
310 static void add_band_w(HWND hRebar, LPCSTR lpszText, int cxMinChild, int cx, int cxIdeal)
312 CHAR buffer[MAX_PATH];
315 if (lpszText != NULL)
316 strcpy(buffer, lpszText);
317 rbi.cbSize = sizeof(rbi);
318 rbi.fMask = RBBIM_SIZE | RBBIM_CHILDSIZE | RBBIM_CHILD | RBBIM_IDEALSIZE | RBBIM_TEXT;
320 rbi.cxMinChild = cxMinChild;
321 rbi.cxIdeal = cxIdeal;
323 rbi.hwndChild = build_toolbar(1, hRebar);
324 rbi.lpText = (lpszText ? buffer : NULL);
325 SendMessage(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
328 static void layout_test(void)
333 rebuild_rebar(&hRebar);
335 rbi.cbSize = sizeof(rbi);
336 rbi.fMask = RBBIM_SIZE | RBBIM_CHILDSIZE | RBBIM_CHILD;
338 rbi.cxMinChild = 100;
340 rbi.hwndChild = NULL;
341 SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
344 rbi.fMask |= RBBIM_STYLE;
345 rbi.fStyle = RBBS_CHILDEDGE;
346 SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
353 rbi.hwndChild = build_toolbar(0, hRebar);
354 SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
357 rbi.fStyle = RBBS_CHILDEDGE;
359 rbi.hwndChild = build_toolbar(0, hRebar);
360 SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
363 SetWindowLong(hRebar, GWL_STYLE, GetWindowLong(hRebar, GWL_STYLE) | RBS_BANDBORDERS);
364 check_sizes(); /* a style change won't start a relayout */
365 rbi.fMask = RBBIM_SIZE;
367 SendMessageA(hRebar, RB_SETBANDINFO, 3, (LPARAM)&rbi);
368 check_sizes(); /* here it will be relayouted */
370 /* this will force a new row */
371 rbi.fMask = RBBIM_SIZE | RBBIM_CHILDSIZE | RBBIM_CHILD;
373 rbi.cxMinChild = 400;
375 rbi.hwndChild = build_toolbar(0, hRebar);
376 SendMessageA(hRebar, RB_INSERTBAND, 1, (LPARAM)&rbi);
379 rbi.fMask = RBBIM_STYLE;
380 rbi.fStyle = RBBS_HIDDEN;
381 SendMessageA(hRebar, RB_SETBANDINFO, 2, (LPARAM)&rbi);
384 SendMessageA(hRebar, RB_DELETEBAND, 2, 0);
386 SendMessageA(hRebar, RB_DELETEBAND, 0, 0);
388 SendMessageA(hRebar, RB_DELETEBAND, 1, 0);
391 rebuild_rebar(&hRebar);
392 add_band_w(hRebar, "ABC", 70, 40, 100);
393 add_band_w(hRebar, NULL, 40, 70, 100);
394 add_band_w(hRebar, NULL, 170, 240, 100);
395 add_band_w(hRebar, "MMMMMMM", 60, 60, 100);
396 add_band_w(hRebar, NULL, 200, 200, 100);
398 SendMessageA(hRebar, RB_MAXIMIZEBAND, 1, TRUE);
400 SendMessageA(hRebar, RB_MAXIMIZEBAND, 1, TRUE);
402 SendMessageA(hRebar, RB_MAXIMIZEBAND, 2, FALSE);
404 SendMessageA(hRebar, RB_MINIMIZEBAND, 2, 0);
406 SendMessageA(hRebar, RB_MINIMIZEBAND, 0, 0);
409 /* VARHEIGHT resizing test on a horizontal rebar */
410 rebuild_rebar(&hRebar);
411 SetWindowLong(hRebar, GWL_STYLE, GetWindowLong(hRebar, GWL_STYLE) | RBS_AUTOSIZE);
413 rbi.fMask = RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_SIZE | RBBIM_STYLE;
414 rbi.fStyle = RBBS_VARIABLEHEIGHT;
419 rbi.cyMaxChild = 200;
421 rbi.hwndChild = build_toolbar(0, hRebar);
422 SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
425 rbi.hwndChild = build_toolbar(0, hRebar);
426 SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
431 rbi.hwndChild = build_toolbar(0, hRebar);
432 SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
435 /* VARHEIGHT resizing on a vertical rebar */
436 rebuild_rebar(&hRebar);
437 SetWindowLong(hRebar, GWL_STYLE, GetWindowLong(hRebar, GWL_STYLE) | CCS_VERT | RBS_AUTOSIZE);
439 rbi.fMask = RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_SIZE | RBBIM_STYLE;
440 rbi.fStyle = RBBS_VARIABLEHEIGHT;
447 rbi.hwndChild = build_toolbar(0, hRebar);
448 SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
452 rbi.hwndChild = build_toolbar(0, hRebar);
453 SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
459 rbi.hwndChild = build_toolbar(0, hRebar);
460 SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
463 DestroyWindow(hRebar);
466 #if 0 /* use this to generate more tests */
468 static void dump_client(HWND hRebar)
472 GetWindowRect(hRebar, &r);
473 MapWindowPoints(HWND_DESKTOP, hMainWnd, (LPPOINT)&r, 2);
474 if (height_change_notify_rect.top != -1)
477 GetClientRect(hRebar, &rcClient);
478 assert(EqualRect(&rcClient, &height_change_notify_rect));
483 printf(" {{%d, %d, %d, %d}, %d, %s},\n", r.left, r.top, r.right, r.bottom, SendMessage(hRebar, RB_GETROWCOUNT, 0, 0),
484 notify ? "TRUE" : "FALSE");
485 SetRect(&height_change_notify_rect, -1, -1, -1, -1);
488 #define comment(fmt, arg1) printf("/* " fmt " */\n", arg1);
489 #define check_client() dump_client(hRebar)
497 } rbresize_test_result_t;
499 rbresize_test_result_t resize_results[] = {
501 {{0, 2, 672, 2}, 0, FALSE},
502 {{0, 2, 672, 22}, 1, TRUE},
503 {{0, 2, 672, 22}, 1, FALSE},
504 {{0, 2, 672, 22}, 1, FALSE},
505 {{0, 2, 672, 22}, 1, FALSE},
506 {{0, 2, 672, 22}, 0, FALSE},
508 {{0, 0, 672, 0}, 0, FALSE},
509 {{0, 0, 672, 20}, 1, TRUE},
510 {{0, 0, 672, 20}, 1, FALSE},
511 {{0, 0, 672, 20}, 1, FALSE},
512 {{0, 0, 672, 20}, 1, FALSE},
513 {{0, 0, 672, 20}, 0, FALSE},
515 {{0, 226, 672, 226}, 0, FALSE},
516 {{0, 206, 672, 226}, 1, TRUE},
517 {{0, 206, 672, 226}, 1, FALSE},
518 {{0, 206, 672, 226}, 1, FALSE},
519 {{0, 206, 672, 226}, 1, FALSE},
520 {{0, 206, 672, 226}, 0, FALSE},
522 {{0, 226, 672, 226}, 0, FALSE},
523 {{0, 206, 672, 226}, 1, TRUE},
524 {{0, 206, 672, 226}, 1, FALSE},
525 {{0, 206, 672, 226}, 1, FALSE},
526 {{0, 206, 672, 226}, 1, FALSE},
527 {{0, 206, 672, 226}, 0, FALSE},
529 {{2, 0, 2, 226}, 0, FALSE},
530 {{2, 0, 22, 226}, 1, TRUE},
531 {{2, 0, 22, 226}, 1, FALSE},
532 {{2, 0, 22, 226}, 1, FALSE},
533 {{2, 0, 22, 226}, 1, FALSE},
534 {{2, 0, 22, 226}, 0, FALSE},
536 {{672, 0, 672, 226}, 0, FALSE},
537 {{652, 0, 672, 226}, 1, TRUE},
538 {{652, 0, 672, 226}, 1, FALSE},
539 {{652, 0, 672, 226}, 1, FALSE},
540 {{652, 0, 672, 226}, 1, FALSE},
541 {{652, 0, 672, 226}, 0, FALSE},
543 {{10, 11, 510, 11}, 0, FALSE},
544 {{10, 15, 510, 35}, 1, TRUE},
545 {{10, 17, 510, 37}, 1, FALSE},
546 {{10, 14, 110, 54}, 2, TRUE},
547 {{0, 4, 0, 44}, 2, FALSE},
548 {{0, 6, 0, 46}, 2, FALSE},
549 {{0, 8, 0, 48}, 2, FALSE},
550 {{0, 12, 0, 32}, 1, TRUE},
551 {{0, 4, 100, 24}, 0, FALSE},
553 {{10, 5, 510, 5}, 0, FALSE},
554 {{10, 5, 510, 25}, 1, TRUE},
555 {{10, 5, 510, 25}, 1, FALSE},
556 {{10, 10, 110, 50}, 2, TRUE},
557 {{0, 0, 0, 40}, 2, FALSE},
558 {{0, 0, 0, 40}, 2, FALSE},
559 {{0, 0, 0, 40}, 2, FALSE},
560 {{0, 0, 0, 20}, 1, TRUE},
561 {{0, 0, 100, 20}, 0, FALSE},
563 {{10, 5, 510, 20}, 0, FALSE},
564 {{10, 5, 510, 20}, 1, TRUE},
565 {{10, 10, 110, 110}, 2, TRUE},
566 {{0, 0, 0, 0}, 2, FALSE},
567 {{0, 0, 0, 0}, 2, FALSE},
568 {{0, 0, 0, 0}, 2, FALSE},
569 {{0, 0, 0, 0}, 1, TRUE},
570 {{0, 0, 100, 100}, 0, FALSE},
572 {{0, 5, 672, 5}, 0, FALSE},
573 {{0, 5, 672, 25}, 1, TRUE},
574 {{0, 10, 672, 30}, 1, FALSE},
575 {{0, 0, 672, 20}, 1, FALSE},
576 {{0, 0, 672, 20}, 1, FALSE},
577 {{0, 0, 672, 20}, 0, FALSE},
579 {{10, 0, 10, 226}, 0, FALSE},
580 {{10, 0, 30, 226}, 1, TRUE},
581 {{10, 0, 30, 226}, 1, FALSE},
582 {{0, 0, 20, 226}, 1, FALSE},
583 {{0, 0, 20, 226}, 1, FALSE},
584 {{0, 0, 20, 226}, 0, FALSE},
586 {{-2, 0, 674, 4}, 0, FALSE},
587 {{-2, 0, 674, 24}, 1, TRUE},
588 {{-2, 0, 674, 24}, 1, FALSE},
589 {{-2, 0, 674, 24}, 1, FALSE},
590 {{-2, 0, 674, 24}, 1, FALSE},
591 {{-2, 0, 674, 24}, 0, FALSE},
593 {{10, 5, 510, 9}, 0, FALSE},
594 {{10, 5, 510, 29}, 1, TRUE},
595 {{10, 5, 510, 29}, 1, FALSE},
596 {{10, 10, 110, 54}, 2, TRUE},
597 {{0, 0, 0, 44}, 2, FALSE},
598 {{0, 0, 0, 44}, 2, FALSE},
599 {{0, 0, 0, 44}, 2, FALSE},
600 {{0, 0, 0, 24}, 1, TRUE},
601 {{0, 0, 100, 24}, 0, FALSE},
603 {{10, 5, 510, 20}, 0, FALSE},
604 {{10, 5, 510, 20}, 1, TRUE},
605 {{10, 10, 110, 110}, 2, TRUE},
606 {{0, 0, 0, 0}, 2, FALSE},
607 {{0, 0, 0, 0}, 2, FALSE},
608 {{0, 0, 0, 0}, 2, FALSE},
609 {{0, 0, 0, 0}, 1, TRUE},
610 {{0, 0, 100, 100}, 0, FALSE},
612 {{-2, 5, 674, 9}, 0, FALSE},
613 {{-2, 5, 674, 29}, 1, TRUE},
614 {{-2, 10, 674, 34}, 1, FALSE},
615 {{-2, 0, 674, 24}, 1, FALSE},
616 {{-2, 0, 674, 24}, 1, FALSE},
617 {{-2, 0, 674, 24}, 0, FALSE},
620 static int resize_numtests = 0;
622 #define comment(fmt, arg1)
623 #define check_client() { \
625 rbresize_test_result_t *res = &resize_results[resize_numtests++]; \
626 assert(resize_numtests <= sizeof(resize_results)/sizeof(resize_results[0])); \
627 GetWindowRect(hRebar, &r); \
628 MapWindowPoints(HWND_DESKTOP, hMainWnd, (LPPOINT)&r, 2); \
629 if ((dwStyles[i] & (CCS_NOPARENTALIGN|CCS_NODIVIDER)) == CCS_NOPARENTALIGN) {\
630 check_rect_no_top("client", r, res->rc); /* the top coordinate changes after every layout and is very implementation-dependent */ \
632 check_rect("client", r, res->rc); \
634 expect_eq((int)SendMessage(hRebar, RB_GETROWCOUNT, 0, 0), res->iNumRows, int, "%d"); \
635 if (res->heightNotify) { \
637 GetClientRect(hRebar, &rcClient); \
638 check_rect("notify", height_change_notify_rect, rcClient); \
639 } else ok(height_change_notify_rect.top == -1, "Unexpected RBN_HEIGHTCHANGE received\n"); \
640 SetRect(&height_change_notify_rect, -1, -1, -1, -1); \
645 static void resize_test(void)
647 DWORD dwStyles[] = {CCS_TOP, CCS_TOP | CCS_NODIVIDER, CCS_BOTTOM, CCS_BOTTOM | CCS_NODIVIDER, CCS_VERT, CCS_RIGHT,
648 CCS_NOPARENTALIGN, CCS_NOPARENTALIGN | CCS_NODIVIDER, CCS_NORESIZE, CCS_NOMOVEY, CCS_NOMOVEY | CCS_VERT,
649 CCS_TOP | WS_BORDER, CCS_NOPARENTALIGN | CCS_NODIVIDER | WS_BORDER, CCS_NORESIZE | WS_BORDER,
650 CCS_NOMOVEY | WS_BORDER};
652 const int styles_count = sizeof(dwStyles) / sizeof(dwStyles[0]);
655 for (i = 0; i < styles_count; i++)
657 comment("style %08x", dwStyles[i]);
658 SetRect(&height_change_notify_rect, -1, -1, -1, -1);
659 hRebar = CreateWindow(REBARCLASSNAME, "A", dwStyles[i] | WS_CHILD | WS_VISIBLE, 10, 5, 500, 15, hMainWnd, NULL, GetModuleHandle(NULL), 0);
661 add_band_w(hRebar, NULL, 70, 100, 0);
662 if (dwStyles[i] & CCS_NOPARENTALIGN) /* the window drifts downward for CCS_NOPARENTALIGN without CCS_NODIVIDER */
664 add_band_w(hRebar, NULL, 70, 100, 0);
666 MoveWindow(hRebar, 10, 10, 100, 100, TRUE);
668 MoveWindow(hRebar, 0, 0, 0, 0, TRUE);
670 /* try to fool the rebar by sending invalid width/height - won't work */
671 if (dwStyles[i] & (CCS_NORESIZE | CCS_NOPARENTALIGN))
675 pos.hwndInsertAfter = NULL;
681 SendMessage(hRebar, WM_WINDOWPOSCHANGING, 0, (LPARAM)&pos);
682 SendMessage(hRebar, WM_WINDOWPOSCHANGED, 0, (LPARAM)&pos);
684 SendMessage(hRebar, WM_SIZE, SIZE_RESTORED, MAKELONG(500, 500));
687 SendMessage(hRebar, RB_DELETEBAND, 0, 0);
689 SendMessage(hRebar, RB_DELETEBAND, 0, 0);
690 MoveWindow(hRebar, 0, 0, 100, 100, TRUE);
692 DestroyWindow(hRebar);
696 static void expect_band_content(UINT uBand, INT fStyle, COLORREF clrFore,
697 COLORREF clrBack, LPCSTR lpText, int iImage, HWND hwndChild,
698 INT cxMinChild, INT cyMinChild, INT cx, HBITMAP hbmBack, INT wID,
699 INT cyChild, INT cyMaxChild, INT cyIntegral, INT cxIdeal, LPARAM lParam,
702 CHAR buf[MAX_PATH] = "abc";
705 memset(&rb, 0xdd, sizeof(rb));
706 rb.cbSize = sizeof(rb);
707 rb.fMask = RBBIM_BACKGROUND | RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_COLORS
708 | RBBIM_HEADERSIZE | RBBIM_ID | RBBIM_IDEALSIZE | RBBIM_IMAGE | RBBIM_LPARAM
709 | RBBIM_SIZE | RBBIM_STYLE | RBBIM_TEXT;
712 ok(SendMessageA(hRebar, RB_GETBANDINFOA, uBand, (LPARAM)&rb), "RB_GETBANDINFO failed\n");
713 expect_eq(rb.fStyle, fStyle, int, "%x");
714 todo_wine expect_eq(rb.clrFore, clrFore, COLORREF, "%x");
715 todo_wine expect_eq(rb.clrBack, clrBack, unsigned, "%x");
716 expect_eq(strcmp(rb.lpText, lpText), 0, int, "%d");
717 expect_eq(rb.iImage, iImage, int, "%x");
718 expect_eq(rb.hwndChild, hwndChild, HWND, "%p");
719 expect_eq(rb.cxMinChild, cxMinChild, int, "%d");
720 expect_eq(rb.cyMinChild, cyMinChild, int, "%d");
721 expect_eq(rb.cx, cx, int, "%d");
722 expect_eq(rb.hbmBack, hbmBack, HBITMAP, "%p");
723 expect_eq(rb.wID, wID, int, "%d");
724 /* the values of cyChild, cyMaxChild and cyIntegral can't be read unless the band is RBBS_VARIABLEHEIGHT */
725 expect_eq(rb.cyChild, cyChild, int, "%x");
726 expect_eq(rb.cyMaxChild, cyMaxChild, int, "%x");
727 expect_eq(rb.cyIntegral, cyIntegral, int, "%x");
728 expect_eq(rb.cxIdeal, cxIdeal, int, "%d");
729 expect_eq(rb.lParam, lParam, LPARAM, "%ld");
730 expect_eq(rb.cxHeader, cxHeader, int, "%d");
733 static void bandinfo_test(void)
736 CHAR szABC[] = "ABC";
737 CHAR szABCD[] = "ABCD";
739 rebuild_rebar(&hRebar);
740 rb.cbSize = sizeof(REBARBANDINFO);
742 ok(SendMessageA(hRebar, RB_INSERTBANDA, 0, (LPARAM)&rb), "RB_INSERTBAND failed\n");
743 expect_band_content(0, 0, 0, GetSysColor(COLOR_3DFACE), "", -1, NULL, 0, 0, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 0);
745 rb.fMask = RBBIM_CHILDSIZE;
751 ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_INSERTBAND failed\n");
752 expect_band_content(0, 0, 0, GetSysColor(COLOR_3DFACE), "", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 0);
754 rb.fMask = RBBIM_TEXT;
756 ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_INSERTBAND failed\n");
757 expect_band_content(0, 0, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 35);
759 rb.cbSize = sizeof(REBARBANDINFO);
761 ok(SendMessageA(hRebar, RB_INSERTBANDA, 1, (LPARAM)&rb), "RB_INSERTBAND failed\n");
762 expect_band_content(1, 0, 0, GetSysColor(COLOR_3DFACE), "", -1, NULL, 0, 0, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 9);
763 expect_band_content(0, 0, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 40);
765 rb.fMask = RBBIM_HEADERSIZE;
767 ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_INSERTBAND failed\n");
768 expect_band_content(0, 0x40000000, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 50);
771 ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_INSERTBAND failed\n");
772 expect_band_content(0, 0x40000000, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 5);
774 rb.fMask = RBBIM_TEXT;
776 ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_INSERTBAND failed\n");
777 expect_band_content(0, 0x40000000, 0, GetSysColor(COLOR_3DFACE), "ABCD", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 5);
778 rb.fMask = RBBIM_STYLE | RBBIM_TEXT;
779 rb.fStyle = RBBS_VARIABLEHEIGHT;
781 ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_INSERTBAND failed\n");
782 expect_band_content(0, RBBS_VARIABLEHEIGHT, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 20, 0x7fffffff, 0, 0, 0, 40);
784 DestroyWindow(hRebar);
793 InitCommonControls();
795 wc.style = CS_HREDRAW | CS_VREDRAW;
798 wc.hInstance = GetModuleHandleA(NULL);
800 wc.hCursor = LoadCursorA(NULL, IDC_IBEAM);
801 wc.hbrBackground = GetSysColorBrush(COLOR_WINDOW);
802 wc.lpszMenuName = NULL;
803 wc.lpszClassName = "MyTestWnd";
804 wc.lpfnWndProc = MyWndProc;
806 hMainWnd = CreateWindowExA(0, "MyTestWnd", "Blah", WS_OVERLAPPEDWINDOW,
807 CW_USEDEFAULT, CW_USEDEFAULT, 672+2*GetSystemMetrics(SM_CXSIZEFRAME),
808 226+GetSystemMetrics(SM_CYCAPTION)+2*GetSystemMetrics(SM_CYSIZEFRAME),
809 NULL, NULL, GetModuleHandleA(NULL), 0);
810 GetClientRect(hMainWnd, &rc);
811 ShowWindow(hMainWnd, SW_SHOW);
815 if(is_font_installed("System") && is_font_installed("Tahoma"))
820 skip("Missing System or Tahoma font\n");
823 while(GetMessageA(&msg,0,0,0)) {
824 TranslateMessage(&msg);
825 DispatchMessageA(&msg);
827 DestroyWindow(hMainWnd);