From ffbf61ae55c8e0062aa76bc9a04cb62815d3fc92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Zalewski?= Date: Mon, 19 Feb 2007 14:09:24 +0100 Subject: [PATCH] comctl32: rebar: Test and fix the WM_SIZE handler and REBAR_ForceResize. --- dlls/comctl32/comctl32.h | 3 + dlls/comctl32/rebar.c | 262 +++++++++++------------------------- dlls/comctl32/tests/rebar.c | 183 +++++++++++++++++++++++++ 3 files changed, 262 insertions(+), 186 deletions(-) diff --git a/dlls/comctl32/comctl32.h b/dlls/comctl32/comctl32.h index 66a0973183c..e7a359881cd 100644 --- a/dlls/comctl32/comctl32.h +++ b/dlls/comctl32/comctl32.h @@ -38,6 +38,9 @@ extern HMODULE COMCTL32_hModule; extern HBRUSH COMCTL32_hPattern55AABrush; +/* has a value of: 0, CCS_TOP, CCS_NOMOVEY, CCS_BOTTOM */ +#define CCS_LAYOUT_MASK 0x3 + /* Property sheet / Wizard */ #define IDD_PROPSHEET 1006 #define IDD_WIZARD 1020 diff --git a/dlls/comctl32/rebar.c b/dlls/comctl32/rebar.c index cfa59f22e06..b7d1c57aa45 100644 --- a/dlls/comctl32/rebar.c +++ b/dlls/comctl32/rebar.c @@ -32,9 +32,7 @@ * - RBS_FIXEDORDER * - RBS_REGISTERDROP * - RBS_TOOLTIPS - * - CCS_NORESIZE - * - CCS_NOMOVEX - * - CCS_NOMOVEY + * - RBS_AUTOSIZE * Messages: * - RB_BEGINDRAG * - RB_DRAGMOVE @@ -190,7 +188,6 @@ typedef struct POINT dragNow; /* x,y of this MouseMove */ INT iOldBand; /* last band that had the mouse cursor over it */ INT ihitoffset; /* offset of hotspot from gripper.left */ - POINT origin; /* left/upper corner of client */ INT ichevronhotBand; /* last band that had a hot chevron */ INT iGrabbedBand;/* band number of band whose gripper was grabbed */ @@ -200,11 +197,9 @@ typedef struct /* fStatus flags */ #define BEGIN_DRAG_ISSUED 0x00000001 #define AUTO_RESIZE 0x00000002 -#define RESIZE_ANYHOW 0x00000004 #define NTF_HGHTCHG 0x00000008 #define BAND_NEEDS_LAYOUT 0x00000010 #define BAND_NEEDS_REDRAW 0x00000020 -#define CREATE_RUNNING 0x00000040 /* used by Windows to mark that the header size has been set by the user and shouldn't be changed */ #define RBBS_UNDOC_FIXEDHEADER 0x40000000 @@ -439,13 +434,18 @@ REBAR_DumpBand (REBAR_INFO *iP) } +/* dest can be equal to src */ static void translate_rect(REBAR_INFO *infoPtr, RECT *dest, const RECT *src) { if (infoPtr->dwStyle & CCS_VERT) { - dest->top = src->left; - dest->bottom = src->right; + int tmp; + tmp = src->left; dest->left = src->top; + dest->top = tmp; + + tmp = src->right; dest->right = src->bottom; + dest->bottom = tmp; } else { *dest = *src; } @@ -465,6 +465,16 @@ static int get_rect_cy(REBAR_INFO *infoPtr, RECT *lpRect) return lpRect->bottom - lpRect->top; } +static void swap_size_if_vert(REBAR_INFO *infoPtr, SIZE *size) +{ + if (infoPtr->dwStyle & CCS_VERT) + { + LONG tmp = size->cx; + size->cx = size->cy; + size->cy = tmp; + } +} + static void round_child_height(REBAR_BAND *lpBand, int cyHeight) { int cy = 0; @@ -933,104 +943,71 @@ REBAR_ForceResize (REBAR_INFO *infoPtr) /* Function: This changes the size of the REBAR window to that */ /* calculated by REBAR_Layout. */ { - RECT rc; INT x, y, width, height; - INT xedge = GetSystemMetrics(SM_CXEDGE); - INT yedge = GetSystemMetrics(SM_CYEDGE); + INT xedge = 0, yedge = 0; + RECT rcSelf; - GetClientRect (infoPtr->hwndSelf, &rc); - - TRACE( " old [%d x %d], new [%d x %d], client [%d x %d]\n", + TRACE( "old [%d x %d], new [%d x %d]\n", infoPtr->oldSize.cx, infoPtr->oldSize.cy, - infoPtr->calcSize.cx, infoPtr->calcSize.cy, - rc.right, rc.bottom); + infoPtr->calcSize.cx, infoPtr->calcSize.cy); if (infoPtr->dwStyle & CCS_NORESIZE) return; - /* If we need to shrink client, then skip size test */ - if ((infoPtr->calcSize.cy >= rc.bottom) && - (infoPtr->calcSize.cx >= rc.right)) { - - /* if size did not change then skip process */ - if ((infoPtr->oldSize.cx == infoPtr->calcSize.cx) && - (infoPtr->oldSize.cy == infoPtr->calcSize.cy) && - !(infoPtr->fStatus & RESIZE_ANYHOW)) - { - TRACE("skipping reset\n"); - return; - } + if (infoPtr->dwStyle & WS_BORDER) + { + xedge = GetSystemMetrics(SM_CXEDGE); + yedge = GetSystemMetrics(SM_CYEDGE); + /* swap for CCS_VERT? */ } - infoPtr->fStatus &= ~RESIZE_ANYHOW; - /* Set flag to ignore next WM_SIZE message */ - infoPtr->fStatus |= AUTO_RESIZE; - - width = 0; - height = 0; - x = 0; - y = 0; - - if (infoPtr->dwStyle & WS_BORDER) { - width = 2 * xedge; - height = 2 * yedge; - } + /* compute rebar window rect in parent client coordinates */ + GetWindowRect(infoPtr->hwndSelf, &rcSelf); + MapWindowPoints(HWND_DESKTOP, GetParent(infoPtr->hwndSelf), (LPPOINT)&rcSelf, 2); + translate_rect(infoPtr, &rcSelf, &rcSelf); + height = (infoPtr->dwStyle & CCS_VERT ? infoPtr->calcSize.cx : infoPtr->calcSize.cy) + 2*yedge; if (!(infoPtr->dwStyle & CCS_NOPARENTALIGN)) { - INT mode = infoPtr->dwStyle & (CCS_VERT | CCS_TOP | CCS_BOTTOM); - RECT rcPcl; + RECT rcParent; + SIZE calcSize; - GetClientRect(GetParent(infoPtr->hwndSelf), &rcPcl); - switch (mode) { - case CCS_TOP: - /* _TOP sets width to parents width */ - width += (rcPcl.right - rcPcl.left); - height += infoPtr->calcSize.cy; - x += ((infoPtr->dwStyle & WS_BORDER) ? -xedge : 0); - y += ((infoPtr->dwStyle & WS_BORDER) ? -yedge : 0); - y += ((infoPtr->dwStyle & CCS_NODIVIDER) ? 0 : REBAR_DIVIDER); - break; - case CCS_BOTTOM: - /* FIXME: wrong wrong wrong */ - /* _BOTTOM sets width to parents width */ - width += (rcPcl.right - rcPcl.left); - height += infoPtr->calcSize.cy; - x += -xedge; - y = rcPcl.bottom - height + 1; - break; - case CCS_LEFT: - /* _LEFT sets height to parents height */ - width += infoPtr->calcSize.cx; - height += (rcPcl.bottom - rcPcl.top); - x += ((infoPtr->dwStyle & WS_BORDER) ? -xedge : 0); - x += ((infoPtr->dwStyle & CCS_NODIVIDER) ? 0 : REBAR_DIVIDER); - y += ((infoPtr->dwStyle & WS_BORDER) ? -yedge : 0); - break; - case CCS_RIGHT: - /* FIXME: wrong wrong wrong */ - /* _RIGHT sets height to parents height */ - width += infoPtr->calcSize.cx; - height += (rcPcl.bottom - rcPcl.top); - x = rcPcl.right - width + 1; - y = -yedge; - break; - default: - width += infoPtr->calcSize.cx; - height += infoPtr->calcSize.cy; + x = -xedge; + width = (infoPtr->dwStyle & CCS_VERT ? infoPtr->calcSize.cy : infoPtr->calcSize.cx) + 2*xedge; + y = 0; /* quiet compiler warning */ + switch ( infoPtr->dwStyle & CCS_LAYOUT_MASK) { + case 0: /* shouldn't happen - see NCCreate */ + case CCS_TOP: + y = ((infoPtr->dwStyle & CCS_NODIVIDER) ? 0 : REBAR_DIVIDER) - yedge; + break; + case CCS_NOMOVEY: + y = rcSelf.top; + break; + case CCS_BOTTOM: + GetClientRect(GetParent(infoPtr->hwndSelf), &rcParent); + translate_rect(infoPtr, &rcParent, &rcParent); + calcSize = infoPtr->calcSize; + swap_size_if_vert(infoPtr, &calcSize); + y = rcParent.bottom - calcSize.cy - yedge; + break; } } else { - width += infoPtr->calcSize.cx; - height += infoPtr->calcSize.cy; - x = infoPtr->origin.x; - y = infoPtr->origin.y; + x = rcSelf.left; + /* As on Windows if the CCS_NODIVIDER is not present the control will move + * 2 pixel down after every layout */ + y = rcSelf.top + ((infoPtr->dwStyle & CCS_NODIVIDER) ? 0 : REBAR_DIVIDER); + width = rcSelf.right - rcSelf.left; } TRACE("hwnd %p, style=%08x, setting at (%d,%d) for (%d,%d)\n", - infoPtr->hwndSelf, infoPtr->dwStyle, - x, y, width, height); - SetWindowPos (infoPtr->hwndSelf, 0, x, y, width, height, - SWP_NOZORDER); + infoPtr->hwndSelf, infoPtr->dwStyle, x, y, width, height); + + /* Set flag to ignore next WM_SIZE message and resize the window */ + infoPtr->fStatus |= AUTO_RESIZE; + if ((infoPtr->dwStyle & CCS_VERT) == 0) + SetWindowPos(infoPtr->hwndSelf, 0, x, y, width, height, SWP_NOZORDER); + else + SetWindowPos(infoPtr->hwndSelf, 0, y, x, height, width, SWP_NOZORDER); infoPtr->fStatus &= ~AUTO_RESIZE; } @@ -1158,16 +1135,6 @@ REBAR_MoveChildWindows (REBAR_INFO *infoPtr, UINT start, UINT endplus) } -static void swap_size_if_vert(REBAR_INFO *infoPtr, SIZE *size) -{ - if (infoPtr->dwStyle & CCS_VERT) - { - LONG tmp = size->cx; - size->cx = size->cy; - size->cy = tmp; - } -} - static int next_band(REBAR_INFO *infoPtr, int i) { int n; @@ -1394,7 +1361,7 @@ REBAR_Layout(REBAR_INFO *infoPtr, LPRECT lpRect, BOOL notify) if (lpRect) { rcAdj = *lpRect; cyTarget = get_rect_cy(infoPtr, lpRect); - } else if (infoPtr->dwStyle & CCS_NORESIZE || GetParent(infoPtr->hwndSelf) == NULL) + } else if (infoPtr->dwStyle & (CCS_NORESIZE | CCS_NOPARENTALIGN) || GetParent(infoPtr->hwndSelf) == NULL) GetClientRect(infoPtr->hwndSelf, &rcAdj); else GetClientRect(GetParent(infoPtr->hwndSelf), &rcAdj); @@ -2010,7 +1977,6 @@ REBAR_DeleteBand (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam) TRACE("setting NEEDS_LAYOUT\n"); infoPtr->fStatus |= BAND_NEEDS_LAYOUT; - infoPtr->fStatus |= RESIZE_ANYHOW; REBAR_Layout(infoPtr, NULL, TRUE); return TRUE; @@ -3150,7 +3116,7 @@ REBAR_NCCreate (HWND hwnd, WPARAM wParam, LPARAM lParam) infoPtr->hcurHorz = LoadCursorW (0, (LPWSTR)IDC_SIZEWE); infoPtr->hcurVert = LoadCursorW (0, (LPWSTR)IDC_SIZENS); infoPtr->hcurDrag = LoadCursorW (0, (LPWSTR)IDC_SIZE); - infoPtr->fStatus = CREATE_RUNNING; + infoPtr->fStatus = 0; infoPtr->hFont = GetStockObject (SYSTEM_FONT); /* issue WM_NOTIFYFORMAT to get unicode status of parent */ @@ -3159,7 +3125,9 @@ REBAR_NCCreate (HWND hwnd, WPARAM wParam, LPARAM lParam) /* Stow away the original style */ infoPtr->orgStyle = cs->style; /* add necessary styles to the requested styles */ - infoPtr->dwStyle = cs->style | WS_VISIBLE | CCS_TOP; + infoPtr->dwStyle = cs->style | WS_VISIBLE; + if ((infoPtr->dwStyle & CCS_LAYOUT_MASK) == 0) + infoPtr->dwStyle |= CCS_TOP; SetWindowLongW (hwnd, GWL_STYLE, infoPtr->dwStyle); /* get font handle for Caption Font */ @@ -3409,88 +3377,17 @@ REBAR_SetRedraw (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam) static LRESULT REBAR_Size (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam) { - RECT rcClient; + TRACE("wParam=%x, lParam=%lx\n", wParam, lParam); - /* auto resize deadlock check */ + /* avoid auto resize infinite recursion */ if (infoPtr->fStatus & AUTO_RESIZE) { infoPtr->fStatus &= ~AUTO_RESIZE; TRACE("AUTO_RESIZE was set, reset, fStatus=%08x lparam=%08lx\n", infoPtr->fStatus, lParam); return 0; } - - if (infoPtr->fStatus & CREATE_RUNNING) { - /* still in CreateWindow */ - RECT rcWin; - - if ((INT)wParam != SIZE_RESTORED) { - ERR("WM_SIZE in create and flags=%08x, lParam=%08lx\n", - wParam, lParam); - } - - TRACE("still in CreateWindow\n"); - infoPtr->fStatus &= ~CREATE_RUNNING; - GetWindowRect ( infoPtr->hwndSelf, &rcWin); - TRACE("win rect (%d,%d)-(%d,%d)\n", - rcWin.left, rcWin.top, rcWin.right, rcWin.bottom); - - if ((lParam == 0) && (rcWin.right-rcWin.left == 0) && - (rcWin.bottom-rcWin.top == 0)) { - /* native control seems to do this */ - GetClientRect (GetParent(infoPtr->hwndSelf), &rcClient); - TRACE("sizing rebar, message and client zero, parent client (%d,%d)\n", - rcClient.right, rcClient.bottom); - } - else { - INT cx, cy; - - cx = rcWin.right - rcWin.left; - cy = rcWin.bottom - rcWin.top; - if ((cx == LOWORD(lParam)) && (cy == HIWORD(lParam))) { - return 0; - } - - /* do the actual WM_SIZE request */ - GetClientRect (infoPtr->hwndSelf, &rcClient); - TRACE("sizing rebar from (%d,%d) to (%d,%d), client (%d,%d)\n", - infoPtr->calcSize.cx, infoPtr->calcSize.cy, - LOWORD(lParam), HIWORD(lParam), - rcClient.right, rcClient.bottom); - } - infoPtr->fStatus |= BAND_NEEDS_LAYOUT; - REBAR_Layout(infoPtr, &rcClient, TRUE); - return 0; - } - else { - if ((INT)wParam != SIZE_RESTORED) { - ERR("WM_SIZE out of create and flags=%08x, lParam=%08lx\n", - wParam, lParam); - } - - /* Handle cases when outside of the CreateWindow process */ - - GetClientRect (infoPtr->hwndSelf, &rcClient); - if ((lParam == 0) && (rcClient.right + rcClient.bottom != 0) && - (infoPtr->dwStyle & RBS_AUTOSIZE)) { - /* on a WM_SIZE to zero and current client not zero and AUTOSIZE */ - /* native seems to use the current parent width for the size */ - infoPtr->fStatus |= BAND_NEEDS_LAYOUT; - GetClientRect (GetParent(infoPtr->hwndSelf), &rcClient); - if (infoPtr->dwStyle & CCS_VERT) - rcClient.right = 0; - else - rcClient.bottom = 0; - TRACE("sizing rebar to parent (%d,%d) size is zero but AUTOSIZE set\n", - rcClient.right, rcClient.bottom); - } - else { - TRACE("sizing rebar from (%d,%d) to (%d,%d), client (%d,%d)\n", - infoPtr->calcSize.cx, infoPtr->calcSize.cy, - LOWORD(lParam), HIWORD(lParam), - rcClient.right, rcClient.bottom); - } - } - + + /* FIXME: wrong */ if (infoPtr->dwStyle & RBS_AUTOSIZE) { NMRBAUTOSIZE autosize; @@ -3502,11 +3399,8 @@ REBAR_Size (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam) autosize.rcTarget.right, autosize.rcTarget.bottom, lParam); } - if (((infoPtr->calcSize.cx != rcClient.right) || (infoPtr->calcSize.cy != rcClient.bottom))) - { - infoPtr->fStatus |= BAND_NEEDS_LAYOUT; - REBAR_Layout(infoPtr, &rcClient, TRUE); - } + infoPtr->fStatus |= BAND_NEEDS_LAYOUT; + REBAR_Layout(infoPtr, NULL, TRUE); return 0; } @@ -3548,13 +3442,9 @@ static LRESULT theme_changed (REBAR_INFO* infoPtr) static LRESULT REBAR_WindowPosChanged (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam) { - WINDOWPOS *lpwp = (WINDOWPOS *)lParam; LRESULT ret; RECT rc; - /* Save the new origin of this window - used by _ForceResize */ - infoPtr->origin.x = lpwp->x; - infoPtr->origin.y = lpwp->y; ret = DefWindowProcW(infoPtr->hwndSelf, WM_WINDOWPOSCHANGED, wParam, lParam); GetWindowRect(infoPtr->hwndSelf, &rc); diff --git a/dlls/comctl32/tests/rebar.c b/dlls/comctl32/tests/rebar.c index a17e002dc40..daff87ff433 100644 --- a/dlls/comctl32/tests/rebar.c +++ b/dlls/comctl32/tests/rebar.c @@ -34,6 +34,12 @@ static HWND hRebar; val.left == exp.left && val.right == exp.right, "invalid rect (" name ") (%d,%d) (%d,%d) - expected (%d,%d) (%d,%d)\n", \ val.left, val.top, val.right, val.bottom, exp.left, exp.top, exp.right, exp.bottom); +#define check_rect_no_top(name, val, exp) { \ + ok((val.bottom - val.top == exp.bottom - exp.top) && \ + val.left == exp.left && val.right == exp.right, "invalid rect (" name ") (%d,%d) (%d,%d) - expected (%d,%d) (%d,%d), ignoring top\n", \ + val.left, val.top, val.right, val.bottom, exp.left, exp.top, exp.right, exp.bottom); \ + } + #define compare(val, exp, format) ok((val) == (exp), #val " value " format " expected " format "\n", (val), (exp)); #define expect_eq(expr, value, type, format) { type ret = expr; ok((value) == ret, #expr " expected " format " got " format "\n", (value), (ret)); } @@ -429,6 +435,182 @@ static void layout_test() DestroyWindow(hRebar); } +#if 0 /* use this to generate more tests */ + +static void dump_client(HWND hRebar) +{ + RECT r; + GetWindowRect(hRebar, &r); + MapWindowPoints(HWND_DESKTOP, hMainWnd, (LPPOINT)&r, 2); + printf(" {{%d, %d, %d, %d}, %d},\n", r.left, r.top, r.right, r.bottom, SendMessage(hRebar, RB_GETROWCOUNT, 0, 0)); +} + +#define comment(fmt, arg1) +#define check_client() dump_client(hRebar) + +#else + +typedef struct { + RECT rc; + INT iNumRows; +} rbresize_test_result_t; + +rbresize_test_result_t resize_results[] = { +/* style 00000001 */ + {{0, 2, 672, 2}, 0}, + {{0, 2, 672, 22}, 1}, + {{0, 2, 672, 22}, 1}, + {{0, 2, 672, 22}, 1}, +/* style 00000041 */ + {{0, 0, 672, 0}, 0}, + {{0, 0, 672, 20}, 1}, + {{0, 0, 672, 20}, 1}, + {{0, 0, 672, 20}, 1}, +/* style 00000003 */ + {{0, 226, 672, 226}, 0}, + {{0, 206, 672, 226}, 1}, + {{0, 206, 672, 226}, 1}, + {{0, 206, 672, 226}, 1}, +/* style 00000043 */ + {{0, 226, 672, 226}, 0}, + {{0, 206, 672, 226}, 1}, + {{0, 206, 672, 226}, 1}, + {{0, 206, 672, 226}, 1}, +/* style 00000080 */ + {{2, 0, 2, 226}, 0}, + {{2, 0, 22, 226}, 1}, + {{2, 0, 22, 226}, 1}, + {{2, 0, 22, 226}, 1}, +/* style 00000083 */ + {{672, 0, 672, 226}, 0}, + {{652, 0, 672, 226}, 1}, + {{652, 0, 672, 226}, 1}, + {{652, 0, 672, 226}, 1}, +/* style 00000008 */ + {{10, 11, 510, 11}, 0}, + {{10, 15, 510, 35}, 1}, + {{10, 17, 510, 37}, 1}, + {{10, 14, 110, 54}, 2}, + {{0, 4, 0, 44}, 2}, + {{0, 6, 0, 46}, 2}, + {{0, 8, 0, 48}, 2}, +/* style 00000048 */ + {{10, 5, 510, 5}, 0}, + {{10, 5, 510, 25}, 1}, + {{10, 5, 510, 25}, 1}, + {{10, 10, 110, 50}, 2}, + {{0, 0, 0, 40}, 2}, + {{0, 0, 0, 40}, 2}, + {{0, 0, 0, 40}, 2}, +/* style 00000004 */ + {{10, 5, 510, 20}, 0}, + {{10, 5, 510, 20}, 1}, + {{10, 10, 110, 110}, 2}, + {{0, 0, 0, 0}, 2}, + {{0, 0, 0, 0}, 2}, + {{0, 0, 0, 0}, 2}, +/* style 00000002 */ + {{0, 5, 672, 5}, 0}, + {{0, 5, 672, 25}, 1}, + {{0, 10, 672, 30}, 1}, + {{0, 0, 672, 20}, 1}, +/* style 00000082 */ + {{10, 0, 10, 226}, 0}, + {{10, 0, 30, 226}, 1}, + {{10, 0, 30, 226}, 1}, + {{0, 0, 20, 226}, 1}, +/* style 00800001 */ + {{-2, 0, 674, 4}, 0}, + {{-2, 0, 674, 24}, 1}, + {{-2, 0, 674, 24}, 1}, + {{-2, 0, 674, 24}, 1}, +/* style 00800048 */ + {{10, 5, 510, 9}, 0}, + {{10, 5, 510, 29}, 1}, + {{10, 5, 510, 29}, 1}, + {{10, 10, 110, 54}, 2}, + {{0, 0, 0, 44}, 2}, + {{0, 0, 0, 44}, 2}, + {{0, 0, 0, 44}, 2}, +/* style 00800004 */ + {{10, 5, 510, 20}, 0}, + {{10, 5, 510, 20}, 1}, + {{10, 10, 110, 110}, 2}, + {{0, 0, 0, 0}, 2}, + {{0, 0, 0, 0}, 2}, + {{0, 0, 0, 0}, 2}, +/* style 00800002 */ + {{-2, 5, 674, 9}, 0}, + {{-2, 5, 674, 29}, 1}, + {{-2, 10, 674, 34}, 1}, + {{-2, 0, 674, 24}, 1}, +}; + +static int resize_numtests = 0; + +#define comment(fmt, arg1) +#define check_client() { \ + RECT r; \ + rbresize_test_result_t *res = &resize_results[resize_numtests++]; \ + assert(resize_numtests <= sizeof(resize_results)/sizeof(resize_results[0])); \ + GetWindowRect(hRebar, &r); \ + MapWindowPoints(HWND_DESKTOP, hMainWnd, (LPPOINT)&r, 2); \ + if ((dwStyles[i] & (CCS_NOPARENTALIGN|CCS_NODIVIDER)) == CCS_NOPARENTALIGN) {\ + check_rect_no_top("client", r, res->rc); /* the top coordinate changes after every layout and very implementation-dependent */ \ + } else { \ + check_rect("client", r, res->rc); \ + } \ + expect_eq((int)SendMessage(hRebar, RB_GETROWCOUNT, 0, 0), res->iNumRows, int, "%d"); \ + } + +#endif + +static void resize_test() +{ + HWND hRebar; + DWORD dwStyles[] = {CCS_TOP, CCS_TOP | CCS_NODIVIDER, CCS_BOTTOM, CCS_BOTTOM | CCS_NODIVIDER, CCS_VERT, CCS_RIGHT, + CCS_NOPARENTALIGN, CCS_NOPARENTALIGN | CCS_NODIVIDER, CCS_NORESIZE, CCS_NOMOVEY, CCS_NOMOVEY | CCS_VERT, + CCS_TOP | WS_BORDER, CCS_NOPARENTALIGN | CCS_NODIVIDER | WS_BORDER, CCS_NORESIZE | WS_BORDER, + CCS_NOMOVEY | WS_BORDER}; + + const int styles_count = sizeof(dwStyles) / sizeof(dwStyles[0]); + int i; + + for (i = 0; i < styles_count; i++) + { + comment("style %08x", dwStyles[i]); + hRebar = CreateWindow(REBARCLASSNAME, "A", dwStyles[i] | WS_CHILD | WS_VISIBLE, 10, 5, 500, 15, hMainWnd, NULL, GetModuleHandle(NULL), 0); + check_client(); + add_band_w(hRebar, NULL, 70, 100, 0); + if (dwStyles[i] & CCS_NOPARENTALIGN) /* the window drifts downward for CCS_NOPARENTALIGN without CCS_NODIVIDER */ + check_client(); + add_band_w(hRebar, NULL, 70, 100, 0); + check_client(); + MoveWindow(hRebar, 10, 10, 100, 100, TRUE); + check_client(); + MoveWindow(hRebar, 0, 0, 0, 0, TRUE); + check_client(); + /* try to fool the rebar by sending invalid width/height - won't work */ + if (dwStyles[i] & (CCS_NORESIZE | CCS_NOPARENTALIGN)) + { + WINDOWPOS pos; + pos.hwnd = hRebar; + pos.hwndInsertAfter = NULL; + pos.cx = 500; + pos.cy = 500; + pos.x = 10; + pos.y = 10; + pos.flags = 0; + SendMessage(hRebar, WM_WINDOWPOSCHANGING, 0, (LPARAM)&pos); + SendMessage(hRebar, WM_WINDOWPOSCHANGED, 0, (LPARAM)&pos); + check_client(); + SendMessage(hRebar, WM_SIZE, SIZE_RESTORED, MAKELONG(500, 500)); + check_client(); + } + DestroyWindow(hRebar); + } +} + static void expect_band_content(UINT uBand, UINT fStyle, COLORREF clrFore, COLORREF clrBack, LPCSTR lpText, int iImage, HWND hwndChild, UINT cxMinChild, UINT cyMinChild, UINT cx, HBITMAP hbmBack, UINT wID, @@ -550,6 +732,7 @@ START_TEST(rebar) bandinfo_test(); layout_test(); + resize_test(); PostQuitMessage(0); while(GetMessageA(&msg,0,0,0)) { TranslateMessage(&msg);