- Fix handling of text color.
- Correct implementation of WM_SETREDRAW to be closer to native.
- Do more implementation of RBS_AUTOSIZE in the WM_SIZE processor.
- Implement RBBS_VARIABLEHEIGHT. Used by IE4.
- Do more testing in WM_SIZE to handle strange cases like native.
diff --git a/dlls/comctl32/rebar.c b/dlls/comctl32/rebar.c
index c96efde..4b5bb82 100644
--- a/dlls/comctl32/rebar.c
+++ b/dlls/comctl32/rebar.c
@@ -8,7 +8,7 @@
#define PROBLEM2 0
/*
- * Rebar control rev 7e
+ * Rebar control rev 7f
*
* Copyright 1998, 1999 Eric Kohl
*
@@ -82,11 +82,20 @@
* 23. Support RB_MINIMIZEBAND.
* 24. RBBS_HIDDEN (and the CCS_VERT+RBBS_NOVERT case) should be supported
* by all routines now.
+ * rev 7f
+ * 25. Fix handling of text color.
+ * 26. Correct implementation of WM_SETREDRAW to be closer to native.
+ * See REBAR_SetRedraw for doc changes of actual vs. MSDN
+ * 27. Do more implementation of RBS_AUTOSIZE in the WM_SIZE processor.
+ * 28. Implement RBBS_VARIABLEHEIGHT. Used by IE4.
+ * 29. Do more testing in WM_SIZE to handle strange cases like native.
*
*
* Still to do:
* 2. Following still not handled: RBBS_FIXEDBMP, RBBS_CHILDEDGE,
* RBBS_USECHEVRON
+ * 3. Following are only partially handled:
+ * RBS_AUTOSIZE, RBBS_VARIABLEHEIGHT
* 5. Native uses (on each draw!!) SM_CYBORDER (or SM_CXBORDER for CCS_VERT)
* to set the size of the separator width (the value SEP_WIDTH_SIZE
* in here). Should be fixed!!
@@ -106,6 +115,7 @@
#include <stdlib.h>
#include <string.h>
+#include "win.h"
#include "winbase.h"
#include "wingdi.h"
#include "wine/unicode.h"
@@ -176,6 +186,7 @@
{
COLORREF clrBk; /* background color */
COLORREF clrText; /* text color */
+ COLORREF clrBtnText; /* system color for BTNTEXT */
COLORREF clrBtnFace; /* system color for BTNFACE */
HIMAGELIST himl; /* handle to imagelist */
UINT uNumBands; /* # of bands in rebar (first=0, last=uNumRows-1 */
@@ -211,6 +222,8 @@
#define RESIZE_ANYHOW 0x00000004
#define NTF_HGHTCHG 0x00000008
#define BAND_NEEDS_LAYOUT 0x00000010
+#define BAND_NEEDS_REDRAW 0x00000020
+#define CREATE_RUNNING 0x00000040
/* ---- REBAR layout constants. Mostly determined by ---- */
/* ---- experiment on WIN 98. ---- */
@@ -385,6 +398,9 @@
iP->hwndSelf, iP->fStatus, iP->dragStart.x, iP->dragStart.y,
iP->dragNow.x, iP->dragNow.y,
iP->ihitBand);
+ TRACE("hwnd=%04x: style=%08lx, I'm Unicode=%s, notify in Unicode=%s, redraw=%s\n",
+ iP->hwndSelf, iP->dwStyle, (iP->bUnicode)?"TRUE":"FALSE",
+ (iP->NtfUnicode)?"TRUE":"FALSE", (iP->DoRedraw)?"TRUE":"FALSE");
for (i = 0; i < iP->uNumBands; i++) {
pB = &iP->bands[i];
TRACE("band # %u: ID=%u, child=%04x, row=%u, clrF=0x%06lx, clrB=0x%06lx\n",
@@ -512,14 +528,13 @@
HFONT hOldFont = SelectObject (hdc, infoPtr->hFont);
INT oldBkMode = SetBkMode (hdc, TRANSPARENT);
COLORREF oldcolor = CLR_NONE;
- if (lpBand->clrFore != CLR_NONE)
- oldcolor = SetTextColor (hdc, lpBand->clrFore);
+ oldcolor = SetTextColor (hdc, (lpBand->clrFore != CLR_NONE) ?
+ lpBand->clrFore : infoPtr->clrBtnText);
DrawTextW (hdc, lpBand->lpText, -1, &lpBand->rcCapText,
DT_CENTER | DT_VCENTER | DT_SINGLELINE);
if (oldBkMode != TRANSPARENT)
SetBkMode (hdc, oldBkMode);
- if (lpBand->clrFore != CLR_NONE)
- SetTextColor (hdc, oldcolor);
+ SetTextColor (hdc, oldcolor);
SelectObject (hdc, hOldFont);
}
}
@@ -671,7 +686,8 @@
}
if ((x >= maxx) || last_adjusted) {
if (x > maxx) {
- ERR("Phase 1 failed, x=%d, maxx=%d\n", x, maxx);
+ ERR("Phase 1 failed, x=%d, maxx=%d, start=%u, end=%u\n",
+ x, maxx, rowstart, rowend);
}
/* done, so spread extra space */
if (x < maxx) {
@@ -740,7 +756,8 @@
}
if (x >= maxx) {
if (x > maxx) {
- ERR("Phase 2 failed, x=%d, maxx=%d\n", x, maxx);
+ ERR("Phase 2 failed, x=%d, maxx=%d, start=%u, end=%u\n",
+ x, maxx, rowstart, rowend);
}
/* done, so spread extra space */
TRACE("Phase 2 succeeded, used x=%d\n", x);
@@ -1132,7 +1149,7 @@
yPos = (lpBand->rcChild.bottom + lpBand->rcChild.top - nEditHeight)/2;
/* center combo box inside child area */
- TRACE("moving child (Combo(Ex)) %04x to (%d,%d)-(%d,%d)\n",
+ TRACE("moving child (Combo(Ex)) %04x to (%d,%d) for (%d,%d)\n",
lpBand->hwndChild,
lpBand->rcChild.left, yPos,
lpBand->rcChild.right - lpBand->rcChild.left,
@@ -1147,7 +1164,7 @@
ERR("DeferWindowPos returned NULL\n");
}
else {
- TRACE("moving child (Other) %04x to (%d,%d)-(%d,%d)\n",
+ TRACE("moving child (Other) %04x to (%d,%d) for (%d,%d)\n",
lpBand->hwndChild,
lpBand->rcChild.left, lpBand->rcChild.top,
lpBand->rcChild.right - lpBand->rcChild.left,
@@ -1191,6 +1208,7 @@
return;
}
infoPtr->fStatus &= ~BAND_NEEDS_LAYOUT;
+ if (!infoPtr->DoRedraw) infoPtr->fStatus |= BAND_NEEDS_REDRAW;
GetClientRect (infoPtr->hwndSelf, &rcClient);
TRACE("Client is (%d,%d)-(%d,%d)\n",
@@ -1215,6 +1233,12 @@
clientcy = adjcy;
}
+ if (!infoPtr->DoRedraw && (clientcx == 0) && (clientcy == 0)) {
+ ERR("no redraw and client is zero, skip layout\n");
+ infoPtr->fStatus |= BAND_NEEDS_LAYOUT;
+ return;
+ }
+
/* save height of original control */
if (infoPtr->dwStyle & CCS_VERT)
origheight = infoPtr->calcSize.cx;
@@ -1224,6 +1248,8 @@
/* ******* Start Phase 1 - all bands on row at minimum size ******* */
+ TRACE("band loop constants, clientcx=%d, clientcy=%d\n",
+ clientcx, clientcy);
x = 0;
y = 0;
row = 1;
@@ -1306,6 +1332,9 @@
}
}
+ TRACE("band %u, row %d, x=%d, y=%d, cxsep=%d, cx=%d\n",
+ i, row,
+ x, y, cxsep, cx);
if (infoPtr->dwStyle & CCS_VERT) {
/* bound the bottom side if we have a bounding rectangle */
rightx = clientcx;
@@ -1502,6 +1531,61 @@
/* ******* End Phase 2 - split rows till adjustment height full ******* */
+ /* ******* Start Phase 2a - adjust all bands for height full ******* */
+ /* assumes that the following variables contain: */
+ /* y/x current height/width of all rows */
+ /* clientcy/clientcx height/width of client area */
+
+ /* **** FIXME FIXME FIXME
+ * this does not take into account that more than one band
+ * is in a row!!!!!!!!!
+ */
+
+ if (((infoPtr->dwStyle & CCS_VERT) ? clientcx > x : clientcy > y) &&
+ infoPtr->uNumBands) {
+ INT diff, i, j;
+
+ diff = (infoPtr->dwStyle & CCS_VERT) ? clientcx - x : clientcy - y;
+ for (i = infoPtr->uNumBands-1; i >= 0; i--) {
+ lpBand = &infoPtr->bands[i];
+ if(HIDDENBAND(lpBand)) continue;
+ if (!lpBand->fMask & RBBS_VARIABLEHEIGHT) continue;
+ if (((INT)lpBand->cyMaxChild < 1) ||
+ ((INT)lpBand->cyIntegral < 1)) {
+ if (lpBand->cyMaxChild + lpBand->cyIntegral == 0) continue;
+ ERR("band %u RBBS_VARIABLEHEIGHT set but cyMax=%d, cyInt=%d\n",
+ i, lpBand->cyMaxChild, lpBand->cyIntegral);
+ continue;
+ }
+ /* j is now the maximum height/width in the client area */
+ j = ((diff / lpBand->cyIntegral) * lpBand->cyIntegral) +
+ ircBw(lpBand);
+ if (j > lpBand->cyMaxChild + REBARSPACE)
+ j = lpBand->cyMaxChild + REBARSPACE;
+ diff -= (j - ircBw(lpBand));
+ if (infoPtr->dwStyle & CCS_VERT)
+ lpBand->rcBand.right = lpBand->rcBand.left + j;
+ else
+ lpBand->rcBand.bottom = lpBand->rcBand.top + j;
+ TRACE("P2a band %d, row %d changed to (%d,%d)-(%d,%d)\n",
+ i, lpBand->iRow,
+ lpBand->rcBand.left, lpBand->rcBand.top,
+ lpBand->rcBand.right, lpBand->rcBand.bottom);
+ if (diff <= 0) break;
+ }
+ if (diff < 0) {
+ ERR("allocated more than available, diff=%d\n", diff);
+ diff = 0;
+ }
+ if (infoPtr->dwStyle & CCS_VERT)
+ x = clientcx - diff;
+ else
+ y = clientcy - diff;
+ }
+
+ /* ******* End Phase 2a - adjust all bands for height full ******* */
+
+
/* ******* Start Phase 3 - adjust all bands for width full ******* */
if (infoPtr->uNumBands) {
@@ -3080,7 +3164,7 @@
REBAR_DumpBand (infoPtr);
if (lprbbi->fMask & (RBBIM_CHILDSIZE | RBBIM_SIZE))
- REBAR_Layout (infoPtr, NULL, TRUE, FALSE);
+ REBAR_Layout (infoPtr, NULL, TRUE, FALSE);
return TRUE;
}
@@ -3321,9 +3405,6 @@
cs->x, cs->y, cs->cx, cs->cy);
}
- if (GetWindowLongA (infoPtr->hwndSelf, GWL_STYLE) & RBS_AUTOSIZE)
- FIXME("style RBS_AUTOSIZE set!\n");
-
TRACE("created!\n");
return 0;
}
@@ -3537,7 +3618,8 @@
/* initialize info structure - initial values are 0 */
infoPtr->clrBk = CLR_NONE;
- infoPtr->clrText = GetSysColor (COLOR_BTNTEXT);
+ infoPtr->clrText = CLR_NONE;
+ infoPtr->clrBtnText = GetSysColor (COLOR_BTNTEXT);
infoPtr->clrBtnFace = GetSysColor (COLOR_BTNFACE);
infoPtr->ihitBand = -1;
infoPtr->hwndSelf = hwnd;
@@ -3547,6 +3629,7 @@
infoPtr->hcurVert = LoadCursorA (0, IDC_SIZENSA);
infoPtr->hcurDrag = LoadCursorA (0, IDC_SIZEA);
infoPtr->bUnicode = IsWindowUnicode (hwnd);
+ infoPtr->fStatus = CREATE_RUNNING;
/* issue WM_NOTIFYFORMAT to get unicode status of parent */
i = SendMessageA(REBAR_GetNotifyParent (infoPtr),
@@ -3758,10 +3841,32 @@
inline static LRESULT
REBAR_SetRedraw (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
+ /*****************************************************
+ *
+ * Function;
+ * Handles the WM_SETREDRAW message.
+ *
+ * Documentation:
+ * According to testing V4.71 of COMCTL32 returns the
+ * *previous* status of the redraw flag (either 0 or -1)
+ * instead of the MSDN documented value of 0 if handled
+ *
+ *****************************************************/
{
- TRACE("set to %s\n", (wParam) ? "TRUE" : "FALSE");
+ BOOL oldredraw = infoPtr->DoRedraw;
+
+ TRACE("set to %s, fStatus=%08x\n",
+ (wParam) ? "TRUE" : "FALSE", infoPtr->fStatus);
infoPtr->DoRedraw = (BOOL) wParam;
- return 0;
+ if (wParam) {
+ if (infoPtr->fStatus & BAND_NEEDS_REDRAW) {
+ REBAR_MoveChildWindows (infoPtr, 0, infoPtr->uNumBands);
+ REBAR_ForceResize (infoPtr);
+ InvalidateRect (infoPtr->hwndSelf, 0, TRUE);
+ }
+ infoPtr->fStatus &= ~BAND_NEEDS_REDRAW;
+ }
+ return (oldredraw) ? -1 : 0;
}
@@ -3775,31 +3880,72 @@
infoPtr->fStatus &= ~AUTO_RESIZE;
TRACE("AUTO_RESIZE was set, reset, fStatus=%08x lparam=%08lx\n",
infoPtr->fStatus, lParam);
- if (infoPtr->dwStyle & RBS_AUTOSIZE) {
- NMRBAUTOSIZE autosize;
-
- GetClientRect(infoPtr->hwndSelf, &autosize.rcTarget);
- autosize.fChanged = 0; /* ??? */
- autosize.rcActual = autosize.rcTarget; /* ??? */
- REBAR_Notify((NMHDR *) &autosize, infoPtr, RBN_AUTOSIZE);
- TRACE("RBN_AUTOSIZE client=%d, lp=%08lx\n",
- autosize.rcTarget.bottom, lParam);
- }
return 0;
}
- GetClientRect (infoPtr->hwndSelf, &rcClient);
- if ((lParam == 0) && (rcClient.right == 0) && (rcClient.bottom == 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);
+ if (infoPtr->fStatus & CREATE_RUNNING) {
+ /* still in CreateWindow */
+ RECT rcWin;
+
+ 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 (%ld,%ld) to (%d,%d), client (%d,%d)\n",
+ infoPtr->calcSize.cx, infoPtr->calcSize.cy,
+ LOWORD(lParam), HIWORD(lParam),
+ rcClient.right, rcClient.bottom);
+ }
}
else {
- TRACE("sizing rebar from (%ld,%ld) to (%d,%d), client (%d,%d)\n",
- infoPtr->calcSize.cx, infoPtr->calcSize.cy,
- LOWORD(lParam), HIWORD(lParam),
- rcClient.right, rcClient.bottom);
+ /* 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 client rect for the size */
+ infoPtr->fStatus |= BAND_NEEDS_LAYOUT;
+ TRACE("sizing rebar to client (%d,%d) size is zero but AUTOSIZE set\n",
+ rcClient.right, rcClient.bottom);
+ }
+ else {
+ TRACE("sizing rebar from (%ld,%ld) 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) {
+ NMRBAUTOSIZE autosize;
+
+ GetClientRect(infoPtr->hwndSelf, &autosize.rcTarget);
+ autosize.fChanged = 0; /* ??? */
+ autosize.rcActual = autosize.rcTarget; /* ??? */
+ REBAR_Notify((NMHDR *) &autosize, infoPtr, RBN_AUTOSIZE);
+ TRACE("RBN_AUTOSIZE client=(%d,%d), lp=%08lx\n",
+ autosize.rcTarget.right, autosize.rcTarget.bottom, lParam);
}
if ((infoPtr->calcSize.cx != rcClient.right) ||
@@ -3821,6 +3967,7 @@
TRACE("current style=%08lx, styleOld=%08lx, style being set to=%08lx\n",
infoPtr->dwStyle, ss->styleOld, ss->styleNew);
infoPtr->dwStyle = ss->styleNew;
+
return FALSE;
}