sizing the page scroller control
Susan Farley
susan at codeweavers.com
Thu Feb 1 12:45:16 CST 2001
Changelog:
* dlls/comctl32/pager.c
Handle the CCS_NORESIZE style.
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/01 19:14:56
@@ -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,
@@ -457,45 +458,126 @@
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;
+ infoPtr->nPos = scrollRange;
+ else
+ infoPtr->nPos = newPos;
+
+ TRACE("[%04x] pos=%d\n", hwnd, infoPtr->nPos);
- if (newPos != 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);
+
+ return 0;
+}
+
+static LRESULT
+PAGER_HandleWindowPosChanging(HWND hwnd, WINDOWPOS *winpos)
+{
+ PAGER_INFO *infoPtr = PAGER_GetInfoPtr (hwnd);
+
+ if (infoPtr->bNoResize && !(winpos->flags & SWP_NOSIZE))
{
- infoPtr->nPos = newPos;
- TRACE("[%04x] pos=%d\n", hwnd, infoPtr->nPos);
+ RECT wndRect;
+ INT cx, cy;
+
+ /* 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) */
- /* gray and restore btns, and if from WM_SETPOS, hide the gray btns */
- PAGER_UpdateBtns(hwnd, infoPtr, scrollRange, !fromBtnPress);
+ GetWindowRect(hwnd, &wndRect);
+
+ cx = wndRect.right - wndRect.left;
+ cy = wndRect.bottom - wndRect.top;
- PAGER_PositionChildWnd(hwnd, infoPtr);
+ if (infoPtr->bHorizontal)
+ {
+ winpos->cy = infoPtr->nHeight;
+ winpos->cx = cx;
+ }
+ else
+ {
+ winpos->cx = infoPtr->nWidth;
+ winpos->cy = cy;
+ }
}
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;
+ GetWindowRect(hwnd, &wndRect);
+
+ /* see what the app says for btn width */
+ PAGER_CalcSize(hwnd, &infoPtr->nWidth, TRUE);
+
+ if (infoPtr->bNoResize)
+ {
+ if (infoPtr->nWidth < wndRect.right - wndRect.left)
+ infoPtr->nWidth += 4 * 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;
+ GetWindowRect(hwnd, &wndRect);
+
+ /* see what the app says for btn height */
+ PAGER_CalcSize(hwnd, &infoPtr->nHeight, FALSE);
+
+ if (infoPtr->bNoResize)
+ {
+ if (infoPtr->nHeight < wndRect.bottom - wndRect.top)
+ infoPtr->nHeight += 4 * 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 +626,6 @@
}
-
static LRESULT
PAGER_SetChild (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
@@ -554,28 +635,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 + 2*infoPtr->nButtonSize : infoPtr->nWidth,
+ infoPtr->bHorizontal ? infoPtr->nHeight : infoPtr->nDelta + 2*infoPtr->nButtonSize,
+ SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOZORDER);
/* position child within the page scroller */
SetWindowPos(infoPtr->hwndChild, HWND_TOP,
@@ -634,6 +705,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 +715,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 +741,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 +777,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 +1075,27 @@
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);
-
- 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;
+ TRACE("[%04x] height = %d\n",
+ hwnd, infoPtr->nHeight);
+ }
+ else
+ {
+ infoPtr->nWidth = LOWORD(lParam);
+ infoPtr->nDelta = HIWORD(lParam) - infoPtr->nButtonSize;
+ TRACE("[%04x] width = %d\n",
+ hwnd, infoPtr->nWidth);
+ }
- PAGER_PositionChildWnd(hwnd, infoPtr);
-
- return TRUE;
+ return PAGER_RecalcSize(hwnd);
}
@@ -1061,10 +1154,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