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
, &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
);