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