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
;
37 #define check_rect(name, val, exp) ok(val.top == exp.top && val.bottom == exp.bottom && \
38 val.left == exp.left && val.right == exp.right, "invalid rect (" name ") (%d,%d) (%d,%d) - expected (%d,%d) (%d,%d)\n", \
39 val.left, val.top, val.right, val.bottom, exp.left, exp.top, exp.right, exp.bottom);
41 #define check_rect_no_top(name, val, exp) { \
42 ok((val.bottom - val.top == exp.bottom - exp.top) && \
43 val.left == exp.left && val.right == exp.right, "invalid rect (" name ") (%d,%d) (%d,%d) - expected (%d,%d) (%d,%d), ignoring top\n", \
44 val.left, val.top, val.right, val.bottom, exp.left, exp.top, exp.right, exp.bottom); \
47 #define compare(val, exp, format) ok((val) == (exp), #val " value " format " expected " format "\n", (val), (exp));
49 #define expect_eq(expr, value, type, format) { type ret = expr; ok((value) == ret, #expr " expected " format " got " format "\n", (value), (ret)); }
51 static INT CALLBACK
is_font_installed_proc(const LOGFONT
*elf
, const TEXTMETRIC
*ntm
, DWORD type
, LPARAM lParam
)
56 static BOOL
is_font_installed(const char *name
)
61 if(!EnumFontFamiliesA(hdc
, name
, is_font_installed_proc
, 0))
68 static HWND
create_rebar_control(void)
72 hwnd
= CreateWindow(REBARCLASSNAME
, NULL
, WS_CHILD
| WS_VISIBLE
, 0, 0, 0, 0,
73 hMainWnd
, (HMENU
)17, GetModuleHandle(NULL
), NULL
);
74 ok(hwnd
!= NULL
, "Failed to create Rebar\n");
76 SendMessageA(hwnd
, WM_SETFONT
, (WPARAM
)GetStockObject(SYSTEM_FONT
), 0);
81 static HWND
build_toolbar(int nr
, HWND hParent
)
84 HWND hToolbar
= CreateWindowEx(0, TOOLBARCLASSNAME
, NULL
, WS_CHILD
| WS_VISIBLE
| CCS_NORESIZE
, 0, 0, 0, 0,
85 hParent
, (HMENU
)5, GetModuleHandle(NULL
), NULL
);
89 ok(hToolbar
!= NULL
, "Toolbar creation problem\n");
90 ok(SendMessage(hToolbar
, TB_BUTTONSTRUCTSIZE
, sizeof(TBBUTTON
), 0) == 0, "TB_BUTTONSTRUCTSIZE failed\n");
91 ok(SendMessage(hToolbar
, TB_AUTOSIZE
, 0, 0) == 0, "TB_AUTOSIZE failed\n");
92 ok(SendMessage(hToolbar
, WM_SETFONT
, (WPARAM
)GetStockObject(SYSTEM_FONT
), 0)==1, "WM_SETFONT\n");
94 for (i
=0; i
<5+nr
; i
++)
97 btns
[i
].idCommand
= i
;
98 btns
[i
].fsStyle
= BTNS_BUTTON
;
99 btns
[i
].fsState
= TBSTATE_ENABLED
;
105 case 0: iBitmapId
= IDB_HIST_SMALL_COLOR
; break;
106 case 1: iBitmapId
= IDB_VIEW_SMALL_COLOR
; break;
107 case 2: iBitmapId
= IDB_STD_SMALL_COLOR
; break;
109 ok(SendMessage(hToolbar
, TB_LOADIMAGES
, iBitmapId
, (LPARAM
)HINST_COMMCTRL
) == 0, "TB_LOADIMAGES failed\n");
110 ok(SendMessage(hToolbar
, TB_ADDBUTTONS
, 5+nr
, (LPARAM
)btns
), "TB_ADDBUTTONS failed\n");
114 static LRESULT CALLBACK
MyWndProc(HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
120 NMHDR
*lpnm
= (NMHDR
*)lParam
;
121 if (lpnm
->code
== RBN_HEIGHTCHANGE
)
122 GetClientRect(lpnm
->hwndFrom
, &height_change_notify_rect
);
126 return DefWindowProcA(hWnd
, msg
, wParam
, lParam
);
129 #if 0 /* use this to generate more tests*/
131 static void dump_sizes(HWND hRebar
)
138 GetClientRect(hRebar
, &r
);
139 count
= SendMessageA(hRebar
, RB_GETROWCOUNT
, 0, 0);
140 printf(" { {%d, %d, %d, %d}, %d, %d, {", r
.left
, r
.top
, r
.right
, r
.bottom
,
141 SendMessageA(hRebar
, RB_GETBARHEIGHT
, 0, 0), count
);
144 for (i
= 0; i
< count
; i
++) /* rows */
145 printf("%d, ", SendMessageA(hRebar
, RB_GETROWHEIGHT
, i
, 0));
148 count
= SendMessageA(hRebar
, RB_GETBANDCOUNT
, 0, 0);
149 printf("%d, {", count
);
151 printf("{{0, 0, 0, 0}, 0, 0},");
152 for (i
=0; i
<count
; i
++)
155 rbi
.cbSize
= REBARBANDINFOA_V6_SIZE
;
156 rbi
.fMask
= RBBIM_SIZE
| RBBIM_CHILDSIZE
| RBBIM_STYLE
;
157 ok(SendMessageA(hRebar
, RB_GETBANDINFOA
, i
, (LPARAM
)&rbi
), "RB_GETBANDINFO failed\n");
158 ok(SendMessageA(hRebar
, RB_GETRECT
, i
, (LPARAM
)&r
), "RB_GETRECT failed\n");
159 printf("%s{ {%3d, %3d, %3d, %3d}, 0x%02x, %d}, ", (i
%2==0 ? "\n " : ""), r
.left
, r
.top
, r
.right
, r
.bottom
,
162 printf("\n }, },\n");
165 #define check_sizes() dump_sizes(hRebar);
166 #define check_sizes_todo(todomask) dump_sizes(hRebar);
180 int cyRowHeights
[50];
182 rbband_result_t bands
[50];
185 rbsize_result_t rbsize_results
[] = {
186 { {0, 0, 672, 0}, 0, 0, {0, }, 0, {{{0, 0, 0, 0}, 0, 0},
188 { {0, 0, 672, 4}, 4, 1, {4, }, 1, {
189 { { 0, 0, 672, 4}, 0x00, 200},
191 { {0, 0, 672, 4}, 4, 1, {4, }, 2, {
192 { { 0, 0, 200, 4}, 0x00, 200}, { {200, 0, 672, 4}, 0x04, 200},
194 { {0, 0, 672, 30}, 30, 1, {30, }, 3, {
195 { { 0, 0, 200, 30}, 0x00, 200}, { {200, 0, 400, 30}, 0x04, 200},
196 { {400, 0, 672, 30}, 0x00, 200},
198 { {0, 0, 672, 34}, 34, 1, {34, }, 4, {
199 { { 0, 0, 200, 34}, 0x00, 200}, { {200, 0, 400, 34}, 0x04, 200},
200 { {400, 0, 604, 34}, 0x00, 200}, { {604, 0, 672, 34}, 0x04, 68},
202 { {0, 0, 672, 34}, 34, 1, {34, }, 4, {
203 { { 0, 0, 200, 34}, 0x00, 200}, { {200, 0, 400, 34}, 0x04, 200},
204 { {400, 0, 604, 34}, 0x00, 200}, { {604, 0, 672, 34}, 0x04, 68},
206 { {0, 0, 672, 34}, 34, 1, {34, }, 4, {
207 { { 0, 0, 200, 34}, 0x00, 200}, { {202, 0, 402, 34}, 0x04, 200},
208 { {404, 0, 604, 34}, 0x00, 200}, { {606, 0, 672, 34}, 0x04, 66},
210 { {0, 0, 672, 70}, 70, 2, {34, 34, }, 5, {
211 { { 0, 0, 142, 34}, 0x00, 200}, { {144, 0, 557, 34}, 0x00, 200},
212 { {559, 0, 672, 34}, 0x04, 200}, { { 0, 36, 200, 70}, 0x00, 200},
213 { {202, 36, 672, 70}, 0x04, 66},
215 { {0, 0, 672, 34}, 34, 1, {34, }, 5, {
216 { { 0, 0, 167, 34}, 0x00, 200}, { {169, 0, 582, 34}, 0x00, 200},
217 { {559, 0, 759, 34}, 0x08, 200}, { {584, 0, 627, 34}, 0x00, 200},
218 { {629, 0, 672, 34}, 0x04, 66},
220 { {0, 0, 672, 34}, 34, 1, {34, }, 4, {
221 { { 0, 0, 167, 34}, 0x00, 200}, { {169, 0, 582, 34}, 0x00, 200},
222 { {584, 0, 627, 34}, 0x00, 200}, { {629, 0, 672, 34}, 0x04, 66},
224 { {0, 0, 672, 34}, 34, 1, {34, }, 3, {
225 { { 0, 0, 413, 34}, 0x00, 200}, { {415, 0, 615, 34}, 0x00, 200},
226 { {617, 0, 672, 34}, 0x04, 66},
228 { {0, 0, 672, 34}, 34, 1, {34, }, 2, {
229 { { 0, 0, 604, 34}, 0x00, 200}, { {606, 0, 672, 34}, 0x04, 66},
231 { {0, 0, 672, 40}, 40, 2, {20, 20, }, 5, {
232 { { 0, 0, 114, 20}, 0x00, 40}, { {114, 0, 184, 20}, 0x00, 70},
233 { {184, 0, 424, 20}, 0x00, 240}, { {424, 0, 672, 20}, 0x00, 60},
234 { { 0, 20, 672, 40}, 0x00, 200},
236 { {0, 0, 672, 40}, 40, 2, {20, 20, }, 5, {
237 { { 0, 0, 114, 20}, 0x00, 40}, { {114, 0, 227, 20}, 0x00, 113},
238 { {227, 0, 424, 20}, 0x00, 197}, { {424, 0, 672, 20}, 0x00, 60},
239 { { 0, 20, 672, 40}, 0x00, 200},
241 { {0, 0, 672, 40}, 40, 2, {20, 20, }, 5, {
242 { { 0, 0, 114, 20}, 0x00, 40}, { {114, 0, 328, 20}, 0x00, 214},
243 { {328, 0, 511, 20}, 0x00, 183}, { {511, 0, 672, 20}, 0x00, 161},
244 { { 0, 20, 672, 40}, 0x00, 200},
246 { {0, 0, 672, 40}, 40, 2, {20, 20, }, 5, {
247 { { 0, 0, 114, 20}, 0x00, 40}, { {114, 0, 167, 20}, 0x00, 53},
248 { {167, 0, 511, 20}, 0x00, 344}, { {511, 0, 672, 20}, 0x00, 161},
249 { { 0, 20, 672, 40}, 0x00, 200},
251 { {0, 0, 672, 40}, 40, 2, {20, 20, }, 5, {
252 { { 0, 0, 114, 20}, 0x00, 40}, { {114, 0, 328, 20}, 0x00, 214},
253 { {328, 0, 511, 20}, 0x00, 183}, { {511, 0, 672, 20}, 0x00, 161},
254 { { 0, 20, 672, 40}, 0x00, 200},
256 { {0, 0, 672, 40}, 40, 2, {20, 20, }, 5, {
257 { { 0, 0, 114, 20}, 0x00, 40}, { {114, 0, 328, 20}, 0x00, 214},
258 { {328, 0, 511, 20}, 0x00, 183}, { {511, 0, 672, 20}, 0x00, 161},
259 { { 0, 20, 672, 40}, 0x00, 200},
261 { {0, 0, 672, 56}, 56, 2, {28, 28, }, 5, {
262 { { 0, 0, 114, 28}, 0x00, 40}, { {114, 0, 328, 28}, 0x00, 214},
263 { {328, 0, 511, 28}, 0x00, 183}, { {511, 0, 672, 28}, 0x00, 161},
264 { { 0, 28, 672, 56}, 0x00, 200},
266 { {0, 0, 672, 40}, 40, 2, {20, 20, }, 5, {
267 { { 0, 0, 114, 20}, 0x00, 40}, { {114, 0, 328, 20}, 0x00, 214},
268 { {328, 0, 511, 20}, 0x00, 183}, { {511, 0, 672, 20}, 0x00, 161},
269 { { 0, 20, 672, 40}, 0x00, 200},
271 { {0, 0, 672, 56}, 56, 2, {28, 28, }, 5, {
272 { { 0, 0, 114, 28}, 0x00, 40}, { {114, 0, 328, 28}, 0x00, 214},
273 { {328, 0, 511, 28}, 0x00, 183}, { {511, 0, 672, 28}, 0x00, 161},
274 { { 0, 28, 672, 56}, 0x00, 200},
276 { {0, 0, 672, 0}, 0, 0, {0, }, 0, {{{0, 0, 0, 0}, 0, 0},
278 { {0, 0, 672, 65}, 65, 1, {65, }, 3, {
279 { { 0, 0, 90, 65}, 0x40, 90}, { { 90, 0, 180, 65}, 0x40, 90},
280 { {180, 0, 672, 65}, 0x40, 90},
282 { {0, 0, 0, 226}, 0, 0, {0, }, 0, {{{0, 0, 0, 0}, 0, 0},
284 { {0, 0, 65, 226}, 65, 1, {65, }, 1, {
285 { { 0, 0, 226, 65}, 0x40, 90},
287 { {0, 0, 65, 226}, 65, 1, {65, }, 2, {
288 { { 0, 0, 90, 65}, 0x40, 90}, { { 90, 0, 226, 65}, 0x40, 90},
290 { {0, 0, 65, 226}, 65, 1, {65, }, 3, {
291 { { 0, 0, 90, 65}, 0x40, 90}, { { 90, 0, 163, 65}, 0x40, 90},
292 { {163, 0, 226, 65}, 0x40, 90},
296 static int rbsize_numtests
= 0;
298 #define check_sizes_todo(todomask) { \
301 int count, i/*, mask=(todomask)*/; \
302 rbsize_result_t *res = &rbsize_results[rbsize_numtests]; \
303 assert(rbsize_numtests < sizeof(rbsize_results)/sizeof(rbsize_results[0])); \
304 GetClientRect(hRebar, &rc); \
305 check_rect("client", rc, res->rcClient); \
306 count = SendMessage(hRebar, RB_GETROWCOUNT, 0, 0); \
307 compare(count, res->nRows, "%d"); \
308 for (i=0; i<min(count, res->nRows); i++) { \
309 int height = SendMessageA(hRebar, RB_GETROWHEIGHT, 0, 0);\
310 ok(height == res->cyRowHeights[i], "Height mismatch for row %d - %d vs %d\n", i, res->cyRowHeights[i], height); \
312 count = SendMessage(hRebar, RB_GETBANDCOUNT, 0, 0); \
313 compare(count, res->nBands, "%d"); \
314 for (i=0; i<min(count, res->nBands); i++) { \
315 ok(SendMessageA(hRebar, RB_GETRECT, i, (LPARAM)&rc) == 1, "RB_GETRECT\n"); \
316 if (!(res->bands[i].fStyle & RBBS_HIDDEN)) \
317 check_rect("band", rc, res->bands[i].rc); \
318 rbi.cbSize = REBARBANDINFOA_V6_SIZE; \
319 rbi.fMask = RBBIM_STYLE | RBBIM_SIZE; \
320 ok(SendMessageA(hRebar, RB_GETBANDINFO, i, (LPARAM)&rbi) == 1, "RB_GETBANDINFO\n"); \
321 compare(rbi.fStyle, res->bands[i].fStyle, "%x"); \
322 compare(rbi.cx, res->bands[i].cx, "%d"); \
327 #define check_sizes() check_sizes_todo(0)
331 static void add_band_w(HWND hRebar
, LPCSTR lpszText
, int cxMinChild
, int cx
, int cxIdeal
)
333 CHAR buffer
[MAX_PATH
];
336 if (lpszText
!= NULL
)
337 strcpy(buffer
, lpszText
);
338 rbi
.cbSize
= REBARBANDINFOA_V6_SIZE
;
339 rbi
.fMask
= RBBIM_SIZE
| RBBIM_CHILDSIZE
| RBBIM_CHILD
| RBBIM_IDEALSIZE
| RBBIM_TEXT
;
341 rbi
.cxMinChild
= cxMinChild
;
342 rbi
.cxIdeal
= cxIdeal
;
344 rbi
.hwndChild
= build_toolbar(1, hRebar
);
345 rbi
.lpText
= (lpszText
? buffer
: NULL
);
346 SendMessage(hRebar
, RB_INSERTBAND
, -1, (LPARAM
)&rbi
);
349 static void test_layout(void)
356 hRebar
= create_rebar_control();
358 rbi
.cbSize
= REBARBANDINFOA_V6_SIZE
;
359 rbi
.fMask
= RBBIM_SIZE
| RBBIM_CHILDSIZE
| RBBIM_CHILD
;
361 rbi
.cxMinChild
= 100;
363 rbi
.hwndChild
= NULL
;
364 SendMessageA(hRebar
, RB_INSERTBAND
, -1, (LPARAM
)&rbi
);
367 rbi
.fMask
|= RBBIM_STYLE
;
368 rbi
.fStyle
= RBBS_CHILDEDGE
;
369 SendMessageA(hRebar
, RB_INSERTBAND
, -1, (LPARAM
)&rbi
);
376 rbi
.hwndChild
= build_toolbar(0, hRebar
);
377 SendMessageA(hRebar
, RB_INSERTBAND
, -1, (LPARAM
)&rbi
);
380 rbi
.fStyle
= RBBS_CHILDEDGE
;
382 rbi
.hwndChild
= build_toolbar(0, hRebar
);
383 SendMessageA(hRebar
, RB_INSERTBAND
, -1, (LPARAM
)&rbi
);
386 SetWindowLong(hRebar
, GWL_STYLE
, GetWindowLong(hRebar
, GWL_STYLE
) | RBS_BANDBORDERS
);
387 check_sizes(); /* a style change won't start a relayout */
388 rbi
.fMask
= RBBIM_SIZE
;
390 SendMessageA(hRebar
, RB_SETBANDINFO
, 3, (LPARAM
)&rbi
);
391 check_sizes(); /* here it will be relayouted */
393 /* this will force a new row */
394 rbi
.fMask
= RBBIM_SIZE
| RBBIM_CHILDSIZE
| RBBIM_CHILD
;
396 rbi
.cxMinChild
= 400;
398 rbi
.hwndChild
= build_toolbar(0, hRebar
);
399 SendMessageA(hRebar
, RB_INSERTBAND
, 1, (LPARAM
)&rbi
);
402 rbi
.fMask
= RBBIM_STYLE
;
403 rbi
.fStyle
= RBBS_HIDDEN
;
404 SendMessageA(hRebar
, RB_SETBANDINFO
, 2, (LPARAM
)&rbi
);
407 SendMessageA(hRebar
, RB_DELETEBAND
, 2, 0);
409 SendMessageA(hRebar
, RB_DELETEBAND
, 0, 0);
411 SendMessageA(hRebar
, RB_DELETEBAND
, 1, 0);
414 DestroyWindow(hRebar
);
416 hRebar
= create_rebar_control();
417 add_band_w(hRebar
, "ABC", 70, 40, 100);
418 add_band_w(hRebar
, NULL
, 40, 70, 100);
419 add_band_w(hRebar
, NULL
, 170, 240, 100);
420 add_band_w(hRebar
, "MMMMMMM", 60, 60, 100);
421 add_band_w(hRebar
, NULL
, 200, 200, 100);
423 SendMessageA(hRebar
, RB_MAXIMIZEBAND
, 1, TRUE
);
425 SendMessageA(hRebar
, RB_MAXIMIZEBAND
, 1, TRUE
);
427 SendMessageA(hRebar
, RB_MAXIMIZEBAND
, 2, FALSE
);
429 SendMessageA(hRebar
, RB_MINIMIZEBAND
, 2, 0);
431 SendMessageA(hRebar
, RB_MINIMIZEBAND
, 0, 0);
434 /* an image will increase the band height */
435 himl
= ImageList_LoadImage(LoadLibrary("comctl32"), MAKEINTRESOURCE(121), 24, 2, CLR_NONE
, IMAGE_BITMAP
, LR_DEFAULTCOLOR
);
436 ri
.cbSize
= sizeof(ri
);
437 ri
.fMask
= RBIM_IMAGELIST
;
439 ok(SendMessage(hRebar
, RB_SETBARINFO
, 0, (LPARAM
)&ri
), "RB_SETBARINFO failed\n");
440 rbi
.fMask
= RBBIM_IMAGE
;
442 SendMessage(hRebar
, RB_SETBANDINFO
, 1, (LPARAM
)&rbi
);
445 /* after removing it everything is back to normal*/
447 SendMessage(hRebar
, RB_SETBANDINFO
, 1, (LPARAM
)&rbi
);
450 /* Only -1 means that the image is not present. Other invalid values increase the height */
452 SendMessage(hRebar
, RB_SETBANDINFO
, 1, (LPARAM
)&rbi
);
455 DestroyWindow(hRebar
);
457 /* VARHEIGHT resizing test on a horizontal rebar */
458 hRebar
= create_rebar_control();
459 SetWindowLong(hRebar
, GWL_STYLE
, GetWindowLong(hRebar
, GWL_STYLE
) | RBS_AUTOSIZE
);
461 rbi
.fMask
= RBBIM_CHILD
| RBBIM_CHILDSIZE
| RBBIM_SIZE
| RBBIM_STYLE
;
462 rbi
.fStyle
= RBBS_VARIABLEHEIGHT
;
467 rbi
.cyMaxChild
= 200;
469 rbi
.hwndChild
= build_toolbar(0, hRebar
);
470 SendMessageA(hRebar
, RB_INSERTBAND
, -1, (LPARAM
)&rbi
);
473 rbi
.hwndChild
= build_toolbar(0, hRebar
);
474 SendMessageA(hRebar
, RB_INSERTBAND
, -1, (LPARAM
)&rbi
);
479 rbi
.hwndChild
= build_toolbar(0, hRebar
);
480 SendMessageA(hRebar
, RB_INSERTBAND
, -1, (LPARAM
)&rbi
);
483 DestroyWindow(hRebar
);
485 /* VARHEIGHT resizing on a vertical rebar */
486 hRebar
= create_rebar_control();
487 SetWindowLong(hRebar
, GWL_STYLE
, GetWindowLong(hRebar
, GWL_STYLE
) | CCS_VERT
| RBS_AUTOSIZE
);
489 rbi
.fMask
= RBBIM_CHILD
| RBBIM_CHILDSIZE
| RBBIM_SIZE
| RBBIM_STYLE
;
490 rbi
.fStyle
= RBBS_VARIABLEHEIGHT
;
497 rbi
.hwndChild
= build_toolbar(0, hRebar
);
498 SendMessageA(hRebar
, RB_INSERTBAND
, -1, (LPARAM
)&rbi
);
502 rbi
.hwndChild
= build_toolbar(0, hRebar
);
503 SendMessageA(hRebar
, RB_INSERTBAND
, -1, (LPARAM
)&rbi
);
509 rbi
.hwndChild
= build_toolbar(0, hRebar
);
510 SendMessageA(hRebar
, RB_INSERTBAND
, -1, (LPARAM
)&rbi
);
513 DestroyWindow(hRebar
);
514 ImageList_Destroy(himl
);
517 #if 0 /* use this to generate more tests */
519 static void dump_client(HWND hRebar
)
523 GetWindowRect(hRebar
, &r
);
524 MapWindowPoints(HWND_DESKTOP
, hMainWnd
, &r
, 2);
525 if (height_change_notify_rect
.top
!= -1)
528 GetClientRect(hRebar
, &rcClient
);
529 assert(EqualRect(&rcClient
, &height_change_notify_rect
));
534 printf(" {{%d, %d, %d, %d}, %d, %s},\n", r
.left
, r
.top
, r
.right
, r
.bottom
, SendMessage(hRebar
, RB_GETROWCOUNT
, 0, 0),
535 notify
? "TRUE" : "FALSE");
536 SetRect(&height_change_notify_rect
, -1, -1, -1, -1);
539 #define comment(fmt, arg1) printf("/* " fmt " */\n", arg1);
540 #define check_client() dump_client(hRebar)
548 } rbresize_test_result_t
;
550 rbresize_test_result_t resize_results
[] = {
552 {{0, 2, 672, 2}, 0, FALSE
},
553 {{0, 2, 672, 22}, 1, TRUE
},
554 {{0, 2, 672, 22}, 1, FALSE
},
555 {{0, 2, 672, 22}, 1, FALSE
},
556 {{0, 2, 672, 22}, 1, FALSE
},
557 {{0, 2, 672, 22}, 0, FALSE
},
559 {{0, 0, 672, 0}, 0, FALSE
},
560 {{0, 0, 672, 20}, 1, TRUE
},
561 {{0, 0, 672, 20}, 1, FALSE
},
562 {{0, 0, 672, 20}, 1, FALSE
},
563 {{0, 0, 672, 20}, 1, FALSE
},
564 {{0, 0, 672, 20}, 0, FALSE
},
566 {{0, 226, 672, 226}, 0, FALSE
},
567 {{0, 206, 672, 226}, 1, TRUE
},
568 {{0, 206, 672, 226}, 1, FALSE
},
569 {{0, 206, 672, 226}, 1, FALSE
},
570 {{0, 206, 672, 226}, 1, FALSE
},
571 {{0, 206, 672, 226}, 0, FALSE
},
573 {{0, 226, 672, 226}, 0, FALSE
},
574 {{0, 206, 672, 226}, 1, TRUE
},
575 {{0, 206, 672, 226}, 1, FALSE
},
576 {{0, 206, 672, 226}, 1, FALSE
},
577 {{0, 206, 672, 226}, 1, FALSE
},
578 {{0, 206, 672, 226}, 0, FALSE
},
580 {{2, 0, 2, 226}, 0, FALSE
},
581 {{2, 0, 22, 226}, 1, TRUE
},
582 {{2, 0, 22, 226}, 1, FALSE
},
583 {{2, 0, 22, 226}, 1, FALSE
},
584 {{2, 0, 22, 226}, 1, FALSE
},
585 {{2, 0, 22, 226}, 0, FALSE
},
587 {{672, 0, 672, 226}, 0, FALSE
},
588 {{652, 0, 672, 226}, 1, TRUE
},
589 {{652, 0, 672, 226}, 1, FALSE
},
590 {{652, 0, 672, 226}, 1, FALSE
},
591 {{652, 0, 672, 226}, 1, FALSE
},
592 {{652, 0, 672, 226}, 0, FALSE
},
594 {{10, 11, 510, 11}, 0, FALSE
},
595 {{10, 15, 510, 35}, 1, TRUE
},
596 {{10, 17, 510, 37}, 1, FALSE
},
597 {{10, 14, 110, 54}, 2, TRUE
},
598 {{0, 4, 0, 44}, 2, FALSE
},
599 {{0, 6, 0, 46}, 2, FALSE
},
600 {{0, 8, 0, 48}, 2, FALSE
},
601 {{0, 12, 0, 32}, 1, TRUE
},
602 {{0, 4, 100, 24}, 0, FALSE
},
604 {{10, 5, 510, 5}, 0, FALSE
},
605 {{10, 5, 510, 25}, 1, TRUE
},
606 {{10, 5, 510, 25}, 1, FALSE
},
607 {{10, 10, 110, 50}, 2, TRUE
},
608 {{0, 0, 0, 40}, 2, FALSE
},
609 {{0, 0, 0, 40}, 2, FALSE
},
610 {{0, 0, 0, 40}, 2, FALSE
},
611 {{0, 0, 0, 20}, 1, TRUE
},
612 {{0, 0, 100, 20}, 0, FALSE
},
614 {{10, 5, 510, 20}, 0, FALSE
},
615 {{10, 5, 510, 20}, 1, TRUE
},
616 {{10, 10, 110, 110}, 2, TRUE
},
617 {{0, 0, 0, 0}, 2, FALSE
},
618 {{0, 0, 0, 0}, 2, FALSE
},
619 {{0, 0, 0, 0}, 2, FALSE
},
620 {{0, 0, 0, 0}, 1, TRUE
},
621 {{0, 0, 100, 100}, 0, FALSE
},
623 {{0, 5, 672, 5}, 0, FALSE
},
624 {{0, 5, 672, 25}, 1, TRUE
},
625 {{0, 10, 672, 30}, 1, FALSE
},
626 {{0, 0, 672, 20}, 1, FALSE
},
627 {{0, 0, 672, 20}, 1, FALSE
},
628 {{0, 0, 672, 20}, 0, FALSE
},
630 {{10, 0, 10, 226}, 0, FALSE
},
631 {{10, 0, 30, 226}, 1, TRUE
},
632 {{10, 0, 30, 226}, 1, FALSE
},
633 {{0, 0, 20, 226}, 1, FALSE
},
634 {{0, 0, 20, 226}, 1, FALSE
},
635 {{0, 0, 20, 226}, 0, FALSE
},
637 {{-2, 0, 674, 4}, 0, FALSE
},
638 {{-2, 0, 674, 24}, 1, TRUE
},
639 {{-2, 0, 674, 24}, 1, FALSE
},
640 {{-2, 0, 674, 24}, 1, FALSE
},
641 {{-2, 0, 674, 24}, 1, FALSE
},
642 {{-2, 0, 674, 24}, 0, FALSE
},
644 {{10, 5, 510, 9}, 0, FALSE
},
645 {{10, 5, 510, 29}, 1, TRUE
},
646 {{10, 5, 510, 29}, 1, FALSE
},
647 {{10, 10, 110, 54}, 2, TRUE
},
648 {{0, 0, 0, 44}, 2, FALSE
},
649 {{0, 0, 0, 44}, 2, FALSE
},
650 {{0, 0, 0, 44}, 2, FALSE
},
651 {{0, 0, 0, 24}, 1, TRUE
},
652 {{0, 0, 100, 24}, 0, FALSE
},
654 {{10, 5, 510, 20}, 0, FALSE
},
655 {{10, 5, 510, 20}, 1, TRUE
},
656 {{10, 10, 110, 110}, 2, TRUE
},
657 {{0, 0, 0, 0}, 2, FALSE
},
658 {{0, 0, 0, 0}, 2, FALSE
},
659 {{0, 0, 0, 0}, 2, FALSE
},
660 {{0, 0, 0, 0}, 1, TRUE
},
661 {{0, 0, 100, 100}, 0, FALSE
},
663 {{-2, 5, 674, 9}, 0, FALSE
},
664 {{-2, 5, 674, 29}, 1, TRUE
},
665 {{-2, 10, 674, 34}, 1, FALSE
},
666 {{-2, 0, 674, 24}, 1, FALSE
},
667 {{-2, 0, 674, 24}, 1, FALSE
},
668 {{-2, 0, 674, 24}, 0, FALSE
},
671 static int resize_numtests
= 0;
673 #define comment(fmt, arg1)
674 #define check_client() { \
676 rbresize_test_result_t *res = &resize_results[resize_numtests++]; \
677 assert(resize_numtests <= sizeof(resize_results)/sizeof(resize_results[0])); \
678 GetWindowRect(hRebar, &r); \
679 MapWindowPoints(HWND_DESKTOP, hMainWnd, (LPPOINT)&r, 2); \
680 if ((dwStyles[i] & (CCS_NOPARENTALIGN|CCS_NODIVIDER)) == CCS_NOPARENTALIGN) {\
681 check_rect_no_top("client", r, res->rc); /* the top coordinate changes after every layout and is very implementation-dependent */ \
683 check_rect("client", r, res->rc); \
685 expect_eq((int)SendMessage(hRebar, RB_GETROWCOUNT, 0, 0), res->iNumRows, int, "%d"); \
686 if (res->heightNotify) { \
688 GetClientRect(hRebar, &rcClient); \
689 check_rect("notify", height_change_notify_rect, rcClient); \
690 } else ok(height_change_notify_rect.top == -1, "Unexpected RBN_HEIGHTCHANGE received\n"); \
691 SetRect(&height_change_notify_rect, -1, -1, -1, -1); \
696 static void test_resize(void)
698 DWORD dwStyles
[] = {CCS_TOP
, CCS_TOP
| CCS_NODIVIDER
, CCS_BOTTOM
, CCS_BOTTOM
| CCS_NODIVIDER
, CCS_VERT
, CCS_RIGHT
,
699 CCS_NOPARENTALIGN
, CCS_NOPARENTALIGN
| CCS_NODIVIDER
, CCS_NORESIZE
, CCS_NOMOVEY
, CCS_NOMOVEY
| CCS_VERT
,
700 CCS_TOP
| WS_BORDER
, CCS_NOPARENTALIGN
| CCS_NODIVIDER
| WS_BORDER
, CCS_NORESIZE
| WS_BORDER
,
701 CCS_NOMOVEY
| WS_BORDER
};
703 const int styles_count
= sizeof(dwStyles
) / sizeof(dwStyles
[0]);
706 for (i
= 0; i
< styles_count
; i
++)
710 comment("style %08x", dwStyles
[i
]);
711 SetRect(&height_change_notify_rect
, -1, -1, -1, -1);
712 hRebar
= CreateWindow(REBARCLASSNAME
, "A", dwStyles
[i
] | WS_CHILD
| WS_VISIBLE
, 10, 5, 500, 15, hMainWnd
, NULL
, GetModuleHandle(NULL
), 0);
714 add_band_w(hRebar
, NULL
, 70, 100, 0);
715 if (dwStyles
[i
] & CCS_NOPARENTALIGN
) /* the window drifts downward for CCS_NOPARENTALIGN without CCS_NODIVIDER */
717 add_band_w(hRebar
, NULL
, 70, 100, 0);
719 MoveWindow(hRebar
, 10, 10, 100, 100, TRUE
);
721 MoveWindow(hRebar
, 0, 0, 0, 0, TRUE
);
723 /* try to fool the rebar by sending invalid width/height - won't work */
724 if (dwStyles
[i
] & (CCS_NORESIZE
| CCS_NOPARENTALIGN
))
728 pos
.hwndInsertAfter
= NULL
;
734 SendMessage(hRebar
, WM_WINDOWPOSCHANGING
, 0, (LPARAM
)&pos
);
735 SendMessage(hRebar
, WM_WINDOWPOSCHANGED
, 0, (LPARAM
)&pos
);
737 SendMessage(hRebar
, WM_SIZE
, SIZE_RESTORED
, MAKELONG(500, 500));
740 SendMessage(hRebar
, RB_DELETEBAND
, 0, 0);
742 SendMessage(hRebar
, RB_DELETEBAND
, 0, 0);
743 MoveWindow(hRebar
, 0, 0, 100, 100, TRUE
);
745 DestroyWindow(hRebar
);
749 static void expect_band_content(HWND hRebar
, UINT uBand
, INT fStyle
, COLORREF clrFore
,
750 COLORREF clrBack
, LPCSTR lpText
, int iImage
, HWND hwndChild
,
751 INT cxMinChild
, INT cyMinChild
, INT cx
, HBITMAP hbmBack
, INT wID
,
752 INT cyChild
, INT cyMaxChild
, INT cyIntegral
, INT cxIdeal
, LPARAM lParam
,
753 INT cxHeader
, INT cxHeader_broken
)
755 CHAR buf
[MAX_PATH
] = "abc";
758 memset(&rb
, 0xdd, sizeof(rb
));
759 rb
.cbSize
= REBARBANDINFOA_V6_SIZE
;
760 rb
.fMask
= RBBIM_BACKGROUND
| RBBIM_CHILD
| RBBIM_CHILDSIZE
| RBBIM_COLORS
761 | RBBIM_HEADERSIZE
| RBBIM_ID
| RBBIM_IDEALSIZE
| RBBIM_IMAGE
| RBBIM_LPARAM
762 | RBBIM_SIZE
| RBBIM_STYLE
| RBBIM_TEXT
;
765 ok(SendMessageA(hRebar
, RB_GETBANDINFOA
, uBand
, (LPARAM
)&rb
), "RB_GETBANDINFO failed\n");
766 expect_eq(rb
.fStyle
, fStyle
, int, "%x");
767 expect_eq(rb
.clrFore
, clrFore
, COLORREF
, "%x");
768 expect_eq(rb
.clrBack
, clrBack
, COLORREF
, "%x");
769 expect_eq(strcmp(rb
.lpText
, lpText
), 0, int, "%d");
770 expect_eq(rb
.iImage
, iImage
, int, "%x");
771 expect_eq(rb
.hwndChild
, hwndChild
, HWND
, "%p");
772 expect_eq(rb
.cxMinChild
, cxMinChild
, int, "%d");
773 expect_eq(rb
.cyMinChild
, cyMinChild
, int, "%d");
774 expect_eq(rb
.cx
, cx
, int, "%d");
775 expect_eq(rb
.hbmBack
, hbmBack
, HBITMAP
, "%p");
776 expect_eq(rb
.wID
, wID
, int, "%d");
777 /* the values of cyChild, cyMaxChild and cyIntegral can't be read unless the band is RBBS_VARIABLEHEIGHT */
778 expect_eq(rb
.cyChild
, cyChild
, int, "%x");
779 expect_eq(rb
.cyMaxChild
, cyMaxChild
, int, "%x");
780 expect_eq(rb
.cyIntegral
, cyIntegral
, int, "%x");
781 expect_eq(rb
.cxIdeal
, cxIdeal
, int, "%d");
782 expect_eq(rb
.lParam
, lParam
, LPARAM
, "%ld");
783 ok( rb
.cxHeader
== cxHeader
|| broken(rb
.cxHeader
== cxHeader_broken
),
784 "expected %d for %d\n", cxHeader
, rb
.cxHeader
);
787 static void test_bandinfo(void)
790 CHAR szABC
[] = "ABC";
791 CHAR szABCD
[] = "ABCD";
794 hRebar
= create_rebar_control();
795 rb
.cbSize
= REBARBANDINFOA_V6_SIZE
;
797 if (!SendMessageA(hRebar
, RB_INSERTBANDA
, 0, (LPARAM
)&rb
))
799 win_skip( "V6 info not supported\n" );
800 DestroyWindow(hRebar
);
803 expect_band_content(hRebar
, 0, 0, 0, GetSysColor(COLOR_3DFACE
), "", -1, NULL
, 0, 0, 0, NULL
, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 0, -1);
805 rb
.fMask
= RBBIM_CHILDSIZE
;
811 ok(SendMessageA(hRebar
, RB_SETBANDINFOA
, 0, (LPARAM
)&rb
), "RB_SETBANDINFO failed\n");
812 expect_band_content(hRebar
, 0, 0, 0, GetSysColor(COLOR_3DFACE
), "", -1, NULL
, 15, 20, 0, NULL
, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 0, -1);
814 rb
.fMask
= RBBIM_TEXT
;
816 ok(SendMessageA(hRebar
, RB_SETBANDINFOA
, 0, (LPARAM
)&rb
), "RB_SETBANDINFO failed\n");
817 expect_band_content(hRebar
, 0, 0, 0, GetSysColor(COLOR_3DFACE
), "ABC", -1, NULL
, 15, 20, 0, NULL
, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 35, -1);
819 rb
.cbSize
= REBARBANDINFOA_V6_SIZE
;
821 ok(SendMessageA(hRebar
, RB_INSERTBANDA
, 1, (LPARAM
)&rb
), "RB_INSERTBAND failed\n");
822 expect_band_content(hRebar
, 1, 0, 0, GetSysColor(COLOR_3DFACE
), "", -1, NULL
, 0, 0, 0, NULL
, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 9, -1);
823 expect_band_content(hRebar
, 0, 0, 0, GetSysColor(COLOR_3DFACE
), "ABC", -1, NULL
, 15, 20, 0, NULL
, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 40, -1);
825 rb
.fMask
= RBBIM_HEADERSIZE
;
827 ok(SendMessageA(hRebar
, RB_SETBANDINFOA
, 0, (LPARAM
)&rb
), "RB_SETBANDINFO failed\n");
828 expect_band_content(hRebar
, 0, 0x40000000, 0, GetSysColor(COLOR_3DFACE
), "ABC", -1, NULL
, 15, 20, 0, NULL
, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 50, -1);
831 ok(SendMessageA(hRebar
, RB_SETBANDINFOA
, 0, (LPARAM
)&rb
), "RB_SETBANDINFO failed\n");
832 expect_band_content(hRebar
, 0, 0x40000000, 0, GetSysColor(COLOR_3DFACE
), "ABC", -1, NULL
, 15, 20, 0, NULL
, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 5, -1);
834 rb
.fMask
= RBBIM_TEXT
;
836 ok(SendMessageA(hRebar
, RB_SETBANDINFOA
, 0, (LPARAM
)&rb
), "RB_SETBANDINFO failed\n");
837 expect_band_content(hRebar
, 0, 0x40000000, 0, GetSysColor(COLOR_3DFACE
), "ABCD", -1, NULL
, 15, 20, 0, NULL
, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 5, -1);
838 rb
.fMask
= RBBIM_STYLE
| RBBIM_TEXT
;
839 rb
.fStyle
= RBBS_VARIABLEHEIGHT
;
841 ok(SendMessageA(hRebar
, RB_SETBANDINFOA
, 0, (LPARAM
)&rb
), "RB_SETBANDINFO failed\n");
842 expect_band_content(hRebar
, 0, RBBS_VARIABLEHEIGHT
, 0, GetSysColor(COLOR_3DFACE
), "ABC", -1, NULL
, 15, 20, 0, NULL
, 0, 20, 0x7fffffff, 0, 0, 0, 40, 5);
844 DestroyWindow(hRebar
);
847 static void test_colors(void)
855 hRebar
= create_rebar_control();
857 /* test default colors */
858 clr
= SendMessage(hRebar
, RB_GETTEXTCOLOR
, 0, 0);
859 compare(clr
, CLR_NONE
, "%x");
860 clr
= SendMessage(hRebar
, RB_GETBKCOLOR
, 0, 0);
861 compare(clr
, CLR_NONE
, "%x");
863 scheme
.dwSize
= sizeof(scheme
);
864 scheme
.clrBtnHighlight
= 0;
865 scheme
.clrBtnShadow
= 0;
866 ret
= SendMessage(hRebar
, RB_GETCOLORSCHEME
, 0, (LPARAM
)&scheme
);
869 compare(scheme
.clrBtnHighlight
, CLR_DEFAULT
, "%x");
870 compare(scheme
.clrBtnShadow
, CLR_DEFAULT
, "%x");
873 skip("RB_GETCOLORSCHEME not supported\n");
875 /* check default band colors */
876 add_band_w(hRebar
, "", 0, 10, 10);
877 bi
.cbSize
= REBARBANDINFOA_V6_SIZE
;
878 bi
.fMask
= RBBIM_COLORS
;
879 bi
.clrFore
= bi
.clrBack
= 0xc0ffe;
880 ret
= SendMessage(hRebar
, RB_GETBANDINFO
, 0, (LPARAM
)&bi
);
881 ok(ret
, "RB_GETBANDINFO failed\n");
882 compare(bi
.clrFore
, RGB(0, 0, 0), "%x");
883 compare(bi
.clrBack
, GetSysColor(COLOR_3DFACE
), "%x");
885 SendMessage(hRebar
, RB_SETTEXTCOLOR
, 0, RGB(255, 0, 0));
886 bi
.clrFore
= bi
.clrBack
= 0xc0ffe;
887 ret
= SendMessage(hRebar
, RB_GETBANDINFO
, 0, (LPARAM
)&bi
);
888 ok(ret
, "RB_GETBANDINFO failed\n");
889 compare(bi
.clrFore
, RGB(0, 0, 0), "%x");
891 DestroyWindow(hRebar
);
895 static BOOL
register_parent_wnd_class(void)
899 wc
.style
= CS_HREDRAW
| CS_VREDRAW
;
902 wc
.hInstance
= GetModuleHandleA(NULL
);
904 wc
.hCursor
= LoadCursorA(NULL
, IDC_IBEAM
);
905 wc
.hbrBackground
= GetSysColorBrush(COLOR_WINDOW
);
906 wc
.lpszMenuName
= NULL
;
907 wc
.lpszClassName
= "MyTestWnd";
908 wc
.lpfnWndProc
= MyWndProc
;
910 return RegisterClassA(&wc
);
913 static HWND
create_parent_window(void)
917 if (!register_parent_wnd_class()) return NULL
;
919 hwnd
= CreateWindowExA(0, "MyTestWnd", "Blah", WS_OVERLAPPEDWINDOW
,
920 CW_USEDEFAULT
, CW_USEDEFAULT
, 672+2*GetSystemMetrics(SM_CXSIZEFRAME
),
921 226+GetSystemMetrics(SM_CYCAPTION
)+2*GetSystemMetrics(SM_CYSIZEFRAME
),
922 NULL
, NULL
, GetModuleHandleA(NULL
), 0);
924 ShowWindow(hwnd
, SW_SHOW
);
931 BOOL (WINAPI
*pInitCommonControlsEx
)(const INITCOMMONCONTROLSEX
*);
932 INITCOMMONCONTROLSEX iccex
;
935 /* LoadLibrary is needed. This file has no references to functions in comctl32 */
936 hComctl32
= LoadLibraryA("comctl32.dll");
937 pInitCommonControlsEx
= (void*)GetProcAddress(hComctl32
, "InitCommonControlsEx");
938 if (!pInitCommonControlsEx
)
940 win_skip("InitCommonControlsEx() is missing. Skipping the tests\n");
943 iccex
.dwSize
= sizeof(iccex
);
944 iccex
.dwICC
= ICC_COOL_CLASSES
;
945 pInitCommonControlsEx(&iccex
);
947 hMainWnd
= create_parent_window();
952 if(!is_font_installed("System") || !is_font_installed("Tahoma"))
954 skip("Missing System or Tahoma font\n");
963 while(GetMessageA(&msg
,0,0,0)) {
964 TranslateMessage(&msg
);
965 DispatchMessageA(&msg
);
967 DestroyWindow(hMainWnd
);
969 FreeLibrary(hComctl32
);