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