mfreadwrite/reader: Add missing allocation check (Coverity).
[wine/zf.git] / dlls / comctl32 / tests / rebar.c
blob21b655b197f5eb7673f64f8f553243403feecc0b
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 #include <assert.h>
21 #include <stdarg.h>
23 #include <windows.h>
24 #include <commctrl.h>
25 #include <uxtheme.h>
27 #include "wine/heap.h"
28 #include "wine/test.h"
30 static BOOL (WINAPI *pImageList_Destroy)(HIMAGELIST);
31 static HIMAGELIST (WINAPI *pImageList_LoadImageA)(HINSTANCE, LPCSTR, int, int, COLORREF, UINT, UINT);
33 static RECT height_change_notify_rect;
34 static HWND hMainWnd;
35 static int system_font_height;
38 #define check_rect(name, val, exp) ok(EqualRect(&val, &exp), \
39 "invalid rect (" name ") %s - expected %s\n", wine_dbgstr_rect(&val), wine_dbgstr_rect(&exp));
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, \
44 "invalid rect (" name ") %s - expected %s, ignoring top\n", \
45 wine_dbgstr_rect(&val), wine_dbgstr_rect(&exp)); }
47 #define compare(val, exp, format) ok((val) == (exp), #val " value " format " expected " format "\n", (val), (exp));
49 #define expect_eq(line, expr, value, type, format) { type ret = expr;\
50 ok((value) == ret, #expr " expected " format " got " format " from line %d\n", (value), (ret), line); }
52 static INT CALLBACK is_font_installed_proc(const LOGFONTA *elf, const TEXTMETRICA *ntm, DWORD type, LPARAM lParam)
54 return 0;
57 static BOOL is_font_installed(const char *name)
59 HDC hdc = GetDC(0);
60 BOOL ret = FALSE;
62 if(!EnumFontFamiliesA(hdc, name, is_font_installed_proc, 0))
63 ret = TRUE;
65 ReleaseDC(0, hdc);
66 return ret;
69 static void init_system_font_height(void) {
70 HDC hDC;
71 TEXTMETRICA tm;
73 hDC = CreateCompatibleDC(NULL);
74 GetTextMetricsA(hDC, &tm);
75 DeleteDC(NULL);
77 system_font_height = tm.tmHeight;
80 static HWND create_rebar_control(void)
82 HWND hwnd;
84 hwnd = CreateWindowA(REBARCLASSNAMEA, NULL, WS_CHILD | WS_VISIBLE, 0, 0, 0, 0,
85 hMainWnd, (HMENU)17, GetModuleHandleA(NULL), NULL);
86 ok(hwnd != NULL, "Failed to create Rebar\n");
88 SendMessageA(hwnd, WM_SETFONT, (WPARAM)GetStockObject(SYSTEM_FONT), 0);
90 return hwnd;
93 static HWND build_toolbar(int nr, HWND hParent)
95 TBBUTTON btns[8];
96 HWND hToolbar = CreateWindowExA(0, TOOLBARCLASSNAMEA, NULL, WS_CHILD | WS_VISIBLE | CCS_NORESIZE, 0, 0, 0, 0,
97 hParent, (HMENU)5, GetModuleHandleA(NULL), NULL);
98 int iBitmapId = 0;
99 int i;
101 ok(hToolbar != NULL, "Toolbar creation problem\n");
102 ok(SendMessageA(hToolbar, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0) == 0, "TB_BUTTONSTRUCTSIZE failed\n");
103 ok(SendMessageA(hToolbar, TB_AUTOSIZE, 0, 0) == 0, "TB_AUTOSIZE failed\n");
104 ok(SendMessageA(hToolbar, WM_SETFONT, (WPARAM)GetStockObject(SYSTEM_FONT), 0)==1, "WM_SETFONT\n");
106 for (i=0; i<5+nr; i++)
108 btns[i].iBitmap = i;
109 btns[i].idCommand = i;
110 btns[i].fsStyle = BTNS_BUTTON;
111 btns[i].fsState = TBSTATE_ENABLED;
112 btns[i].iString = 0;
115 switch (nr)
117 case 0: iBitmapId = IDB_HIST_SMALL_COLOR; break;
118 case 1: iBitmapId = IDB_VIEW_SMALL_COLOR; break;
119 case 2: iBitmapId = IDB_STD_SMALL_COLOR; break;
121 ok(SendMessageA(hToolbar, TB_LOADIMAGES, iBitmapId, (LPARAM)HINST_COMMCTRL) == 0, "TB_LOADIMAGES failed\n");
122 ok(SendMessageA(hToolbar, TB_ADDBUTTONSA, 5+nr, (LPARAM)btns), "TB_ADDBUTTONSA failed\n");
123 return hToolbar;
126 static int g_parent_measureitem;
128 static LRESULT CALLBACK parent_wndproc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
130 switch (msg)
132 case WM_NOTIFY:
134 NMHDR *lpnm = (NMHDR *)lParam;
135 if (lpnm->code == RBN_HEIGHTCHANGE)
136 GetClientRect(lpnm->hwndFrom, &height_change_notify_rect);
138 break;
139 case WM_MEASUREITEM:
140 g_parent_measureitem++;
141 break;
143 return DefWindowProcA(hWnd, msg, wParam, lParam);
146 #if 0 /* use this to generate more tests*/
148 static void dump_sizes(HWND hRebar)
150 SIZE sz;
151 RECT r;
152 int count;
153 int i, h;
155 GetClientRect(hRebar, &r);
156 count = SendMessageA(hRebar, RB_GETROWCOUNT, 0, 0);
157 printf(" { {%d, %d, %d, %d}, %d, %d, {", r.left, r.top, r.right, r.bottom,
158 SendMessageA(hRebar, RB_GETBARHEIGHT, 0, 0), count);
159 if (count == 0)
160 printf("0, ");
161 for (i = 0; i < count; i++) /* rows */
162 printf("%d, ", SendMessageA(hRebar, RB_GETROWHEIGHT, i, 0));
163 printf("}, ");
165 count = SendMessageA(hRebar, RB_GETBANDCOUNT, 0, 0);
166 printf("%d, {", count);
167 if (count == 0)
168 printf("{{0, 0, 0, 0}, 0, 0},");
169 for (i=0; i<count; i++)
171 REBARBANDINFOA rbi;
172 rbi.cbSize = REBARBANDINFOA_V6_SIZE;
173 rbi.fMask = RBBIM_SIZE | RBBIM_CHILDSIZE | RBBIM_STYLE;
174 ok(SendMessageA(hRebar, RB_GETBANDINFOA, i, (LPARAM)&rbi), "RB_GETBANDINFOA failed\n");
175 ok(SendMessageA(hRebar, RB_GETRECT, i, (LPARAM)&r), "RB_GETRECT failed\n");
176 printf("%s{ {%3d, %3d, %3d, %3d}, 0x%02x, %d}, ", (i%2==0 ? "\n " : ""), r.left, r.top, r.right, r.bottom,
177 rbi.fStyle, rbi.cx);
179 printf("\n }, },\n");
182 #define check_sizes() dump_sizes(hRebar);
183 #define check_sizes_todo(todomask) dump_sizes(hRebar);
185 #else
187 static int string_width(const CHAR *s) {
188 SIZE sz;
189 HDC hdc;
191 hdc = CreateCompatibleDC(NULL);
192 GetTextExtentPoint32A(hdc, s, strlen(s), &sz);
193 DeleteDC(hdc);
195 return sz.cx;
198 typedef struct {
199 RECT rc;
200 DWORD fStyle;
201 UINT cx;
202 } rbband_result_t;
204 typedef struct {
205 RECT rcClient;
206 int cyBarHeight;
207 int nRows;
208 int *cyRowHeights;
209 int nBands;
210 rbband_result_t *bands;
211 } rbsize_result_t;
213 static rbsize_result_t rbsize_init(int cleft, int ctop, int cright, int cbottom, int cyBarHeight, int nRows, int nBands)
215 rbsize_result_t ret;
217 SetRect(&ret.rcClient, cleft, ctop, cright, cbottom);
218 ret.cyBarHeight = cyBarHeight;
219 ret.nRows = 0;
220 ret.cyRowHeights = heap_alloc_zero(nRows * sizeof(int));
221 ret.nBands = 0;
222 ret.bands = heap_alloc_zero(nBands * sizeof(*ret.bands));
224 return ret;
227 static void rbsize_add_row(rbsize_result_t *rbsr, int rowHeight) {
228 rbsr->cyRowHeights[rbsr->nRows] = rowHeight;
229 rbsr->nRows++;
232 static void rbsize_add_band(rbsize_result_t *rbsr, int left, int top, int right, int bottom, DWORD fStyle, UINT cx)
234 SetRect(&(rbsr->bands[rbsr->nBands].rc), left, top, right, bottom);
235 rbsr->bands[rbsr->nBands].fStyle = fStyle;
236 rbsr->bands[rbsr->nBands].cx = cx;
237 rbsr->nBands++;
240 static rbsize_result_t *rbsize_results;
242 #define rbsize_results_num 27
244 static void rbsize_results_init(void)
246 rbsize_results = heap_alloc(rbsize_results_num * sizeof(*rbsize_results));
248 rbsize_results[0] = rbsize_init(0, 0, 672, 0, 0, 0, 0);
250 rbsize_results[1] = rbsize_init(0, 0, 672, 4, 4, 1, 1);
251 rbsize_add_row(&rbsize_results[1], 4);
252 rbsize_add_band(&rbsize_results[1], 0, 0, 672, 4, 0x00, 200);
254 rbsize_results[2] = rbsize_init(0, 0, 672, 4, 4, 1, 2);
255 rbsize_add_row(&rbsize_results[2], 4);
256 rbsize_add_band(&rbsize_results[2], 0, 0, 200, 4, 0x00, 200);
257 rbsize_add_band(&rbsize_results[2], 200, 0, 672, 4, 0x04, 200);
259 rbsize_results[3] = rbsize_init(0, 0, 672, 30, 30, 1, 3);
260 rbsize_add_row(&rbsize_results[3], 30);
261 rbsize_add_band(&rbsize_results[3], 0, 0, 200, 30, 0x00, 200);
262 rbsize_add_band(&rbsize_results[3], 200, 0, 400, 30, 0x04, 200);
263 rbsize_add_band(&rbsize_results[3], 400, 0, 672, 30, 0x00, 200);
265 rbsize_results[4] = rbsize_init(0, 0, 672, 34, 34, 1, 4);
266 rbsize_add_row(&rbsize_results[4], 34);
267 rbsize_add_band(&rbsize_results[4], 0, 0, 200, 34, 0x00, 200);
268 rbsize_add_band(&rbsize_results[4], 200, 0, 400, 34, 0x04, 200);
269 rbsize_add_band(&rbsize_results[4], 400, 0, 604, 34, 0x00, 200);
270 rbsize_add_band(&rbsize_results[4], 604, 0, 672, 34, 0x04, 68);
272 rbsize_results[5] = rbsize_init(0, 0, 672, 34, 34, 1, 4);
273 rbsize_add_row(&rbsize_results[5], 34);
274 rbsize_add_band(&rbsize_results[5], 0, 0, 200, 34, 0x00, 200);
275 rbsize_add_band(&rbsize_results[5], 200, 0, 400, 34, 0x04, 200);
276 rbsize_add_band(&rbsize_results[5], 400, 0, 604, 34, 0x00, 200);
277 rbsize_add_band(&rbsize_results[5], 604, 0, 672, 34, 0x04, 68);
279 rbsize_results[6] = rbsize_init(0, 0, 672, 34, 34, 1, 4);
280 rbsize_add_row(&rbsize_results[6], 34);
281 rbsize_add_band(&rbsize_results[6], 0, 0, 200, 34, 0x00, 200);
282 rbsize_add_band(&rbsize_results[6], 202, 0, 402, 34, 0x04, 200);
283 rbsize_add_band(&rbsize_results[6], 404, 0, 604, 34, 0x00, 200);
284 rbsize_add_band(&rbsize_results[6], 606, 0, 672, 34, 0x04, 66);
286 rbsize_results[7] = rbsize_init(0, 0, 672, 70, 70, 2, 5);
287 rbsize_add_row(&rbsize_results[7], 34);
288 rbsize_add_row(&rbsize_results[7], 34);
289 rbsize_add_band(&rbsize_results[7], 0, 0, 142, 34, 0x00, 200);
290 rbsize_add_band(&rbsize_results[7], 144, 0, 557, 34, 0x00, 200);
291 rbsize_add_band(&rbsize_results[7], 559, 0, 672, 34, 0x04, 200);
292 rbsize_add_band(&rbsize_results[7], 0, 36, 200, 70, 0x00, 200);
293 rbsize_add_band(&rbsize_results[7], 202, 36, 672, 70, 0x04, 66);
295 rbsize_results[8] = rbsize_init(0, 0, 672, 34, 34, 1, 5);
296 rbsize_add_row(&rbsize_results[8], 34);
297 rbsize_add_band(&rbsize_results[8], 0, 0, 167, 34, 0x00, 200);
298 rbsize_add_band(&rbsize_results[8], 169, 0, 582, 34, 0x00, 200);
299 rbsize_add_band(&rbsize_results[8], 559, 0, 759, 34, 0x08, 200);
300 rbsize_add_band(&rbsize_results[8], 584, 0, 627, 34, 0x00, 200);
301 rbsize_add_band(&rbsize_results[8], 629, 0, 672, 34, 0x04, 66);
303 rbsize_results[9] = rbsize_init(0, 0, 672, 34, 34, 1, 4);
304 rbsize_add_row(&rbsize_results[9], 34);
305 rbsize_add_band(&rbsize_results[9], 0, 0, 167, 34, 0x00, 200);
306 rbsize_add_band(&rbsize_results[9], 169, 0, 582, 34, 0x00, 200);
307 rbsize_add_band(&rbsize_results[9], 584, 0, 627, 34, 0x00, 200);
308 rbsize_add_band(&rbsize_results[9], 629, 0, 672, 34, 0x04, 66);
310 rbsize_results[10] = rbsize_init(0, 0, 672, 34, 34, 1, 3);
311 rbsize_add_row(&rbsize_results[10], 34);
312 rbsize_add_band(&rbsize_results[10], 0, 0, 413, 34, 0x00, 200);
313 rbsize_add_band(&rbsize_results[10], 415, 0, 615, 34, 0x00, 200);
314 rbsize_add_band(&rbsize_results[10], 617, 0, 672, 34, 0x04, 66);
316 rbsize_results[11] = rbsize_init(0, 0, 672, 34, 34, 1, 2);
317 rbsize_add_row(&rbsize_results[11], 34);
318 rbsize_add_band(&rbsize_results[11], 0, 0, 604, 34, 0x00, 200);
319 rbsize_add_band(&rbsize_results[11], 606, 0, 672, 34, 0x04, 66);
321 rbsize_results[12] = rbsize_init(0, 0, 672, 8 + 2*system_font_height, 40, 2, 5);
322 rbsize_add_row(&rbsize_results[12], 4 + system_font_height);
323 rbsize_add_row(&rbsize_results[12], 4 + system_font_height);
324 rbsize_add_band(&rbsize_results[12], 0, 0, 87 + string_width("ABC"), 4 + system_font_height, 0x00, 40);
325 rbsize_add_band(&rbsize_results[12], 87 + string_width("ABC"), 0, 157 + string_width("ABC"), 4 + system_font_height, 0x00, 70);
326 rbsize_add_band(&rbsize_results[12], 157 + string_width("ABC"), 0, 397 + string_width("ABC"), 4 + system_font_height, 0x00, 240);
327 rbsize_add_band(&rbsize_results[12], 397 + string_width("ABC"), 0, 672, 4 + system_font_height, 0x00, 60);
328 rbsize_add_band(&rbsize_results[12], 0, 4 + system_font_height, 672, 8 + 2*system_font_height, 0x00, 200);
330 rbsize_results[13] = rbsize_init(0, 0, 672, 8 + 2*system_font_height, 40, 2, 5);
331 rbsize_add_row(&rbsize_results[13], 4 + system_font_height);
332 rbsize_add_row(&rbsize_results[13], 4 + system_font_height);
333 rbsize_add_band(&rbsize_results[13], 0, 0, 87 + string_width("ABC"), 4 + system_font_height, 0x00, 40);
334 rbsize_add_band(&rbsize_results[13], 87 + string_width("ABC"), 0, 200 + string_width("ABC"), 4 + system_font_height, 0x00, 113);
335 rbsize_add_band(&rbsize_results[13], 200 + string_width("ABC"), 0, 397 + string_width("ABC"), 4 + system_font_height, 0x00, 197);
336 rbsize_add_band(&rbsize_results[13], 397 + string_width("ABC"), 0, 672, 4 + system_font_height, 0x00, 60);
337 rbsize_add_band(&rbsize_results[13], 0, 4 + system_font_height, 672, 8 + 2*system_font_height, 0x00, 200);
339 rbsize_results[14] = rbsize_init(0, 0, 672, 8 + 2*system_font_height, 40, 2, 5);
340 rbsize_add_row(&rbsize_results[14], 4 + system_font_height);
341 rbsize_add_row(&rbsize_results[14], 4 + system_font_height);
342 rbsize_add_band(&rbsize_results[14], 0, 0, 87 + string_width("ABC"), 4 + system_font_height, 0x00, 40);
343 rbsize_add_band(&rbsize_results[14], 87 + string_width("ABC"), 0, 412 - string_width("MMMMMMM"), 4 + system_font_height, 0x00, 325 - string_width("ABC") - string_width("MMMMMMM"));
344 rbsize_add_band(&rbsize_results[14], 412 - string_width("MMMMMMM"), 0, 595 - string_width("MMMMMMM"), 4 + system_font_height, 0x00, 183);
345 rbsize_add_band(&rbsize_results[14], 595 - string_width("MMMMMMM"), 0, 672, 4 + system_font_height, 0x00, 77 + string_width("MMMMMMM"));
346 rbsize_add_band(&rbsize_results[14], 0, 4 + system_font_height, 672, 8 + 2*system_font_height, 0x00, 200);
348 rbsize_results[15] = rbsize_init(0, 0, 672, 8 + 2*system_font_height, 40, 2, 5);
349 rbsize_add_row(&rbsize_results[15], 4 + system_font_height);
350 rbsize_add_row(&rbsize_results[15], 4 + system_font_height);
351 rbsize_add_band(&rbsize_results[15], 0, 0, 87 + string_width("ABC"), 4 + system_font_height, 0x00, 40);
352 rbsize_add_band(&rbsize_results[15], 87 + string_width("ABC"), 0, 140 + string_width("ABC"), 4 + system_font_height, 0x00, 53);
353 rbsize_add_band(&rbsize_results[15], 140 + string_width("ABC"), 0, 595 - string_width("MMMMMMM"), 4 + system_font_height, 0x00, 455 - string_width("MMMMMMM") - string_width("ABC"));
354 rbsize_add_band(&rbsize_results[15], 595 - string_width("MMMMMMM"), 0, 672, 4 + system_font_height, 0x00, 77 + string_width("MMMMMMM"));
355 rbsize_add_band(&rbsize_results[15], 0, 4 + system_font_height, 672, 8 + 2*system_font_height, 0x00, 200);
357 rbsize_results[16] = rbsize_init(0, 0, 672, 8 + 2*system_font_height, 40, 2, 5);
358 rbsize_add_row(&rbsize_results[16], 4 + system_font_height);
359 rbsize_add_row(&rbsize_results[16], 4 + system_font_height);
360 rbsize_add_band(&rbsize_results[16], 0, 0, 87 + string_width("ABC"), 4 + system_font_height, 0x00, 40);
361 rbsize_add_band(&rbsize_results[16], 87 + string_width("ABC"), 0, 412 - string_width("MMMMMMM"), 4 + system_font_height, 0x00, 325 - string_width("ABC") - string_width("MMMMMMM"));
362 rbsize_add_band(&rbsize_results[16], 412 - string_width("MMMMMMM"), 0, 595 - string_width("MMMMMMM"), 4 + system_font_height, 0x00, 183);
363 rbsize_add_band(&rbsize_results[16], 595 - string_width("MMMMMMM"), 0, 672, 4 + system_font_height, 0x00, 77 + string_width("MMMMMMM"));
364 rbsize_add_band(&rbsize_results[16], 0, 4 + system_font_height, 672, 8 + 2*system_font_height, 0x00, 200);
366 rbsize_results[17] = rbsize_init(0, 0, 672, 8 + 2*system_font_height, 40, 2, 5);
367 rbsize_add_row(&rbsize_results[17], 4 + system_font_height);
368 rbsize_add_row(&rbsize_results[17], 4 + system_font_height);
369 rbsize_add_band(&rbsize_results[17], 0, 0, 87 + string_width("ABC"), 4 + system_font_height, 0x00, 40);
370 rbsize_add_band(&rbsize_results[17], 87 + string_width("ABC"), 0, 412 - string_width("MMMMMMM"), 4 + system_font_height, 0x00, 325 - string_width("ABC") - string_width("MMMMMMM"));
371 rbsize_add_band(&rbsize_results[17], 412 - string_width("MMMMMMM"), 0, 595 - string_width("MMMMMMM"), 4 + system_font_height, 0x00, 183);
372 rbsize_add_band(&rbsize_results[17], 595 - string_width("MMMMMMM"), 0, 672, 4 + system_font_height, 0x00, 77 + string_width("MMMMMMM"));
373 rbsize_add_band(&rbsize_results[17], 0, 4 + system_font_height, 672, 8 + 2*system_font_height, 0x00, 200);
375 rbsize_results[18] = rbsize_init(0, 0, 672, 56, 56, 2, 5);
376 rbsize_add_row(&rbsize_results[18], 28);
377 rbsize_add_row(&rbsize_results[18], 28);
378 rbsize_add_band(&rbsize_results[18], 0, 0, 87 + string_width("ABC"), 28, 0x00, 40);
379 rbsize_add_band(&rbsize_results[18], 87 + string_width("ABC"), 0, 412 - string_width("MMMMMMM"), 28, 0x00, 325 - string_width("ABC") - string_width("MMMMMMM"));
380 rbsize_add_band(&rbsize_results[18], 412 - string_width("MMMMMMM"), 0, 595 - string_width("MMMMMMM"), 28, 0x00, 183);
381 rbsize_add_band(&rbsize_results[18], 595 - string_width("MMMMMMM"), 0, 672, 28, 0x00, 77 + string_width("MMMMMMM"));
382 rbsize_add_band(&rbsize_results[18], 0, 28, 672, 56, 0x00, 200);
384 rbsize_results[19] = rbsize_init(0, 0, 672, 8 + 2*system_font_height, 40, 2, 5);
385 rbsize_add_row(&rbsize_results[19], 4 + system_font_height);
386 rbsize_add_row(&rbsize_results[19], 4 + system_font_height);
387 rbsize_add_band(&rbsize_results[19], 0, 0, 87 + string_width("ABC"), 4 + system_font_height, 0x00, 40);
388 rbsize_add_band(&rbsize_results[19], 87 + string_width("ABC"), 0, 412 - string_width("MMMMMMM"), 4 + system_font_height, 0x00, 325 - string_width("ABC") - string_width("MMMMMMM"));
389 rbsize_add_band(&rbsize_results[19], 412 - string_width("MMMMMMM"), 0, 595 - string_width("MMMMMMM"), 4 + system_font_height, 0x00, 183);
390 rbsize_add_band(&rbsize_results[19], 595 - string_width("MMMMMMM"), 0, 672, 4 + system_font_height, 0x00, 77 + string_width("MMMMMMM"));
391 rbsize_add_band(&rbsize_results[19], 0, 4 + system_font_height, 672, 8 + 2*system_font_height, 0x00, 200);
393 rbsize_results[20] = rbsize_init(0, 0, 672, 56, 56, 2, 5);
394 rbsize_add_row(&rbsize_results[20], 28);
395 rbsize_add_row(&rbsize_results[20], 28);
396 rbsize_add_band(&rbsize_results[20], 0, 0, 87 + string_width("ABC"), 28, 0x00, 40);
397 rbsize_add_band(&rbsize_results[20], 87 + string_width("ABC"), 0, 412 - string_width("MMMMMMM"), 28, 0x00, 325 - string_width("ABC") - string_width("MMMMMMM"));
398 rbsize_add_band(&rbsize_results[20], 412 - string_width("MMMMMMM"), 0, 595 - string_width("MMMMMMM"), 28, 0x00, 183);
399 rbsize_add_band(&rbsize_results[20], 595 - string_width("MMMMMMM"), 0, 672, 28, 0x00, 77 + string_width("MMMMMMM"));
400 rbsize_add_band(&rbsize_results[20], 0, 28, 672, 56, 0x00, 200);
402 rbsize_results[21] = rbsize_init(0, 0, 672, 0, 0, 0, 0);
404 rbsize_results[22] = rbsize_init(0, 0, 672, 65, 56, 1, 3);
405 rbsize_add_row(&rbsize_results[22], 65);
406 rbsize_add_band(&rbsize_results[22], 0, 0, 90, 65, 0x40, 90);
407 rbsize_add_band(&rbsize_results[22], 90, 0, 180, 65, 0x40, 90);
408 rbsize_add_band(&rbsize_results[22], 180, 0, 672, 65, 0x40, 90);
410 rbsize_results[23] = rbsize_init(0, 0, 0, 226, 0, 0, 0);
412 rbsize_results[24] = rbsize_init(0, 0, 65, 226, 65, 1, 1);
413 rbsize_add_row(&rbsize_results[24], 65);
414 rbsize_add_band(&rbsize_results[24], 0, 0, 226, 65, 0x40, 90);
416 rbsize_results[25] = rbsize_init(0, 0, 65, 226, 65, 1, 2);
417 rbsize_add_row(&rbsize_results[25], 65);
418 rbsize_add_band(&rbsize_results[25], 0, 0, 90, 65, 0x40, 90);
419 rbsize_add_band(&rbsize_results[25], 90, 0, 226, 65, 0x40, 90);
421 rbsize_results[26] = rbsize_init(0, 0, 65, 226, 65, 1, 3);
422 rbsize_add_row(&rbsize_results[26], 65);
423 rbsize_add_band(&rbsize_results[26], 0, 0, 90, 65, 0x40, 90);
424 rbsize_add_band(&rbsize_results[26], 90, 0, 163, 65, 0x40, 90);
425 rbsize_add_band(&rbsize_results[26], 163, 0, 226, 65, 0x40, 90);
428 static void rbsize_results_free(void)
430 int i;
432 for (i = 0; i < rbsize_results_num; i++) {
433 heap_free(rbsize_results[i].cyRowHeights);
434 heap_free(rbsize_results[i].bands);
436 heap_free(rbsize_results);
437 rbsize_results = NULL;
440 static int rbsize_numtests = 0;
442 #define check_sizes_todo(todomask) { \
443 RECT rc; \
444 REBARBANDINFOA rbi; \
445 int count, i/*, mask=(todomask)*/; \
446 const rbsize_result_t *res = &rbsize_results[rbsize_numtests]; \
447 GetClientRect(hRebar, &rc); \
448 check_rect("client", rc, res->rcClient); \
449 count = SendMessageA(hRebar, RB_GETROWCOUNT, 0, 0); \
450 compare(count, res->nRows, "%d"); \
451 for (i=0; i<min(count, res->nRows); i++) { \
452 int height = SendMessageA(hRebar, RB_GETROWHEIGHT, 0, 0);\
453 ok(height == res->cyRowHeights[i], "Height mismatch for row %d - %d vs %d\n", i, res->cyRowHeights[i], height); \
455 count = SendMessageA(hRebar, RB_GETBANDCOUNT, 0, 0); \
456 compare(count, res->nBands, "%d"); \
457 for (i=0; i<min(count, res->nBands); i++) { \
458 ok(SendMessageA(hRebar, RB_GETRECT, i, (LPARAM)&rc) == 1, "RB_GETRECT\n"); \
459 if (!(res->bands[i].fStyle & RBBS_HIDDEN)) \
460 check_rect("band", rc, res->bands[i].rc); \
461 rbi.cbSize = REBARBANDINFOA_V6_SIZE; \
462 rbi.fMask = RBBIM_STYLE | RBBIM_SIZE; \
463 ok(SendMessageA(hRebar, RB_GETBANDINFOA, i, (LPARAM)&rbi) == 1, "RB_GETBANDINFOA\n"); \
464 compare(rbi.fStyle, res->bands[i].fStyle, "%x"); \
465 compare(rbi.cx, res->bands[i].cx, "%d"); \
467 rbsize_numtests++; \
470 #define check_sizes() check_sizes_todo(0)
472 #endif
474 static void add_band_w(HWND hRebar, LPCSTR lpszText, int cxMinChild, int cx, int cxIdeal)
476 CHAR buffer[MAX_PATH];
477 REBARBANDINFOA rbi;
479 if (lpszText != NULL)
480 strcpy(buffer, lpszText);
481 rbi.cbSize = REBARBANDINFOA_V6_SIZE;
482 rbi.fMask = RBBIM_SIZE | RBBIM_CHILDSIZE | RBBIM_CHILD | RBBIM_IDEALSIZE | RBBIM_TEXT;
483 rbi.cx = cx;
484 rbi.cxMinChild = cxMinChild;
485 rbi.cxIdeal = cxIdeal;
486 rbi.cyMinChild = 20;
487 rbi.hwndChild = build_toolbar(1, hRebar);
488 rbi.lpText = (lpszText ? buffer : NULL);
489 SendMessageA(hRebar, RB_INSERTBANDA, -1, (LPARAM)&rbi);
492 static void test_layout(void)
494 HWND hRebar;
495 REBARBANDINFOA rbi;
496 HIMAGELIST himl;
497 REBARINFO ri;
498 int count;
500 rbsize_results_init();
502 hRebar = create_rebar_control();
503 check_sizes();
504 rbi.cbSize = REBARBANDINFOA_V6_SIZE;
505 rbi.fMask = RBBIM_SIZE | RBBIM_CHILDSIZE | RBBIM_CHILD;
506 rbi.cx = 200;
507 rbi.cxMinChild = 100;
508 rbi.cyMinChild = 30;
509 rbi.hwndChild = NULL;
510 SendMessageA(hRebar, RB_INSERTBANDA, -1, (LPARAM)&rbi);
511 check_sizes();
513 rbi.fMask |= RBBIM_STYLE;
514 rbi.fStyle = RBBS_CHILDEDGE;
515 SendMessageA(hRebar, RB_INSERTBANDA, -1, (LPARAM)&rbi);
516 check_sizes();
518 rbi.fStyle = 0;
519 rbi.cx = 200;
520 rbi.cxMinChild = 30;
521 rbi.cyMinChild = 30;
522 rbi.hwndChild = build_toolbar(0, hRebar);
523 SendMessageA(hRebar, RB_INSERTBANDA, -1, (LPARAM)&rbi);
524 check_sizes();
526 rbi.fStyle = RBBS_CHILDEDGE;
527 rbi.cx = 68;
528 rbi.hwndChild = build_toolbar(0, hRebar);
529 SendMessageA(hRebar, RB_INSERTBANDA, -1, (LPARAM)&rbi);
530 check_sizes();
532 SetWindowLongA(hRebar, GWL_STYLE, GetWindowLongA(hRebar, GWL_STYLE) | RBS_BANDBORDERS);
533 check_sizes(); /* a style change won't start a relayout */
534 rbi.fMask = RBBIM_SIZE;
535 rbi.cx = 66;
536 SendMessageA(hRebar, RB_SETBANDINFOA, 3, (LPARAM)&rbi);
537 check_sizes(); /* here it will be relayouted */
539 /* this will force a new row */
540 rbi.fMask = RBBIM_SIZE | RBBIM_CHILDSIZE | RBBIM_CHILD;
541 rbi.cx = 200;
542 rbi.cxMinChild = 400;
543 rbi.cyMinChild = 30;
544 rbi.hwndChild = build_toolbar(0, hRebar);
545 SendMessageA(hRebar, RB_INSERTBANDA, 1, (LPARAM)&rbi);
546 check_sizes();
548 rbi.fMask = RBBIM_STYLE;
549 rbi.fStyle = RBBS_HIDDEN;
550 SendMessageA(hRebar, RB_SETBANDINFOA, 2, (LPARAM)&rbi);
551 check_sizes();
553 SendMessageA(hRebar, RB_DELETEBAND, 2, 0);
554 check_sizes();
555 SendMessageA(hRebar, RB_DELETEBAND, 0, 0);
556 check_sizes();
557 SendMessageA(hRebar, RB_DELETEBAND, 1, 0);
558 check_sizes();
560 DestroyWindow(hRebar);
562 hRebar = create_rebar_control();
563 add_band_w(hRebar, "ABC", 70, 40, 100);
564 add_band_w(hRebar, NULL, 40, 70, 100);
565 add_band_w(hRebar, NULL, 170, 240, 100);
566 add_band_w(hRebar, "MMMMMMM", 60, 60, 100);
567 add_band_w(hRebar, NULL, 200, 200, 100);
568 check_sizes();
569 SendMessageA(hRebar, RB_MAXIMIZEBAND, 1, TRUE);
570 check_sizes();
571 SendMessageA(hRebar, RB_MAXIMIZEBAND, 1, TRUE);
572 check_sizes();
573 SendMessageA(hRebar, RB_MAXIMIZEBAND, 2, FALSE);
574 check_sizes();
575 SendMessageA(hRebar, RB_MINIMIZEBAND, 2, 0);
576 check_sizes();
577 SendMessageA(hRebar, RB_MINIMIZEBAND, 0, 0);
578 check_sizes();
580 /* an image will increase the band height */
581 himl = pImageList_LoadImageA(GetModuleHandleA("comctl32"), MAKEINTRESOURCEA(121), 24, 2,
582 CLR_NONE, IMAGE_BITMAP, LR_DEFAULTCOLOR);
583 ri.cbSize = sizeof(ri);
584 ri.fMask = RBIM_IMAGELIST;
585 ri.himl = himl;
586 ok(SendMessageA(hRebar, RB_SETBARINFO, 0, (LPARAM)&ri), "RB_SETBARINFO failed\n");
587 rbi.fMask = RBBIM_IMAGE;
588 rbi.iImage = 1;
589 SendMessageA(hRebar, RB_SETBANDINFOA, 1, (LPARAM)&rbi);
590 check_sizes();
592 /* after removing it everything is back to normal*/
593 rbi.iImage = -1;
594 SendMessageA(hRebar, RB_SETBANDINFOA, 1, (LPARAM)&rbi);
595 check_sizes();
597 /* Only -1 means that the image is not present. Other invalid values increase the height */
598 rbi.iImage = -2;
599 SendMessageA(hRebar, RB_SETBANDINFOA, 1, (LPARAM)&rbi);
600 check_sizes();
602 DestroyWindow(hRebar);
604 /* VARHEIGHT resizing test on a horizontal rebar */
605 hRebar = create_rebar_control();
606 SetWindowLongA(hRebar, GWL_STYLE, GetWindowLongA(hRebar, GWL_STYLE) | RBS_AUTOSIZE);
607 check_sizes();
608 rbi.fMask = RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_SIZE | RBBIM_STYLE;
609 rbi.fStyle = RBBS_VARIABLEHEIGHT;
610 rbi.cxMinChild = 50;
611 rbi.cyMinChild = 10;
612 rbi.cyIntegral = 11;
613 rbi.cyChild = 70;
614 rbi.cyMaxChild = 200;
615 rbi.cx = 90;
616 rbi.hwndChild = build_toolbar(0, hRebar);
617 SendMessageA(hRebar, RB_INSERTBANDA, -1, (LPARAM)&rbi);
619 rbi.cyChild = 50;
620 rbi.hwndChild = build_toolbar(0, hRebar);
621 SendMessageA(hRebar, RB_INSERTBANDA, -1, (LPARAM)&rbi);
623 rbi.cyMinChild = 40;
624 rbi.cyChild = 50;
625 rbi.cyIntegral = 5;
626 rbi.hwndChild = build_toolbar(0, hRebar);
627 SendMessageA(hRebar, RB_INSERTBANDA, -1, (LPARAM)&rbi);
628 check_sizes();
630 DestroyWindow(hRebar);
632 /* VARHEIGHT resizing on a vertical rebar */
633 hRebar = create_rebar_control();
634 SetWindowLongA(hRebar, GWL_STYLE, GetWindowLongA(hRebar, GWL_STYLE) | CCS_VERT | RBS_AUTOSIZE);
635 check_sizes();
636 rbi.fMask = RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_SIZE | RBBIM_STYLE;
637 rbi.fStyle = RBBS_VARIABLEHEIGHT;
638 rbi.cxMinChild = 50;
639 rbi.cyMinChild = 10;
640 rbi.cyIntegral = 11;
641 rbi.cyChild = 70;
642 rbi.cyMaxChild = 90;
643 rbi.cx = 90;
644 rbi.hwndChild = build_toolbar(0, hRebar);
645 SendMessageA(hRebar, RB_INSERTBANDA, -1, (LPARAM)&rbi);
646 check_sizes();
648 rbi.cyChild = 50;
649 rbi.hwndChild = build_toolbar(0, hRebar);
650 SendMessageA(hRebar, RB_INSERTBANDA, -1, (LPARAM)&rbi);
651 check_sizes();
653 rbi.cyMinChild = 40;
654 rbi.cyChild = 50;
655 rbi.cyIntegral = 5;
656 rbi.hwndChild = build_toolbar(0, hRebar);
657 SendMessageA(hRebar, RB_INSERTBANDA, -1, (LPARAM)&rbi);
658 check_sizes();
660 DestroyWindow(hRebar);
661 pImageList_Destroy(himl);
663 /* One hidden band. */
664 hRebar = create_rebar_control();
666 rbi.cbSize = REBARBANDINFOA_V6_SIZE;
667 rbi.fMask = RBBIM_STYLE | RBBIM_SIZE | RBBIM_CHILDSIZE | RBBIM_CHILD;
668 rbi.fStyle = RBBS_HIDDEN;
669 rbi.cx = 200;
670 rbi.cxMinChild = 100;
671 rbi.cyMinChild = 30;
672 rbi.hwndChild = NULL;
674 SendMessageA(hRebar, RB_INSERTBANDA, -1, (LPARAM)&rbi);
675 count = SendMessageA(hRebar, RB_GETROWCOUNT, 0, 0);
676 ok(!count, "Unexpected row count %d.\n", count);
678 DestroyWindow(hRebar);
680 rbsize_results_free();
683 #if 0 /* use this to generate more tests */
685 static void dump_client(HWND hRebar)
687 RECT r;
688 BOOL notify;
689 GetWindowRect(hRebar, &r);
690 MapWindowPoints(HWND_DESKTOP, hMainWnd, &r, 2);
691 if (height_change_notify_rect.top != -1)
693 RECT rcClient;
694 GetClientRect(hRebar, &rcClient);
695 assert(EqualRect(&rcClient, &height_change_notify_rect));
696 notify = TRUE;
698 else
699 notify = FALSE;
700 printf(" {{%d, %d, %d, %d}, %d, %s},\n", r.left, r.top, r.right, r.bottom, SendMessageA(hRebar, RB_GETROWCOUNT, 0, 0),
701 notify ? "TRUE" : "FALSE");
702 SetRect(&height_change_notify_rect, -1, -1, -1, -1);
705 #define comment(fmt, arg1) printf("/* " fmt " */\n", arg1);
706 #define check_client() dump_client(hRebar)
708 #else
710 typedef struct {
711 RECT rc;
712 INT iNumRows;
713 BOOL heightNotify;
714 } rbresize_test_result_t;
716 static const rbresize_test_result_t resize_results[] = {
717 /* style 00000001 */
718 {{0, 2, 672, 2}, 0, FALSE},
719 {{0, 2, 672, 22}, 1, TRUE},
720 {{0, 2, 672, 22}, 1, FALSE},
721 {{0, 2, 672, 22}, 1, FALSE},
722 {{0, 2, 672, 22}, 1, FALSE},
723 {{0, 2, 672, 22}, 0, FALSE},
724 /* style 00000041 */
725 {{0, 0, 672, 0}, 0, FALSE},
726 {{0, 0, 672, 20}, 1, TRUE},
727 {{0, 0, 672, 20}, 1, FALSE},
728 {{0, 0, 672, 20}, 1, FALSE},
729 {{0, 0, 672, 20}, 1, FALSE},
730 {{0, 0, 672, 20}, 0, FALSE},
731 /* style 00000003 */
732 {{0, 226, 672, 226}, 0, FALSE},
733 {{0, 206, 672, 226}, 1, TRUE},
734 {{0, 206, 672, 226}, 1, FALSE},
735 {{0, 206, 672, 226}, 1, FALSE},
736 {{0, 206, 672, 226}, 1, FALSE},
737 {{0, 206, 672, 226}, 0, FALSE},
738 /* style 00000043 */
739 {{0, 226, 672, 226}, 0, FALSE},
740 {{0, 206, 672, 226}, 1, TRUE},
741 {{0, 206, 672, 226}, 1, FALSE},
742 {{0, 206, 672, 226}, 1, FALSE},
743 {{0, 206, 672, 226}, 1, FALSE},
744 {{0, 206, 672, 226}, 0, FALSE},
745 /* style 00000080 */
746 {{2, 0, 2, 226}, 0, FALSE},
747 {{2, 0, 22, 226}, 1, TRUE},
748 {{2, 0, 22, 226}, 1, FALSE},
749 {{2, 0, 22, 226}, 1, FALSE},
750 {{2, 0, 22, 226}, 1, FALSE},
751 {{2, 0, 22, 226}, 0, FALSE},
752 /* style 00000083 */
753 {{672, 0, 672, 226}, 0, FALSE},
754 {{652, 0, 672, 226}, 1, TRUE},
755 {{652, 0, 672, 226}, 1, FALSE},
756 {{652, 0, 672, 226}, 1, FALSE},
757 {{652, 0, 672, 226}, 1, FALSE},
758 {{652, 0, 672, 226}, 0, FALSE},
759 /* style 00000008 */
760 {{10, 11, 510, 11}, 0, FALSE},
761 {{10, 15, 510, 35}, 1, TRUE},
762 {{10, 17, 510, 37}, 1, FALSE},
763 {{10, 14, 110, 54}, 2, TRUE},
764 {{0, 4, 0, 44}, 2, FALSE},
765 {{0, 6, 0, 46}, 2, FALSE},
766 {{0, 8, 0, 48}, 2, FALSE},
767 {{0, 12, 0, 32}, 1, TRUE},
768 {{0, 4, 100, 24}, 0, FALSE},
769 /* style 00000048 */
770 {{10, 5, 510, 5}, 0, FALSE},
771 {{10, 5, 510, 25}, 1, TRUE},
772 {{10, 5, 510, 25}, 1, FALSE},
773 {{10, 10, 110, 50}, 2, TRUE},
774 {{0, 0, 0, 40}, 2, FALSE},
775 {{0, 0, 0, 40}, 2, FALSE},
776 {{0, 0, 0, 40}, 2, FALSE},
777 {{0, 0, 0, 20}, 1, TRUE},
778 {{0, 0, 100, 20}, 0, FALSE},
779 /* style 00000004 */
780 {{10, 5, 510, 20}, 0, FALSE},
781 {{10, 5, 510, 20}, 1, TRUE},
782 {{10, 10, 110, 110}, 2, TRUE},
783 {{0, 0, 0, 0}, 2, FALSE},
784 {{0, 0, 0, 0}, 2, FALSE},
785 {{0, 0, 0, 0}, 2, FALSE},
786 {{0, 0, 0, 0}, 1, TRUE},
787 {{0, 0, 100, 100}, 0, FALSE},
788 /* style 00000002 */
789 {{0, 5, 672, 5}, 0, FALSE},
790 {{0, 5, 672, 25}, 1, TRUE},
791 {{0, 10, 672, 30}, 1, FALSE},
792 {{0, 0, 672, 20}, 1, FALSE},
793 {{0, 0, 672, 20}, 1, FALSE},
794 {{0, 0, 672, 20}, 0, FALSE},
795 /* style 00000082 */
796 {{10, 0, 10, 226}, 0, FALSE},
797 {{10, 0, 30, 226}, 1, TRUE},
798 {{10, 0, 30, 226}, 1, FALSE},
799 {{0, 0, 20, 226}, 1, FALSE},
800 {{0, 0, 20, 226}, 1, FALSE},
801 {{0, 0, 20, 226}, 0, FALSE},
802 /* style 00800001 */
803 {{-2, 0, 674, 4}, 0, FALSE},
804 {{-2, 0, 674, 24}, 1, TRUE},
805 {{-2, 0, 674, 24}, 1, FALSE},
806 {{-2, 0, 674, 24}, 1, FALSE},
807 {{-2, 0, 674, 24}, 1, FALSE},
808 {{-2, 0, 674, 24}, 0, FALSE},
809 /* style 00800048 */
810 {{10, 5, 510, 9}, 0, FALSE},
811 {{10, 5, 510, 29}, 1, TRUE},
812 {{10, 5, 510, 29}, 1, FALSE},
813 {{10, 10, 110, 54}, 2, TRUE},
814 {{0, 0, 0, 44}, 2, FALSE},
815 {{0, 0, 0, 44}, 2, FALSE},
816 {{0, 0, 0, 44}, 2, FALSE},
817 {{0, 0, 0, 24}, 1, TRUE},
818 {{0, 0, 100, 24}, 0, FALSE},
819 /* style 00800004 */
820 {{10, 5, 510, 20}, 0, FALSE},
821 {{10, 5, 510, 20}, 1, TRUE},
822 {{10, 10, 110, 110}, 2, TRUE},
823 {{0, 0, 0, 0}, 2, FALSE},
824 {{0, 0, 0, 0}, 2, FALSE},
825 {{0, 0, 0, 0}, 2, FALSE},
826 {{0, 0, 0, 0}, 1, TRUE},
827 {{0, 0, 100, 100}, 0, FALSE},
828 /* style 00800002 */
829 {{-2, 5, 674, 9}, 0, FALSE},
830 {{-2, 5, 674, 29}, 1, TRUE},
831 {{-2, 10, 674, 34}, 1, FALSE},
832 {{-2, 0, 674, 24}, 1, FALSE},
833 {{-2, 0, 674, 24}, 1, FALSE},
834 {{-2, 0, 674, 24}, 0, FALSE},
837 static DWORD resize_numtests = 0;
839 #define comment(fmt, arg1)
840 #define check_client() { \
841 RECT r; \
842 int value; \
843 const rbresize_test_result_t *res = &resize_results[resize_numtests++]; \
844 assert(resize_numtests <= ARRAY_SIZE(resize_results)); \
845 GetWindowRect(hRebar, &r); \
846 MapWindowPoints(HWND_DESKTOP, hMainWnd, (LPPOINT)&r, 2); \
847 if ((dwStyles[i] & (CCS_NOPARENTALIGN|CCS_NODIVIDER)) == CCS_NOPARENTALIGN) {\
848 check_rect_no_top("client", r, res->rc); /* the top coordinate changes after every layout and is very implementation-dependent */ \
849 } else { \
850 check_rect("client", r, res->rc); \
852 value = (int)SendMessageA(hRebar, RB_GETROWCOUNT, 0, 0); \
853 ok(res->iNumRows == value, "RB_GETROWCOUNT expected %d got %d\n", res->iNumRows, value); \
854 if (res->heightNotify) { \
855 RECT rcClient; \
856 GetClientRect(hRebar, &rcClient); \
857 check_rect("notify", height_change_notify_rect, rcClient); \
858 } else ok(height_change_notify_rect.top == -1, "Unexpected RBN_HEIGHTCHANGE received\n"); \
859 SetRect(&height_change_notify_rect, -1, -1, -1, -1); \
862 #endif
864 static void test_resize(void)
866 DWORD dwStyles[] = {CCS_TOP, CCS_TOP | CCS_NODIVIDER, CCS_BOTTOM, CCS_BOTTOM | CCS_NODIVIDER, CCS_VERT, CCS_RIGHT,
867 CCS_NOPARENTALIGN, CCS_NOPARENTALIGN | CCS_NODIVIDER, CCS_NORESIZE, CCS_NOMOVEY, CCS_NOMOVEY | CCS_VERT,
868 CCS_TOP | WS_BORDER, CCS_NOPARENTALIGN | CCS_NODIVIDER | WS_BORDER, CCS_NORESIZE | WS_BORDER,
869 CCS_NOMOVEY | WS_BORDER};
871 const int styles_count = ARRAY_SIZE(dwStyles);
872 int i;
874 for (i = 0; i < styles_count; i++)
876 HWND hRebar;
878 comment("style %08x", dwStyles[i]);
879 SetRect(&height_change_notify_rect, -1, -1, -1, -1);
880 hRebar = CreateWindowA(REBARCLASSNAMEA, "A", dwStyles[i] | WS_CHILD | WS_VISIBLE, 10, 5, 500, 15, hMainWnd, NULL, GetModuleHandleA(NULL), 0);
881 check_client();
882 add_band_w(hRebar, NULL, 70, 100, 0);
883 if (dwStyles[i] & CCS_NOPARENTALIGN) /* the window drifts downward for CCS_NOPARENTALIGN without CCS_NODIVIDER */
884 check_client();
885 add_band_w(hRebar, NULL, 70, 100, 0);
886 check_client();
887 MoveWindow(hRebar, 10, 10, 100, 100, TRUE);
888 check_client();
889 MoveWindow(hRebar, 0, 0, 0, 0, TRUE);
890 check_client();
891 /* try to fool the rebar by sending invalid width/height - won't work */
892 if (dwStyles[i] & (CCS_NORESIZE | CCS_NOPARENTALIGN))
894 WINDOWPOS pos;
895 pos.hwnd = hRebar;
896 pos.hwndInsertAfter = NULL;
897 pos.cx = 500;
898 pos.cy = 500;
899 pos.x = 10;
900 pos.y = 10;
901 pos.flags = 0;
902 SendMessageA(hRebar, WM_WINDOWPOSCHANGING, 0, (LPARAM)&pos);
903 SendMessageA(hRebar, WM_WINDOWPOSCHANGED, 0, (LPARAM)&pos);
904 check_client();
905 SendMessageA(hRebar, WM_SIZE, SIZE_RESTORED, MAKELONG(500, 500));
906 check_client();
908 SendMessageA(hRebar, RB_DELETEBAND, 0, 0);
909 check_client();
910 SendMessageA(hRebar, RB_DELETEBAND, 0, 0);
911 MoveWindow(hRebar, 0, 0, 100, 100, TRUE);
912 check_client();
913 DestroyWindow(hRebar);
917 static void expect_band_content_(int line, HWND hRebar, UINT uBand, INT fStyle, COLORREF clrFore,
918 COLORREF clrBack, LPCSTR lpText, int iImage, HWND hwndChild,
919 INT cxMinChild, INT cyMinChild, INT cx, HBITMAP hbmBack, INT wID,
920 INT cyChild, INT cyMaxChild, INT cyIntegral, INT cxIdeal, LPARAM lParam,
921 UINT cxHeader, UINT cxHeader_broken)
923 CHAR buf[MAX_PATH] = "abc";
924 REBARBANDINFOA rb;
926 memset(&rb, 0xdd, sizeof(rb));
927 rb.cbSize = REBARBANDINFOA_V6_SIZE;
928 rb.fMask = RBBIM_BACKGROUND | RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_COLORS
929 | RBBIM_HEADERSIZE | RBBIM_ID | RBBIM_IDEALSIZE | RBBIM_IMAGE | RBBIM_LPARAM
930 | RBBIM_SIZE | RBBIM_STYLE | RBBIM_TEXT;
931 rb.lpText = buf;
932 rb.cch = MAX_PATH;
933 ok(SendMessageA(hRebar, RB_GETBANDINFOA, uBand, (LPARAM)&rb), "RB_GETBANDINFOA failed from line %d\n", line);
934 expect_eq(line, rb.fStyle, fStyle, int, "%x");
935 expect_eq(line, rb.clrFore, clrFore, COLORREF, "%x");
936 expect_eq(line, rb.clrBack, clrBack, COLORREF, "%x");
937 expect_eq(line, strcmp(rb.lpText, lpText), 0, int, "%d");
938 expect_eq(line, rb.iImage, iImage, int, "%x");
939 expect_eq(line, rb.hwndChild, hwndChild, HWND, "%p");
940 expect_eq(line, rb.cxMinChild, cxMinChild, int, "%d");
941 expect_eq(line, rb.cyMinChild, cyMinChild, int, "%d");
942 expect_eq(line, rb.cx, cx, int, "%d");
943 expect_eq(line, rb.hbmBack, hbmBack, HBITMAP, "%p");
944 expect_eq(line, rb.wID, wID, int, "%d");
945 /* the values of cyChild, cyMaxChild and cyIntegral can't be read unless the band is RBBS_VARIABLEHEIGHT */
946 expect_eq(line, rb.cyChild, cyChild, int, "%x");
947 expect_eq(line, rb.cyMaxChild, cyMaxChild, int, "%x");
948 expect_eq(line, rb.cyIntegral, cyIntegral, int, "%x");
949 expect_eq(line, rb.cxIdeal, cxIdeal, int, "%d");
950 expect_eq(line, rb.lParam, lParam, LPARAM, "%ld");
951 ok(rb.cxHeader == cxHeader || rb.cxHeader == cxHeader + 1 || broken(rb.cxHeader == cxHeader_broken),
952 "expected %d for %d from line %d\n", cxHeader, rb.cxHeader, line);
955 #define expect_band_content(hRebar, uBand, fStyle, clrFore, clrBack,\
956 lpText, iImage, hwndChild, cxMinChild, cyMinChild, cx, hbmBack, wID,\
957 cyChild, cyMaxChild, cyIntegral, cxIdeal, lParam, cxHeader, cxHeader_broken) \
958 expect_band_content_(__LINE__, hRebar, uBand, fStyle, clrFore, clrBack,\
959 lpText, iImage, hwndChild, cxMinChild, cyMinChild, cx, hbmBack, wID,\
960 cyChild, cyMaxChild, cyIntegral, cxIdeal, lParam, cxHeader, cxHeader_broken)
962 static void test_bandinfo(void)
964 REBARBANDINFOA rb;
965 CHAR szABC[] = "ABC";
966 CHAR szABCD[] = "ABCD";
967 HWND hRebar;
969 hRebar = create_rebar_control();
970 rb.cbSize = REBARBANDINFOA_V6_SIZE;
971 rb.fMask = 0;
972 if (!SendMessageA(hRebar, RB_INSERTBANDA, 0, (LPARAM)&rb))
974 win_skip( "V6 info not supported\n" );
975 DestroyWindow(hRebar);
976 return;
978 expect_band_content(hRebar, 0, 0, 0, GetSysColor(COLOR_3DFACE), "", -1, NULL, 0, 0, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 0, -1);
980 rb.fMask = RBBIM_CHILDSIZE;
981 rb.cxMinChild = 15;
982 rb.cyMinChild = 20;
983 rb.cyChild = 30;
984 rb.cyMaxChild = 20;
985 rb.cyIntegral = 10;
986 ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_SETBANDINFOA failed\n");
987 expect_band_content(hRebar, 0, 0, 0, GetSysColor(COLOR_3DFACE), "", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 0, -1);
989 rb.fMask = RBBIM_TEXT;
990 rb.lpText = szABC;
991 ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_SETBANDINFOA failed\n");
992 expect_band_content(hRebar, 0, 0, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 3 + 2*system_font_height, -1);
994 rb.cbSize = REBARBANDINFOA_V6_SIZE;
995 rb.fMask = 0;
996 ok(SendMessageA(hRebar, RB_INSERTBANDA, 1, (LPARAM)&rb), "RB_INSERTBANDA failed\n");
997 expect_band_content(hRebar, 1, 0, 0, GetSysColor(COLOR_3DFACE), "", -1, NULL, 0, 0, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 9, -1);
998 expect_band_content(hRebar, 0, 0, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 8 + 2*system_font_height, -1);
1000 rb.fMask = RBBIM_HEADERSIZE;
1001 rb.cxHeader = 50;
1002 ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_SETBANDINFOA failed\n");
1003 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);
1005 rb.cxHeader = 5;
1006 ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_SETBANDINFOA failed\n");
1007 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);
1009 rb.fMask = RBBIM_TEXT;
1010 rb.lpText = szABCD;
1011 ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_SETBANDINFOA failed\n");
1012 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);
1013 rb.fMask = RBBIM_STYLE | RBBIM_TEXT;
1014 rb.fStyle = RBBS_VARIABLEHEIGHT;
1015 rb.lpText = szABC;
1016 ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_SETBANDINFOA failed\n");
1017 expect_band_content(hRebar, 0, RBBS_VARIABLEHEIGHT, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 20, 0x7fffffff, 0, 0, 0, 8 + 2*system_font_height, 5);
1019 DestroyWindow(hRebar);
1022 static void test_colors(void)
1024 COLORSCHEME scheme;
1025 COLORREF clr;
1026 BOOL ret;
1027 HWND hRebar;
1028 REBARBANDINFOA bi;
1030 hRebar = create_rebar_control();
1032 /* test default colors */
1033 clr = SendMessageA(hRebar, RB_GETTEXTCOLOR, 0, 0);
1034 compare(clr, CLR_NONE, "%x");
1035 clr = SendMessageA(hRebar, RB_GETBKCOLOR, 0, 0);
1036 compare(clr, CLR_NONE, "%x");
1038 scheme.dwSize = sizeof(scheme);
1039 scheme.clrBtnHighlight = 0;
1040 scheme.clrBtnShadow = 0;
1041 ret = SendMessageA(hRebar, RB_GETCOLORSCHEME, 0, (LPARAM)&scheme);
1042 if (ret)
1044 compare(scheme.clrBtnHighlight, CLR_DEFAULT, "%x");
1045 compare(scheme.clrBtnShadow, CLR_DEFAULT, "%x");
1047 else
1048 skip("RB_GETCOLORSCHEME not supported\n");
1050 /* check default band colors */
1051 add_band_w(hRebar, "", 0, 10, 10);
1052 bi.cbSize = REBARBANDINFOA_V6_SIZE;
1053 bi.fMask = RBBIM_COLORS;
1054 bi.clrFore = bi.clrBack = 0xc0ffe;
1055 ret = SendMessageA(hRebar, RB_GETBANDINFOA, 0, (LPARAM)&bi);
1056 ok(ret, "RB_GETBANDINFOA failed\n");
1057 compare(bi.clrFore, RGB(0, 0, 0), "%x");
1058 compare(bi.clrBack, GetSysColor(COLOR_3DFACE), "%x");
1060 SendMessageA(hRebar, RB_SETTEXTCOLOR, 0, RGB(255, 0, 0));
1061 bi.clrFore = bi.clrBack = 0xc0ffe;
1062 ret = SendMessageA(hRebar, RB_GETBANDINFOA, 0, (LPARAM)&bi);
1063 ok(ret, "RB_GETBANDINFOA failed\n");
1064 compare(bi.clrFore, RGB(0, 0, 0), "%x");
1066 DestroyWindow(hRebar);
1070 static BOOL register_parent_wnd_class(void)
1072 WNDCLASSA wc;
1074 wc.style = CS_HREDRAW | CS_VREDRAW;
1075 wc.cbClsExtra = 0;
1076 wc.cbWndExtra = 0;
1077 wc.hInstance = GetModuleHandleA(NULL);
1078 wc.hIcon = NULL;
1079 wc.hCursor = LoadCursorA(NULL, (LPCSTR)IDC_IBEAM);
1080 wc.hbrBackground = GetSysColorBrush(COLOR_WINDOW);
1081 wc.lpszMenuName = NULL;
1082 wc.lpszClassName = "MyTestWnd";
1083 wc.lpfnWndProc = parent_wndproc;
1085 return RegisterClassA(&wc);
1088 static HWND create_parent_window(void)
1090 HWND hwnd;
1092 if (!register_parent_wnd_class()) return NULL;
1094 hwnd = CreateWindowExA(0, "MyTestWnd", "Blah", WS_OVERLAPPEDWINDOW,
1095 CW_USEDEFAULT, CW_USEDEFAULT, 672+2*GetSystemMetrics(SM_CXSIZEFRAME),
1096 226+GetSystemMetrics(SM_CYCAPTION)+2*GetSystemMetrics(SM_CYSIZEFRAME),
1097 NULL, NULL, GetModuleHandleA(NULL), 0);
1099 ShowWindow(hwnd, SW_SHOW);
1100 return hwnd;
1103 static void test_showband(void)
1105 HWND hRebar;
1106 REBARBANDINFOA rbi;
1107 BOOL ret;
1109 hRebar = create_rebar_control();
1111 /* no bands */
1112 ret = SendMessageA(hRebar, RB_SHOWBAND, 0, TRUE);
1113 ok(ret == FALSE, "got %d\n", ret);
1115 rbi.cbSize = REBARBANDINFOA_V6_SIZE;
1116 rbi.fMask = RBBIM_SIZE | RBBIM_CHILDSIZE | RBBIM_CHILD;
1117 rbi.cx = 200;
1118 rbi.cxMinChild = 100;
1119 rbi.cyMinChild = 30;
1120 rbi.hwndChild = NULL;
1121 SendMessageA(hRebar, RB_INSERTBANDA, -1, (LPARAM)&rbi);
1123 /* index out of range */
1124 ret = SendMessageA(hRebar, RB_SHOWBAND, 1, TRUE);
1125 ok(ret == FALSE, "got %d\n", ret);
1127 ret = SendMessageA(hRebar, RB_SHOWBAND, 0, TRUE);
1128 ok(ret == TRUE, "got %d\n", ret);
1130 DestroyWindow(hRebar);
1133 static void test_notification(void)
1135 MEASUREITEMSTRUCT mis;
1136 HWND rebar;
1138 rebar = create_rebar_control();
1140 g_parent_measureitem = 0;
1141 SendMessageA(rebar, WM_MEASUREITEM, 0, (LPARAM)&mis);
1142 ok(g_parent_measureitem == 1, "got %d\n", g_parent_measureitem);
1144 DestroyWindow(rebar);
1147 static void init_functions(void)
1149 HMODULE hComCtl32 = LoadLibraryA("comctl32.dll");
1151 #define X(f) p##f = (void*)GetProcAddress(hComCtl32, #f);
1152 X(ImageList_Destroy);
1153 X(ImageList_LoadImageA);
1154 #undef X
1157 START_TEST(rebar)
1159 MSG msg;
1161 init_system_font_height();
1162 init_functions();
1164 hMainWnd = create_parent_window();
1166 test_bandinfo();
1167 test_colors();
1168 test_showband();
1169 test_notification();
1171 if(!is_font_installed("System") || !is_font_installed("Tahoma"))
1173 skip("Missing System or Tahoma font\n");
1174 goto out;
1177 test_layout();
1178 test_resize();
1180 out:
1181 PostQuitMessage(0);
1182 while(GetMessageA(&msg,0,0,0)) {
1183 TranslateMessage(&msg);
1184 DispatchMessageA(&msg);
1186 DestroyWindow(hMainWnd);