comctl32: rebar[2/4]: test and fix the WM_SIZE handler and
REBAR_ForceResize
Mikołaj Zalewski
mikolaj at zalewski.pl
Sat Feb 17 15:29:37 CST 2007
The first patch is quite big it may not appear immediatelly but will
have to wait for the moderator. It is based on my previous patch:
http://www.winehq.org/pipermail/wine-patches/2007-February/035479.html
with tests for RB_MAXIMIZE/RB_MINIMIZE and some fixes. In this patch I
test and fix another source of possible problems: the WM_SIZE handler
and REBAR_ForceResize. The thrid and fourth patch contains some cosmetic
changes. These patches fixes all the rebar bugs I've found in Bugzilla:
#1115, #3169, #3501 and #6632. I also haven't noticed problems in
Process Explorer. The only thing I know is broken are the sidebars of IE
(but that's not a regression).
There is a problem that these patches conflicts with the /Misha
Koshelev patches (the first patch contains the handling of CCS_NORESIZE,
Misha tests patch changes the prototype of rebuild_toolbar in a way that
will make my tests not to compile) but if Misha's patches will be
commited I'll try to fix my patches to resolve the conflict.
/
-------------- next part --------------
From 72414e2fc1fa13daff05b189d92508a88556a466 Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Miko=C5=82aj_Zalewski?= <mikolaj at zalewski.pl>
Date: Sat, 17 Feb 2007 19:30:34 +0100
Subject: [PATCH] comctl32: rebar: test and fix the WM_SIZE handler and REBAR_ForceResize
---
dlls/comctl32/comctl32.h | 3 +
dlls/comctl32/rebar.c | 264 +++++++++++++------------------------------
dlls/comctl32/tests/rebar.c | 183 ++++++++++++++++++++++++++++++
3 files changed, 263 insertions(+), 187 deletions(-)
diff --git a/dlls/comctl32/comctl32.h b/dlls/comctl32/comctl32.h
index 66a0973..e7a3598 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 9da110c..0a196ba 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;
-
- 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;
+ RECT rcParent;
+ SIZE calcSize;
+
+ 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 2633dcb..5c179ef 100644
--- a/dlls/comctl32/tests/rebar.c
+++ b/dlls/comctl32/tests/rebar.c
@@ -33,6 +33,12 @@ static HWND hRebar;
#define check_rect(name, val, exp) ok(val.top == exp.top && val.bottom == exp.bottom && \
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));
@@ -428,6 +434,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,
@@ -549,6 +731,7 @@ START_TEST(rebar)
bandinfo_test();
layout_test();
+ resize_test();
PostQuitMessage(0);
while(GetMessageA(&msg,0,0,0)) {
TranslateMessage(&msg);
--
1.4.4.2
More information about the wine-patches
mailing list