page scroller improvements for IE4

Susan Farley susan at codeweavers.com
Thu Feb 22 11:30:19 CST 2001


With this patch, the menu bar (which is the child of a pager
control) shows up on Internet Explorer 4.  Thanks to Guy
Albertelli for pointing out that problem.  There is still a
problem with the way it scrolls--I'll work on that next.  

Changelog:
* dlls/comctl32/pager.c
     Horiz/Vert determination must be dynamic, as the style may
not be set upon creation; improved positioning and scrolling.

* include/commctrl.h
     Avoid alignment problems with NMPGSCROLL struct.

Susan Farley
<susan at codeweavers.com>
-------------- next part --------------
Index: include/commctrl.h
===================================================================
RCS file: /home/wine/wine/include/commctrl.h,v
retrieving revision 1.75
diff -u -r1.75 commctrl.h
--- include/commctrl.h	2001/02/12 19:39:58	1.75
+++ include/commctrl.h	2001/02/22 17:28:46
@@ -1817,7 +1817,7 @@
     INT  iXpos;
     INT  iYpos;
     INT  iScroll;
-} NMPGSCROLL, *LPNMPGSCROLL;
+} WINE_PACKED NMPGSCROLL, *LPNMPGSCROLL;
 
 typedef struct
 {
Index: dlls/comctl32/pager.c
===================================================================
RCS file: /home/wine/wine/dlls/comctl32/pager.c,v
retrieving revision 1.23
diff -u -r1.23 pager.c
--- dlls/comctl32/pager.c	2001/02/12 03:42:23	1.23
+++ dlls/comctl32/pager.c	2001/02/22 17:28:46
@@ -25,12 +25,10 @@
 {
     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 */
@@ -40,10 +38,12 @@
 } PAGER_INFO;
 
 #define PAGER_GetInfoPtr(hwnd) ((PAGER_INFO *)GetWindowLongA(hwnd, 0))
+#define PAGER_IsHorizontal(hwnd) ((GetWindowLongA (hwnd, GWL_STYLE) & PGS_HORZ))
 
 #define MIN_ARROW_WIDTH  8
 #define MIN_ARROW_HEIGHT 5
 
+
 /* the horizontal arrows are: 
  *
  * 01234    01234
@@ -296,14 +296,21 @@
 {
     if (infoPtr->hwndChild)
     {
+        RECT rcClient;
         int nPos = infoPtr->nPos;
 
         /* compensate for a grayed btn, which will soon become invisible */
         if (infoPtr->TLbtnState == PGF_GRAYED)
             nPos += infoPtr->nButtonSize;
+
+        GetClientRect(hwnd, &rcClient);
 
-        if (infoPtr->bHorizontal)
+        if (PAGER_IsHorizontal(hwnd))
         {
+            int wndSize = max(0, rcClient.right - rcClient.left);
+            if (infoPtr->nWidth < wndSize)
+                infoPtr->nWidth = wndSize;
+
             TRACE("[%04x] SWP %dx%d at (%d,%d)\n", hwnd,
                          infoPtr->nWidth, infoPtr->nHeight,
                          -nPos, 0);
@@ -314,6 +321,10 @@
         }
         else
         {
+            int wndSize = max(0, rcClient.bottom - rcClient.top);
+            if (infoPtr->nHeight < wndSize)
+                infoPtr->nHeight = wndSize;
+
             TRACE("[%04x] SWP %dx%d at (%d,%d)\n", hwnd, 
                          infoPtr->nWidth, infoPtr->nHeight,
                          0, -nPos);
@@ -323,7 +334,7 @@
                          SWP_NOZORDER);
         }
 
-        InvalidateRect(infoPtr->hwndChild, NULL, FALSE);
+        InvalidateRect(infoPtr->hwndChild, NULL, TRUE);
     }
 }
 
@@ -338,7 +349,7 @@
         RECT wndRect;
         GetWindowRect(hwnd, &wndRect);
 
-        if (infoPtr->bHorizontal)
+        if (PAGER_IsHorizontal(hwnd))
         {
             wndSize = wndRect.right - wndRect.left;
             PAGER_CalcSize(hwnd, &infoPtr->nWidth, TRUE);
@@ -486,7 +497,7 @@
          * that was created with CCS_NORESIZE style
          * (i.e. height for a horizontal pager, or width for a vertical one) */
 
-        if (infoPtr->bHorizontal)
+        if (PAGER_IsHorizontal(hwnd))
             winpos->cy = infoPtr->nHeight;
         else
             winpos->cx = infoPtr->nWidth;
@@ -503,7 +514,7 @@
    * size, and experimentation shows that affect is almost right. */
 
     RECT wndRect;
-    INT delta;
+    INT delta, h;
     GetWindowRect(hwnd, &wndRect);
 
     /* see what the app says for btn width */
@@ -517,9 +528,14 @@
         else if (delta > 0)
             infoPtr->nWidth +=  infoPtr->nButtonSize / 3;
     }
+
+    h = wndRect.bottom - wndRect.top;
 
-    infoPtr->nDelta = wndRect.bottom - wndRect.top - infoPtr->nButtonSize;
+    /* 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);
 }
@@ -532,7 +548,7 @@
    * size, and experimentation shows that affect is almost right. */
 
     RECT wndRect;
-    INT delta;
+    INT delta, w;
     GetWindowRect(hwnd, &wndRect);
 
     /* see what the app says for btn height */
@@ -546,8 +562,12 @@
         else if (delta > 0)
             infoPtr->nHeight +=  infoPtr->nButtonSize / 3;
     }
+
+    w = wndRect.right - wndRect.left;
 
-    infoPtr->nDelta = wndRect.right - wndRect.left - infoPtr->nButtonSize;
+    /* 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);
@@ -557,6 +577,7 @@
 PAGER_RecalcSize(HWND hwnd)
 {
     PAGER_INFO *infoPtr = PAGER_GetInfoPtr (hwnd);
+
     TRACE("[%04x]\n", hwnd);
 
     if (infoPtr->hwndChild)
@@ -632,16 +653,10 @@
     {
         TRACE("[%04x] hwndChild=%04x\n", hwnd, infoPtr->hwndChild);
 
-        if (infoPtr->bHorizontal)
+        if (PAGER_IsHorizontal(hwnd))
             PAGER_SetFixedHeight(hwnd, infoPtr);
         else
-           PAGER_SetFixedWidth(hwnd, infoPtr);
-
-        /* adjust non-scrollable dimension to fit the child */
-        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);
+            PAGER_SetFixedWidth(hwnd, infoPtr);
 
         /* position child within the page scroller */
         SetWindowPos(infoPtr->hwndChild, HWND_TOP,
@@ -662,7 +677,6 @@
 
     if (infoPtr->hwndChild)
     {
-        BOOL res = FALSE;
         ZeroMemory (&nmpgScroll, sizeof (NMPGSCROLL));
         nmpgScroll.hdr.hwndFrom = hwnd;
         nmpgScroll.hdr.idFrom   = GetWindowLongA (hwnd, GWL_ID);
@@ -671,28 +685,32 @@
         GetClientRect(hwnd, &nmpgScroll.rcParent);  
         nmpgScroll.iXpos = nmpgScroll.iYpos = 0;
         nmpgScroll.iDir = dir;
-        nmpgScroll.iScroll = infoPtr->nDelta;
 
-        if (infoPtr->bHorizontal)
+        if (PAGER_IsHorizontal(hwnd))
+        {
+            nmpgScroll.iScroll = nmpgScroll.rcParent.right -
+                                 nmpgScroll.rcParent.left;
             nmpgScroll.iXpos = infoPtr->nPos;
+        }
         else
+        {
+            nmpgScroll.iScroll = nmpgScroll.rcParent.bottom -
+                                 nmpgScroll.rcParent.top;
             nmpgScroll.iYpos = infoPtr->nPos;
-
-        TRACE("[%04x] sending PGN_SCROLL\n", hwnd);
-        res = SendMessageA (hwnd, WM_NOTIFY,
+        }
+  
+        SendMessageA (hwnd, WM_NOTIFY,
                     (WPARAM)nmpgScroll.hdr.idFrom, (LPARAM)&nmpgScroll);
+  
+        TRACE("[%04x] PGN_SCROLL returns iScroll=%d\n", hwnd, nmpgScroll.iScroll);
 
-        if (res && 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);
     }
 }
 
@@ -701,9 +719,8 @@
 {
     PAGER_INFO *infoPtr;
     DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
-    RECT rect;
 
-    SetWindowLongA(hwnd, GWL_STYLE, dwStyle & WS_CLIPCHILDREN);
+    dwStyle |= WS_CLIPCHILDREN;
 
     /* allocate memory for info structure */
     infoPtr = (PAGER_INFO *)COMCTL32_Alloc (sizeof(PAGER_INFO));
@@ -726,36 +743,15 @@
         FIXME("[%04x] Autoscroll style is not implemented yet.\n", hwnd);
     if (dwStyle & PGS_DRAGNDROP)
         FIXME("[%04x] Drag and Drop style is not implemented yet.\n", hwnd);
-    if ((dwStyle & PGS_HORZ) && (dwStyle & PGS_VERT))
-    {
-        ERR("[%04x] Cannot have both horizontal and vertical styles.\n", hwnd);
-        ERR("[%04x] Defaulting to vertical.\n", hwnd);
-        dwStyle &= ~PGS_HORZ;
-    }
-    else if (!(dwStyle & PGS_HORZ) && !(dwStyle & PGS_VERT))
-        dwStyle |= PGS_VERT; /* the default according to MSDN */
-
-    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");
+    /*
+	 * If neither horizontal nor vertical style specified, default to vertical.
+	 * This is probably not necessary, since the style may be set later on as
+	 * the control is initialized, but just in case it isn't, set it here.
+	 */
+    if (!(dwStyle & PGS_HORZ) && !(dwStyle & PGS_VERT))
+        dwStyle |= PGS_VERT;
 
+    SetWindowLongA(hwnd, GWL_STYLE, dwStyle);
     return 0;
 }
 
@@ -782,7 +778,7 @@
      * coordinates of the corresponding window's client area.
      */
 	
-    if (infoPtr->bHorizontal)
+    if (PAGER_IsHorizontal(hwnd))
     {
         if (infoPtr->TLbtnState) /* != PGF_INVISIBLE */
             lpRect->left += infoPtr->nButtonSize;
@@ -812,6 +808,7 @@
     DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
     RECT rcWindow, rcBottomRight, rcTopLeft;
     HDC hdc;
+    BOOL bHorizontal = PAGER_IsHorizontal(hwnd);
 
     if (dwStyle & WS_MINIMIZE)
         return 0;
@@ -825,7 +822,7 @@
     OffsetRect (&rcWindow, -rcWindow.left, -rcWindow.top);
 
     rcTopLeft = rcBottomRight = rcWindow;
-    if (infoPtr->bHorizontal)
+    if (bHorizontal)
     {
         rcTopLeft.right = rcTopLeft.left + infoPtr->nButtonSize;
         rcBottomRight.left = rcBottomRight.right - infoPtr->nButtonSize;
@@ -837,9 +834,9 @@
     }
 
     PAGER_DrawButton(hdc, infoPtr->clrBk, rcTopLeft,
-                    infoPtr->bHorizontal, TRUE, infoPtr->TLbtnState);
+                     bHorizontal, TRUE, infoPtr->TLbtnState);
     PAGER_DrawButton(hdc, infoPtr->clrBk, rcBottomRight,
-                    infoPtr->bHorizontal, FALSE, infoPtr->BRbtnState); 
+                     bHorizontal, FALSE, infoPtr->BRbtnState); 
 
     ReleaseDC( hwnd, hdc );
     return 0;
@@ -850,6 +847,7 @@
 {
     PAGER_INFO *infoPtr = PAGER_GetInfoPtr (hwnd);
     RECT clientRect;
+    BOOL bHorizontal = PAGER_IsHorizontal(hwnd);
 
     GetClientRect (hwnd, &clientRect);
 
@@ -861,7 +859,7 @@
 
     if (infoPtr->TLbtnState && infoPtr->TLbtnState != PGF_GRAYED)
     {
-        if (infoPtr->bHorizontal)
+        if (bHorizontal)
         {
             if (pt->x < clientRect.left)
             {
@@ -881,7 +879,7 @@
 
     if (infoPtr->BRbtnState && infoPtr->BRbtnState != PGF_GRAYED)
     {
-        if (infoPtr->bHorizontal)
+        if (bHorizontal)
         {
             if (pt->x > clientRect.right)
             {
@@ -999,9 +997,6 @@
 
     TRACE("[%04x]\n", hwnd);
 	
-    if (infoPtr->nDelta <= 0)
-        return FALSE;
-
     hit = PAGER_HitTest(hwnd, &pt);
 
     /* put btn in DEPRESSED state */
@@ -1078,16 +1073,10 @@
     PAGER_INFO *infoPtr = PAGER_GetInfoPtr (hwnd);
     TRACE("[%04x] %dx%d\n", hwnd, LOWORD(lParam), HIWORD(lParam));
 
-    if (infoPtr->bHorizontal)
-    {
+    if (PAGER_IsHorizontal(hwnd))
         infoPtr->nHeight = HIWORD(lParam);
-        infoPtr->nDelta =  LOWORD(lParam) - infoPtr->nButtonSize;
-    }
     else
-    {
         infoPtr->nWidth = LOWORD(lParam);
-        infoPtr->nDelta = HIWORD(lParam) - infoPtr->nButtonSize;
-    }
 
     return PAGER_RecalcSize(hwnd);
 }





More information about the wine-patches mailing list