This patch greatly improves the page scroller. I was kind of waiting til my last patch was accepted before submitting more. (This one includes those changes too, so it ought to apply to the tip of winehq.) Maybe it will fix the problem. Otherwise, please do send me traces (+pager,+win).
thanks, sue
"Guy L. Albertelli" wrote:
While working on ComboEx with the 1/29/2001 CVS, IE4 no longer displays its menu bar. (Well, not really a menu bar, it is a Rebar with a Pager as the child and a Toolbar as a child of the Pager. The Toolbar buttons are the "menu" items.) If I revert the Pager code to the 12/29/2000 version (very limited functionality) then the "menu" appears and is usable. If you need traces, I can provide them.
This is with preinstalled copy of IE4.
Thanks,
Guy Albertelli <galberte@neo.lrun.com>
Index: include/commctrl.h =================================================================== RCS file: /home/wine/wine/include/commctrl.h,v retrieving revision 1.69 diff -u -r1.69 commctrl.h --- include/commctrl.h 2000/12/19 02:08:35 1.69 +++ include/commctrl.h 2001/02/07 16:18:46 @@ -1754,7 +1754,7 @@ INT iXpos; INT iYpos; INT iScroll; -} NMPGSCROLL, *LPNMPGSCROLL; +} WINE_PACKED NMPGSCROLL, *LPNMPGSCROLL;
typedef struct { Index: dlls/comctl32/commctrl.c =================================================================== RCS file: /home/wine/wine/dlls/comctl32/commctrl.c,v retrieving revision 1.37 diff -u -r1.37 commctrl.c --- dlls/comctl32/commctrl.c 2001/01/09 20:50:13 1.37 +++ dlls/comctl32/commctrl.c 2001/02/07 16:18:47 @@ -127,6 +127,7 @@ TRACKBAR_Register (); TREEVIEW_Register (); UPDOWN_Register (); + PAGER_Register (); } COMCTL32_dwProcessesAttached++; break; 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/07 16:18:47 @@ -24,12 +24,12 @@ 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 */ INT nButtonSize;/* size of the pager btns */ INT nPos; /* scroll position */ - INT nDelta; /* scroll delta */ INT nWidth; /* from child wnd's response to PGN_CALCSIZE */ INT nHeight; /* from child wnd's response to PGN_CALCSIZE */ BOOL bForward; /* forward WM_MOUSEMOVE msgs to the contained wnd */ @@ -309,12 +309,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 +350,7 @@ childSize = infoPtr->nHeight; }
+ TRACE("childSize = %d, wndSize = %d\n", childSize, wndSize); if (childSize > wndSize) scrollRange = childSize - wndSize + infoPtr->nButtonSize; } @@ -457,45 +458,141 @@ 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) */ + + GetWindowRect(hwnd, &wndRect);
- /* gray and restore btns, and if from WM_SETPOS, hide the gray btns */ - PAGER_UpdateBtns(hwnd, infoPtr, scrollRange, !fromBtnPress); + cx = wndRect.right - wndRect.left; + cy = wndRect.bottom - wndRect.top;
- PAGER_PositionChildWnd(hwnd, infoPtr); + 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, h; + 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; + } + + h = wndRect.bottom - wndRect.top; + + /* adjust non-scrollable dimension to fit the child */ + SetWindowPos(hwnd, 0, 0,0, infoPtr->nWidth, h, + SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOZORDER); + + + 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, w; + 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; + } + + w = wndRect.right - wndRect.left; + + /* adjust non-scrollable dimension to fit the child */ + SetWindowPos(hwnd, 0, 0,0, w, infoPtr->nHeight, + SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOZORDER); + + 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 +641,6 @@ }
- static LRESULT PAGER_SetChild (HWND hwnd, WPARAM wParam, LPARAM lParam) { @@ -554,28 +650,12 @@
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); - - /* 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); + if (infoPtr->bHorizontal) + PAGER_SetFixedHeight(hwnd, infoPtr); + else + PAGER_SetFixedWidth(hwnd, infoPtr);
/* position child within the page scroller */ SetWindowPos(infoPtr->hwndChild, HWND_TOP, @@ -593,6 +673,7 @@ { PAGER_INFO *infoPtr = PAGER_GetInfoPtr (hwnd); NMPGSCROLL nmpgScroll; + RECT rcWnd;
if (infoPtr->hwndChild) { @@ -601,32 +682,36 @@ nmpgScroll.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID); nmpgScroll.hdr.code = PGN_SCROLL;
+ GetWindowRect(hwnd, &rcWnd); GetClientRect(hwnd, &nmpgScroll.rcParent); nmpgScroll.iXpos = nmpgScroll.iYpos = 0; nmpgScroll.iDir = dir; - nmpgScroll.iScroll = infoPtr->nDelta;
if (infoPtr->bHorizontal) + { + nmpgScroll.iScroll = rcWnd.right - rcWnd.left; nmpgScroll.iXpos = infoPtr->nPos; + } else - nmpgScroll.iYpos = infoPtr->nPos; - - TRACE("[%04x] sending PGN_SCROLL\n", hwnd); + { + nmpgScroll.iScroll = rcWnd.bottom - rcWnd.top; + nmpgScroll.iYpos = infoPtr->nPos; + } + nmpgScroll.iScroll -= 2*infoPtr->nButtonSize; + SendMessageA (hwnd, WM_NOTIFY, (WPARAM)nmpgScroll.hdr.idFrom, (LPARAM)&nmpgScroll); + + TRACE("[%04x] PGN_SCROLL returns iScroll=%d\n", hwnd, nmpgScroll.iScroll);
- if (infoPtr->nDelta != nmpgScroll.iScroll) + if (nmpgScroll.iScroll > 0) { - TRACE("delta changing from %d to %d\n", - infoPtr->nDelta, nmpgScroll.iScroll); - infoPtr->nDelta = nmpgScroll.iScroll; + if (dir == PGF_SCROLLLEFT || dir == PGF_SCROLLUP) + PAGER_SetPos(hwnd, infoPtr->nPos - nmpgScroll.iScroll, TRUE); + else + PAGER_SetPos(hwnd, infoPtr->nPos + nmpgScroll.iScroll, TRUE); } - - if (dir == PGF_SCROLLLEFT || dir == PGF_SCROLLUP) - PAGER_SetPos(hwnd, infoPtr->nPos - infoPtr->nDelta, TRUE); - else - PAGER_SetPos(hwnd, infoPtr->nPos + infoPtr->nDelta, TRUE); - } + } }
static LRESULT @@ -634,6 +719,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 +729,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 +755,20 @@
infoPtr->bHorizontal = dwStyle & PGS_HORZ;
+ GetWindowRect(hwnd, &rect); + if (infoPtr->bHorizontal) + { + infoPtr->nHeight = rect.bottom - rect.top; + TRACE("height = %d %s\n", infoPtr->nHeight, + infoPtr->bNoResize ? "CCS_NORESIZE" : ""); + } + else + { + infoPtr->nWidth = rect.right - rect.left; + 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 +789,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 */ @@ -913,9 +1015,6 @@
TRACE("[%04x]\n", hwnd); - if (infoPtr->nDelta <= 0) - return FALSE; - hit = PAGER_HitTest(hwnd, &pt);
/* put btn in DEPRESSED state */ @@ -985,24 +1084,19 @@
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); + else + infoPtr->nWidth = LOWORD(lParam);
- PAGER_PositionChildWnd(hwnd, infoPtr); - - return TRUE; + return PAGER_RecalcSize(hwnd); }
@@ -1061,10 +1155,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);