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