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