comctl32: rebar: Test and fix the WM_SIZE handler and REBAR_ForceResize.

This commit is contained in:
Mikołaj Zalewski 2007-02-19 14:09:24 +01:00 committed by Alexandre Julliard
parent f0a7a74666
commit ffbf61ae55
3 changed files with 262 additions and 186 deletions

View File

@ -38,6 +38,9 @@
extern HMODULE COMCTL32_hModule; extern HMODULE COMCTL32_hModule;
extern HBRUSH COMCTL32_hPattern55AABrush; extern HBRUSH COMCTL32_hPattern55AABrush;
/* has a value of: 0, CCS_TOP, CCS_NOMOVEY, CCS_BOTTOM */
#define CCS_LAYOUT_MASK 0x3
/* Property sheet / Wizard */ /* Property sheet / Wizard */
#define IDD_PROPSHEET 1006 #define IDD_PROPSHEET 1006
#define IDD_WIZARD 1020 #define IDD_WIZARD 1020

View File

@ -32,9 +32,7 @@
* - RBS_FIXEDORDER * - RBS_FIXEDORDER
* - RBS_REGISTERDROP * - RBS_REGISTERDROP
* - RBS_TOOLTIPS * - RBS_TOOLTIPS
* - CCS_NORESIZE * - RBS_AUTOSIZE
* - CCS_NOMOVEX
* - CCS_NOMOVEY
* Messages: * Messages:
* - RB_BEGINDRAG * - RB_BEGINDRAG
* - RB_DRAGMOVE * - RB_DRAGMOVE
@ -190,7 +188,6 @@ typedef struct
POINT dragNow; /* x,y of this MouseMove */ POINT dragNow; /* x,y of this MouseMove */
INT iOldBand; /* last band that had the mouse cursor over it */ INT iOldBand; /* last band that had the mouse cursor over it */
INT ihitoffset; /* offset of hotspot from gripper.left */ 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 ichevronhotBand; /* last band that had a hot chevron */
INT iGrabbedBand;/* band number of band whose gripper was grabbed */ INT iGrabbedBand;/* band number of band whose gripper was grabbed */
@ -200,11 +197,9 @@ typedef struct
/* fStatus flags */ /* fStatus flags */
#define BEGIN_DRAG_ISSUED 0x00000001 #define BEGIN_DRAG_ISSUED 0x00000001
#define AUTO_RESIZE 0x00000002 #define AUTO_RESIZE 0x00000002
#define RESIZE_ANYHOW 0x00000004
#define NTF_HGHTCHG 0x00000008 #define NTF_HGHTCHG 0x00000008
#define BAND_NEEDS_LAYOUT 0x00000010 #define BAND_NEEDS_LAYOUT 0x00000010
#define BAND_NEEDS_REDRAW 0x00000020 #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 */ /* 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 #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) static void translate_rect(REBAR_INFO *infoPtr, RECT *dest, const RECT *src)
{ {
if (infoPtr->dwStyle & CCS_VERT) { if (infoPtr->dwStyle & CCS_VERT) {
dest->top = src->left; int tmp;
dest->bottom = src->right; tmp = src->left;
dest->left = src->top; dest->left = src->top;
dest->top = tmp;
tmp = src->right;
dest->right = src->bottom; dest->right = src->bottom;
dest->bottom = tmp;
} else { } else {
*dest = *src; *dest = *src;
} }
@ -465,6 +465,16 @@ static int get_rect_cy(REBAR_INFO *infoPtr, RECT *lpRect)
return lpRect->bottom - lpRect->top; 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) static void round_child_height(REBAR_BAND *lpBand, int cyHeight)
{ {
int cy = 0; int cy = 0;
@ -933,104 +943,71 @@ REBAR_ForceResize (REBAR_INFO *infoPtr)
/* Function: This changes the size of the REBAR window to that */ /* Function: This changes the size of the REBAR window to that */
/* calculated by REBAR_Layout. */ /* calculated by REBAR_Layout. */
{ {
RECT rc;
INT x, y, width, height; INT x, y, width, height;
INT xedge = GetSystemMetrics(SM_CXEDGE); INT xedge = 0, yedge = 0;
INT yedge = GetSystemMetrics(SM_CYEDGE); RECT rcSelf;
GetClientRect (infoPtr->hwndSelf, &rc); TRACE( "old [%d x %d], new [%d x %d]\n",
TRACE( " old [%d x %d], new [%d x %d], client [%d x %d]\n",
infoPtr->oldSize.cx, infoPtr->oldSize.cy, infoPtr->oldSize.cx, infoPtr->oldSize.cy,
infoPtr->calcSize.cx, infoPtr->calcSize.cy, infoPtr->calcSize.cx, infoPtr->calcSize.cy);
rc.right, rc.bottom);
if (infoPtr->dwStyle & CCS_NORESIZE) if (infoPtr->dwStyle & CCS_NORESIZE)
return; return;
/* If we need to shrink client, then skip size test */ if (infoPtr->dwStyle & WS_BORDER)
if ((infoPtr->calcSize.cy >= rc.bottom) && {
(infoPtr->calcSize.cx >= rc.right)) { xedge = GetSystemMetrics(SM_CXEDGE);
yedge = GetSystemMetrics(SM_CYEDGE);
/* if size did not change then skip process */ /* swap for CCS_VERT? */
if ((infoPtr->oldSize.cx == infoPtr->calcSize.cx) &&
(infoPtr->oldSize.cy == infoPtr->calcSize.cy) &&
!(infoPtr->fStatus & RESIZE_ANYHOW))
{
TRACE("skipping reset\n");
return;
}
} }
infoPtr->fStatus &= ~RESIZE_ANYHOW; /* compute rebar window rect in parent client coordinates */
/* Set flag to ignore next WM_SIZE message */ GetWindowRect(infoPtr->hwndSelf, &rcSelf);
infoPtr->fStatus |= AUTO_RESIZE; MapWindowPoints(HWND_DESKTOP, GetParent(infoPtr->hwndSelf), (LPPOINT)&rcSelf, 2);
translate_rect(infoPtr, &rcSelf, &rcSelf);
width = 0;
height = 0;
x = 0;
y = 0;
if (infoPtr->dwStyle & WS_BORDER) {
width = 2 * xedge;
height = 2 * yedge;
}
height = (infoPtr->dwStyle & CCS_VERT ? infoPtr->calcSize.cx : infoPtr->calcSize.cy) + 2*yedge;
if (!(infoPtr->dwStyle & CCS_NOPARENTALIGN)) { if (!(infoPtr->dwStyle & CCS_NOPARENTALIGN)) {
INT mode = infoPtr->dwStyle & (CCS_VERT | CCS_TOP | CCS_BOTTOM); RECT rcParent;
RECT rcPcl; SIZE calcSize;
GetClientRect(GetParent(infoPtr->hwndSelf), &rcPcl); x = -xedge;
switch (mode) { width = (infoPtr->dwStyle & CCS_VERT ? infoPtr->calcSize.cy : infoPtr->calcSize.cx) + 2*xedge;
case CCS_TOP: y = 0; /* quiet compiler warning */
/* _TOP sets width to parents width */ switch ( infoPtr->dwStyle & CCS_LAYOUT_MASK) {
width += (rcPcl.right - rcPcl.left); case 0: /* shouldn't happen - see NCCreate */
height += infoPtr->calcSize.cy; case CCS_TOP:
x += ((infoPtr->dwStyle & WS_BORDER) ? -xedge : 0); y = ((infoPtr->dwStyle & CCS_NODIVIDER) ? 0 : REBAR_DIVIDER) - yedge;
y += ((infoPtr->dwStyle & WS_BORDER) ? -yedge : 0); break;
y += ((infoPtr->dwStyle & CCS_NODIVIDER) ? 0 : REBAR_DIVIDER); case CCS_NOMOVEY:
break; y = rcSelf.top;
case CCS_BOTTOM: break;
/* FIXME: wrong wrong wrong */ case CCS_BOTTOM:
/* _BOTTOM sets width to parents width */ GetClientRect(GetParent(infoPtr->hwndSelf), &rcParent);
width += (rcPcl.right - rcPcl.left); translate_rect(infoPtr, &rcParent, &rcParent);
height += infoPtr->calcSize.cy; calcSize = infoPtr->calcSize;
x += -xedge; swap_size_if_vert(infoPtr, &calcSize);
y = rcPcl.bottom - height + 1; y = rcParent.bottom - calcSize.cy - yedge;
break; 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;
} }
} }
else { else {
width += infoPtr->calcSize.cx; x = rcSelf.left;
height += infoPtr->calcSize.cy; /* As on Windows if the CCS_NODIVIDER is not present the control will move
x = infoPtr->origin.x; * 2 pixel down after every layout */
y = infoPtr->origin.y; 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", TRACE("hwnd %p, style=%08x, setting at (%d,%d) for (%d,%d)\n",
infoPtr->hwndSelf, infoPtr->dwStyle, infoPtr->hwndSelf, infoPtr->dwStyle, x, y, width, height);
x, y, width, height);
SetWindowPos (infoPtr->hwndSelf, 0, x, y, width, height, /* Set flag to ignore next WM_SIZE message and resize the window */
SWP_NOZORDER); 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; 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) static int next_band(REBAR_INFO *infoPtr, int i)
{ {
int n; int n;
@ -1394,7 +1361,7 @@ REBAR_Layout(REBAR_INFO *infoPtr, LPRECT lpRect, BOOL notify)
if (lpRect) { if (lpRect) {
rcAdj = *lpRect; rcAdj = *lpRect;
cyTarget = get_rect_cy(infoPtr, 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); GetClientRect(infoPtr->hwndSelf, &rcAdj);
else else
GetClientRect(GetParent(infoPtr->hwndSelf), &rcAdj); GetClientRect(GetParent(infoPtr->hwndSelf), &rcAdj);
@ -2010,7 +1977,6 @@ REBAR_DeleteBand (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
TRACE("setting NEEDS_LAYOUT\n"); TRACE("setting NEEDS_LAYOUT\n");
infoPtr->fStatus |= BAND_NEEDS_LAYOUT; infoPtr->fStatus |= BAND_NEEDS_LAYOUT;
infoPtr->fStatus |= RESIZE_ANYHOW;
REBAR_Layout(infoPtr, NULL, TRUE); REBAR_Layout(infoPtr, NULL, TRUE);
return TRUE; return TRUE;
@ -3150,7 +3116,7 @@ REBAR_NCCreate (HWND hwnd, WPARAM wParam, LPARAM lParam)
infoPtr->hcurHorz = LoadCursorW (0, (LPWSTR)IDC_SIZEWE); infoPtr->hcurHorz = LoadCursorW (0, (LPWSTR)IDC_SIZEWE);
infoPtr->hcurVert = LoadCursorW (0, (LPWSTR)IDC_SIZENS); infoPtr->hcurVert = LoadCursorW (0, (LPWSTR)IDC_SIZENS);
infoPtr->hcurDrag = LoadCursorW (0, (LPWSTR)IDC_SIZE); infoPtr->hcurDrag = LoadCursorW (0, (LPWSTR)IDC_SIZE);
infoPtr->fStatus = CREATE_RUNNING; infoPtr->fStatus = 0;
infoPtr->hFont = GetStockObject (SYSTEM_FONT); infoPtr->hFont = GetStockObject (SYSTEM_FONT);
/* issue WM_NOTIFYFORMAT to get unicode status of parent */ /* 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 */ /* Stow away the original style */
infoPtr->orgStyle = cs->style; infoPtr->orgStyle = cs->style;
/* add necessary styles to the requested styles */ /* 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); SetWindowLongW (hwnd, GWL_STYLE, infoPtr->dwStyle);
/* get font handle for Caption Font */ /* get font handle for Caption Font */
@ -3409,88 +3377,17 @@ REBAR_SetRedraw (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
static LRESULT static LRESULT
REBAR_Size (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam) 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) { if (infoPtr->fStatus & AUTO_RESIZE) {
infoPtr->fStatus &= ~AUTO_RESIZE; infoPtr->fStatus &= ~AUTO_RESIZE;
TRACE("AUTO_RESIZE was set, reset, fStatus=%08x lparam=%08lx\n", TRACE("AUTO_RESIZE was set, reset, fStatus=%08x lparam=%08lx\n",
infoPtr->fStatus, lParam); infoPtr->fStatus, lParam);
return 0; return 0;
} }
if (infoPtr->fStatus & CREATE_RUNNING) { /* FIXME: wrong */
/* 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);
}
}
if (infoPtr->dwStyle & RBS_AUTOSIZE) { if (infoPtr->dwStyle & RBS_AUTOSIZE) {
NMRBAUTOSIZE autosize; NMRBAUTOSIZE autosize;
@ -3502,11 +3399,8 @@ REBAR_Size (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
autosize.rcTarget.right, autosize.rcTarget.bottom, 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, NULL, TRUE);
infoPtr->fStatus |= BAND_NEEDS_LAYOUT;
REBAR_Layout(infoPtr, &rcClient, TRUE);
}
return 0; return 0;
} }
@ -3548,13 +3442,9 @@ static LRESULT theme_changed (REBAR_INFO* infoPtr)
static LRESULT static LRESULT
REBAR_WindowPosChanged (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam) REBAR_WindowPosChanged (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
{ {
WINDOWPOS *lpwp = (WINDOWPOS *)lParam;
LRESULT ret; LRESULT ret;
RECT rc; 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, ret = DefWindowProcW(infoPtr->hwndSelf, WM_WINDOWPOSCHANGED,
wParam, lParam); wParam, lParam);
GetWindowRect(infoPtr->hwndSelf, &rc); GetWindowRect(infoPtr->hwndSelf, &rc);

View File

@ -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 == 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); 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 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)); } #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); 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, static void expect_band_content(UINT uBand, UINT fStyle, COLORREF clrFore,
COLORREF clrBack, LPCSTR lpText, int iImage, HWND hwndChild, COLORREF clrBack, LPCSTR lpText, int iImage, HWND hwndChild,
UINT cxMinChild, UINT cyMinChild, UINT cx, HBITMAP hbmBack, UINT wID, UINT cxMinChild, UINT cyMinChild, UINT cx, HBITMAP hbmBack, UINT wID,
@ -550,6 +732,7 @@ START_TEST(rebar)
bandinfo_test(); bandinfo_test();
layout_test(); layout_test();
resize_test();
PostQuitMessage(0); PostQuitMessage(0);
while(GetMessageA(&msg,0,0,0)) { while(GetMessageA(&msg,0,0,0)) {
TranslateMessage(&msg); TranslateMessage(&msg);