sizing the page scroller control
Susan Farley
susan at codeweavers.com
Fri Feb 2 21:08:25 CST 2001
Please disregard my previous patch.
This one handles the sizing issues better, as well as properly checks
the return value of SendMessage from the PGN_NOTIFY msg before changing
the scroll delta.
Changelog:
* dlls/comctl32/pager.c
Handles the CCS_NORESIZE style.
Change the scroll delta only when the app responds to the PGN_NOTIFY
msg.
Susan Farley <susan at codeweavers.com>
-------------- next part --------------
Index: dlls/comctl32/pager.c
===================================================================
RCS file: /home/wine/wine/dlls/comctl32/pager.c,v
retrieving revision 1.21
diff -u -r1.21 pager.c
--- dlls/comctl32/pager.c 2001/01/26 20:43:41 1.21
+++ dlls/comctl32/pager.c 2001/02/03 02:53:47
@@ -24,6 +24,7 @@
typedef struct
{
HWND hwndChild; /* handle of the contained wnd */
+ BOOL bNoResize; /* set when created with CCS_NORESIZE */
BOOL bHorizontal;/* orientation of the control */
COLORREF clrBk; /* background color */
INT nBorder; /* border size for the control */
@@ -309,12 +310,12 @@
SetWindowPos(infoPtr->hwndChild, 0,
-nPos, 0,
infoPtr->nWidth, infoPtr->nHeight,
- SWP_NOZORDER);
+ SWP_NOZORDER);
}
else
{
TRACE("[%04x] SWP %dx%d at (%d,%d)\n", hwnd,
- infoPtr->nWidth, infoPtr->nHeight,
+ infoPtr->nWidth, infoPtr->nHeight,
0, -nPos);
SetWindowPos(infoPtr->hwndChild, 0,
0, -nPos,
@@ -350,6 +351,7 @@
childSize = infoPtr->nHeight;
}
+ TRACE("childSize = %d, wndSize = %d\n", childSize, wndSize);
if (childSize > wndSize)
scrollRange = childSize - wndSize + infoPtr->nButtonSize;
}
@@ -457,45 +459,120 @@
PAGER_INFO *infoPtr = PAGER_GetInfoPtr (hwnd);
INT scrollRange = PAGER_GetScrollRange(hwnd, infoPtr);
- if (scrollRange <= 0)
- newPos = 0;
- else if (newPos < 0)
- newPos = 0;
+ if ((scrollRange <= 0) || (newPos < 0))
+ infoPtr->nPos = 0;
else if (newPos > scrollRange)
- newPos = scrollRange;
-
- if (newPos != infoPtr->nPos)
- {
+ infoPtr->nPos = scrollRange;
+ else
infoPtr->nPos = newPos;
- TRACE("[%04x] pos=%d\n", hwnd, infoPtr->nPos);
+
+ TRACE("[%04x] pos=%d\n", hwnd, infoPtr->nPos);
+
+ /* gray and restore btns, and if from WM_SETPOS, hide the gray btns */
+ PAGER_UpdateBtns(hwnd, infoPtr, scrollRange, !fromBtnPress);
+ PAGER_PositionChildWnd(hwnd, infoPtr);
- /* gray and restore btns, and if from WM_SETPOS, hide the gray btns */
- PAGER_UpdateBtns(hwnd, infoPtr, scrollRange, !fromBtnPress);
+ return 0;
+}
- PAGER_PositionChildWnd(hwnd, infoPtr);
+static LRESULT
+PAGER_HandleWindowPosChanging(HWND hwnd, WINDOWPOS *winpos)
+{
+ PAGER_INFO *infoPtr = PAGER_GetInfoPtr (hwnd);
+
+ if (infoPtr->bNoResize && !(winpos->flags & SWP_NOSIZE))
+ {
+ /* don't let the app resize the nonscrollable dimension of a control
+ * that was created with CCS_NORESIZE style
+ * (i.e. height for a horizontal pager, or width for a vertical one) */
+
+ if (infoPtr->bHorizontal)
+ winpos->cy = infoPtr->nHeight;
+ else
+ winpos->cx = infoPtr->nWidth;
}
return 0;
}
+static void
+PAGER_SetFixedWidth(HWND hwnd, PAGER_INFO* infoPtr)
+{
+ /* Must set the non-scrollable dimension to be less than the full height/width
+ * so that NCCalcSize is called. The Msoft docs mention 3/4 factor for button
+ * size, and experimentation shows that affect is almost right. */
+
+ RECT wndRect;
+ INT delta;
+ GetWindowRect(hwnd, &wndRect);
+
+ /* see what the app says for btn width */
+ PAGER_CalcSize(hwnd, &infoPtr->nWidth, TRUE);
+
+ if (infoPtr->bNoResize)
+ {
+ delta = wndRect.right - wndRect.left - infoPtr->nWidth;
+ if (delta > infoPtr->nButtonSize)
+ infoPtr->nWidth += 4 * infoPtr->nButtonSize / 3;
+ else if (delta > 0)
+ infoPtr->nWidth += infoPtr->nButtonSize / 3;
+ }
+
+ infoPtr->nDelta = wndRect.bottom - wndRect.top - infoPtr->nButtonSize;
+
+ TRACE("[%04x] infoPtr->nWidth set to %d\n",
+ hwnd, infoPtr->nWidth);
+}
+
+static void
+PAGER_SetFixedHeight(HWND hwnd, PAGER_INFO* infoPtr)
+{
+ /* Must set the non-scrollable dimension to be less than the full height/width
+ * so that NCCalcSize is called. The Msoft docs mention 3/4 factor for button
+ * size, and experimentation shows that affect is almost right. */
+
+ RECT wndRect;
+ INT delta;
+ GetWindowRect(hwnd, &wndRect);
+
+ /* see what the app says for btn height */
+ PAGER_CalcSize(hwnd, &infoPtr->nHeight, FALSE);
+
+ if (infoPtr->bNoResize)
+ {
+ delta = wndRect.bottom - wndRect.top - infoPtr->nHeight;
+ if (delta > infoPtr->nButtonSize)
+ infoPtr->nHeight += 4 * infoPtr->nButtonSize / 3;
+ else if (delta > 0)
+ infoPtr->nHeight += infoPtr->nButtonSize / 3;
+ }
+
+ infoPtr->nDelta = wndRect.right - wndRect.left - infoPtr->nButtonSize;
+
+ TRACE("[%04x] infoPtr->nHeight set to %d\n",
+ hwnd, infoPtr->nHeight);
+}
+
static LRESULT
PAGER_RecalcSize(HWND hwnd)
{
PAGER_INFO *infoPtr = PAGER_GetInfoPtr (hwnd);
- INT scrollRange;
-
TRACE("[%04x]\n", hwnd);
- scrollRange = PAGER_GetScrollRange(hwnd, infoPtr);
- if (scrollRange <= 0)
- PAGER_SetPos(hwnd, 0, FALSE);
- else
+ if (infoPtr->hwndChild)
{
- PAGER_UpdateBtns(hwnd, infoPtr, scrollRange, TRUE);
- PAGER_PositionChildWnd(hwnd, infoPtr);
+ INT scrollRange = PAGER_GetScrollRange(hwnd, infoPtr);
+
+ if (scrollRange <= 0)
+ PAGER_SetPos(hwnd, 0, FALSE);
+ else
+ {
+ PAGER_UpdateBtns(hwnd, infoPtr, scrollRange, TRUE);
+ PAGER_PositionChildWnd(hwnd, infoPtr);
+ }
}
- return 0;
+ return 1;
}
@@ -544,7 +621,6 @@
}
-
static LRESULT
PAGER_SetChild (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
@@ -554,28 +630,18 @@
if (infoPtr->hwndChild)
{
- RECT wndRect;
- INT wndSizeScrollable;
-
TRACE("[%04x] hwndChild=%04x\n", hwnd, infoPtr->hwndChild);
- GetWindowRect(hwnd, &wndRect);
- wndSizeScrollable = infoPtr->bHorizontal ?
- wndRect.right - wndRect.left :
- wndRect.bottom - wndRect.top;
-
- infoPtr->nPos = 0;
- infoPtr->nDelta = wndSizeScrollable;
-
- PAGER_CalcSize(hwnd, &infoPtr->nWidth, TRUE);
- PAGER_CalcSize(hwnd, &infoPtr->nHeight, FALSE);
+ if (infoPtr->bHorizontal)
+ PAGER_SetFixedHeight(hwnd, infoPtr);
+ else
+ PAGER_SetFixedWidth(hwnd, infoPtr);
/* adjust non-scrollable dimension to fit the child */
- SetWindowPos(hwnd, 0,
- 0,0,
- infoPtr->bHorizontal ? wndSizeScrollable : infoPtr->nWidth,
- infoPtr->bHorizontal ? infoPtr->nHeight : wndSizeScrollable,
- SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOZORDER);
+ SetWindowPos(hwnd, 0, 0,0,
+ infoPtr->bHorizontal ? infoPtr->nDelta + infoPtr->nButtonSize : infoPtr->nWidth,
+ infoPtr->bHorizontal ? infoPtr->nHeight : infoPtr->nDelta + infoPtr->nButtonSize,
+ SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOZORDER);
/* position child within the page scroller */
SetWindowPos(infoPtr->hwndChild, HWND_TOP,
@@ -596,6 +662,7 @@
if (infoPtr->hwndChild)
{
+ BOOL res = FALSE;
ZeroMemory (&nmpgScroll, sizeof (NMPGSCROLL));
nmpgScroll.hdr.hwndFrom = hwnd;
nmpgScroll.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
@@ -612,10 +679,10 @@
nmpgScroll.iYpos = infoPtr->nPos;
TRACE("[%04x] sending PGN_SCROLL\n", hwnd);
- SendMessageA (hwnd, WM_NOTIFY,
+ res = SendMessageA (hwnd, WM_NOTIFY,
(WPARAM)nmpgScroll.hdr.idFrom, (LPARAM)&nmpgScroll);
- if (infoPtr->nDelta != nmpgScroll.iScroll)
+ if (res && infoPtr->nDelta != nmpgScroll.iScroll)
{
TRACE("delta changing from %d to %d\n",
infoPtr->nDelta, nmpgScroll.iScroll);
@@ -634,6 +701,8 @@
{
PAGER_INFO *infoPtr;
DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
+ RECT rect;
+
SetWindowLongA(hwnd, GWL_STYLE, dwStyle & WS_CLIPCHILDREN);
/* allocate memory for info structure */
@@ -642,6 +711,7 @@
/* set default settings */
infoPtr->hwndChild = (HWND)NULL;
+ infoPtr->bNoResize = dwStyle & CCS_NORESIZE;
infoPtr->clrBk = GetSysColor(COLOR_BTNFACE);
infoPtr->nBorder = 0;
infoPtr->nButtonSize = 12;
@@ -667,6 +737,22 @@
infoPtr->bHorizontal = dwStyle & PGS_HORZ;
+ GetWindowRect(hwnd, &rect);
+ if (infoPtr->bHorizontal)
+ {
+ infoPtr->nHeight = rect.bottom - rect.top;
+ infoPtr->nDelta = rect.right - rect.left - infoPtr->nButtonSize;
+ TRACE("height = %d %s\n", infoPtr->nHeight,
+ infoPtr->bNoResize ? "CCS_NORESIZE" : "");
+ }
+ else
+ {
+ infoPtr->nWidth = rect.right - rect.left;
+ infoPtr->nDelta = rect.bottom - rect.top - infoPtr->nButtonSize;
+ TRACE("width = %d %s\n", infoPtr->nWidth,
+ infoPtr->bNoResize ? "CCS_NORESIZE" : "");
+ }
+
TRACE("[%04x] orientation = %s\n", hwnd,
infoPtr->bHorizontal ? "PGS_HORZ" : "PGS_VERT");
@@ -687,15 +773,15 @@
static LRESULT
PAGER_NCCalcSize(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
- PAGER_INFO *infoPtr = PAGER_GetInfoPtr (hwnd);
+ PAGER_INFO *infoPtr = PAGER_GetInfoPtr (hwnd);
+ LPRECT lpRect = (LPRECT)lParam;
/*
* lParam points to a RECT struct. On entry, the struct
* contains the proposed wnd rectangle for the window.
* On exit, the struct should contain the screen
* coordinates of the corresponding window's client area.
*/
- LPRECT lpRect = (LPRECT)lParam;
-
+
if (infoPtr->bHorizontal)
{
if (infoPtr->TLbtnState) /* != PGF_INVISIBLE */
@@ -985,24 +1071,25 @@
static LRESULT
-PAGER_Size (HWND hwnd)
+PAGER_Size (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
/* note that WM_SIZE is sent whenever NCCalcSize resizes the client wnd */
PAGER_INFO *infoPtr = PAGER_GetInfoPtr (hwnd);
- RECT wndRect;
- GetWindowRect(hwnd, &wndRect);
+ TRACE("[%04x] %dx%d\n", hwnd, LOWORD(lParam), HIWORD(lParam));
- infoPtr->nDelta = infoPtr->bHorizontal ?
- wndRect.right - wndRect.left :
- wndRect.bottom - wndRect.top;
- infoPtr->nDelta -= 2*infoPtr->nButtonSize;
-
- TRACE("[%04x] nDelta=%d\n", hwnd, infoPtr->nDelta);
+ if (infoPtr->bHorizontal)
+ {
+ infoPtr->nHeight = HIWORD(lParam);
+ infoPtr->nDelta = LOWORD(lParam) - infoPtr->nButtonSize;
+ }
+ else
+ {
+ infoPtr->nWidth = LOWORD(lParam);
+ infoPtr->nDelta = HIWORD(lParam) - infoPtr->nButtonSize;
+ }
- PAGER_PositionChildWnd(hwnd, infoPtr);
-
- return TRUE;
+ return PAGER_RecalcSize(hwnd);
}
@@ -1061,10 +1148,13 @@
return PAGER_Destroy (hwnd, wParam, lParam);
case WM_SIZE:
- return PAGER_Size (hwnd);
+ return PAGER_Size (hwnd, wParam, lParam);
case WM_NCPAINT:
return PAGER_NCPaint (hwnd, wParam, lParam);
+
+ case WM_WINDOWPOSCHANGING:
+ return PAGER_HandleWindowPosChanging (hwnd, (WINDOWPOS*)lParam);
case WM_NCCALCSIZE:
return PAGER_NCCalcSize (hwnd, wParam, lParam);
More information about the wine-patches
mailing list