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