Author: jimtabor
Date: Thu Dec  1 03:20:02 2011
New Revision: 54555
URL: 
http://svn.reactos.org/svn/reactos?rev=54555&view=rev
Log:
[Win32k|User32]
- Fix scrollbar class support. Sync ports from wine. Added the window scroll structure to
the class. Pass all but 15 tests, two are wine todos lines 304 and 343.
Modified:
    trunk/reactos/dll/win32/user32/controls/scrollbar.c
    trunk/reactos/include/reactos/win32k/ntuser.h
    trunk/reactos/subsystems/win32/win32k/include/scroll.h
    trunk/reactos/subsystems/win32/win32k/ntuser/class.c
    trunk/reactos/subsystems/win32/win32k/ntuser/scrollbar.c
Modified: trunk/reactos/dll/win32/user32/controls/scrollbar.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/controls/…
==============================================================================
--- trunk/reactos/dll/win32/user32/controls/scrollbar.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/user32/controls/scrollbar.c [iso-8859-1] Thu Dec  1 03:20:02
2011
@@ -1,5 +1,4 @@
-/* $Id $
- *
+/*
  * ReactOS User32 Library
  * - ScrollBar control
  *
@@ -80,7 +79,7 @@
     CS_DBLCLKS | CS_VREDRAW | CS_HREDRAW | CS_PARENTDC, /* style */
     ScrollBarWndProcA,      /* procA */
     ScrollBarWndProcW,      /* procW */
-    0,                      /* extra */
+    sizeof(SBWND)-sizeof(WND), /* extra */
     IDC_ARROW,              /* cursor */
     0                       /* brush */
 };
@@ -310,6 +309,7 @@
 void
 IntDrawScrollBar(HWND Wnd, HDC DC, INT Bar)
 {
+  //PSBTRACK pSBTrack;
   //INT ThumbSize;
   SCROLLBARINFO Info;
   BOOL Vertical;
@@ -344,7 +344,7 @@
       return;
     }
-  //ThumbSize = Info.xyThumbBottom - Info.xyThumbTop;
+  //ThumbSize = pSBTrack->pSBCalc->pxThumbBottom -
pSBTrack->pSBCalc->pxThumbTop;
   /*
    * Draw the arrows.
@@ -1175,11 +1175,8 @@
   ScrollInfo.cbSize = sizeof(SCROLLINFO);
   ScrollInfo.fMask = SIF_RANGE;
   Result = NtUserSBGetParms(Wnd, Bar, NULL, &ScrollInfo);
-  if (Result)
-    {
-      *MinPos = ScrollInfo.nMin;
-      *MaxPos = ScrollInfo.nMax;
-    }
+  *MinPos = Result ? ScrollInfo.nMin : 0;
+  *MaxPos = Result ? ScrollInfo.nMax : 0;
   return Result;
 }
@@ -1200,13 +1197,11 @@
   if (SBType != SB_CTL)
   {
-      PWND pwnd = ValidateHwnd(Wnd);
-      if (!pwnd) return;
-      XOffset = pwnd->rcClient.left - pwnd->rcWindow.left;
-      YOffset = pwnd->rcClient.top - pwnd->rcWindow.top;
+      RECT rect;
+      GetClientRect(Wnd, &rect);
       ScreenToClient(Wnd, &Pt);
-      Pt.x += XOffset;
-      Pt.y += YOffset;
+      Pt.x -= rect.left;
+      Pt.y -= rect.top;
   }
   IntScrollHandleScrollEvent(Wnd, SBType, WM_LBUTTONDOWN, Pt);
@@ -1241,7 +1236,7 @@
  *           ScrollBarWndProc
  */
 LRESULT WINAPI
-ScrollBarWndProc(WNDPROC DefWindowProc, HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
+ScrollBarWndProc_common(WNDPROC DefWindowProc, HWND Wnd, UINT Msg, WPARAM wParam, LPARAM
lParam, BOOL unicode )
 {
 #ifdef __REACTOS__ // Do this now, remove after Server side is fixed.
   PWND pWnd;
@@ -1279,26 +1274,14 @@
         IntScrollCreateScrollBar(Wnd, (LPCREATESTRUCTW) lParam);
         break;
-//#if 0 /* FIXME */
       case WM_ENABLE:
         {
-//          SCROLLBAR_INFO *infoPtr;
-//          if ((infoPtr = SCROLL_GetScrollBarInfo( hwnd, SB_CTL )))
-//            {
-//              infoPtr->flags = wParam ? ESB_ENABLE_BOTH : ESB_DISABLE_BOTH;
-//              SCROLL_RefreshScrollBar(hwnd, SB_CTL, TRUE, TRUE);
-//            }
-          HDC hdc;
-          DbgPrint("ScrollBarWndProc WM_ENABLE\n");
+          TRACE("ScrollBarWndProc WM_ENABLE\n");
           NtUserEnableScrollBar(Wnd,SB_CTL,(wParam ? ESB_ENABLE_BOTH :
ESB_DISABLE_BOTH));
           /* Refresh Scrollbars. */
-          hdc = GetDCEx( Wnd, 0, DCX_CACHE );
-          if (!hdc) return 1;
-          IntDrawScrollBar( Wnd, hdc, SB_CTL);
-          ReleaseDC( Wnd, hdc );
+          SCROLL_RefreshScrollBar(Wnd, SB_CTL, TRUE, TRUE);
        }
        return 0;
-//#endif
       case WM_LBUTTONDBLCLK:
       case WM_LBUTTONDOWN:
@@ -1430,9 +1413,9 @@
       case SBM_GETRANGE:
         return IntScrollGetScrollRange(Wnd, SB_CTL, (LPINT) wParam, (LPINT) lParam);
-
+
       case SBM_ENABLE_ARROWS:
-        return EnableScrollBar(Wnd, SB_CTL, wParam);
+        return EnableScrollBar( Wnd, SB_CTL, wParam );
       case SBM_SETSCROLLINFO:
         return NtUserSetScrollInfo(Wnd, SB_CTL, (SCROLLINFO *) lParam, wParam);
@@ -1460,7 +1443,10 @@
           {
             WARN("unknown msg %04x wp=%04lx lp=%08lx\n", Msg, wParam, lParam);
           }
-        return DefWindowProc(Wnd, Msg, wParam, lParam );
+        if (unicode)
+            return DefWindowProcW( Wnd, Msg, wParam, lParam );
+        else
+            return DefWindowProcA( Wnd, Msg, wParam, lParam );
     }
   return 0;
@@ -1469,13 +1455,13 @@
 LRESULT WINAPI
 ScrollBarWndProcW(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
 {
-  return ScrollBarWndProc(DefWindowProcW, Wnd, Msg, wParam, lParam);
+  return ScrollBarWndProc_common(DefWindowProcW, Wnd, Msg, wParam, lParam, TRUE);
 }
 LRESULT WINAPI
 ScrollBarWndProcA(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
 {
-  return ScrollBarWndProc(DefWindowProcA, Wnd, Msg, wParam, lParam);
+  return ScrollBarWndProc_common(DefWindowProcA, Wnd, Msg, wParam, lParam, FALSE);
 }
@@ -1493,8 +1479,14 @@
    Hook = BeginIfHookedUserApiHook();
      /* Bypass SEH and go direct. */
-   if (!Hook) return NtUserEnableScrollBar(hwnd, nBar, flags);
-
+   if (!Hook)
+   {
+      Ret = NtUserEnableScrollBar(hwnd, nBar, flags);
+      if (GetLastError() == ERROR_INVALID_PARAMETER) return Ret;
+      if (nBar == SB_CTL) return Ret;
+      SCROLL_RefreshScrollBar( hwnd, nBar, TRUE, TRUE );
+      return Ret;
+   }
    _SEH2_TRY
    {
       Ret = guah.EnableScrollBar(hwnd, nBar, flags);
Modified: trunk/reactos/include/reactos/win32k/ntuser.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/win32k/ntu…
==============================================================================
--- trunk/reactos/include/reactos/win32k/ntuser.h [iso-8859-1] (original)
+++ trunk/reactos/include/reactos/win32k/ntuser.h [iso-8859-1] Thu Dec  1 03:20:02 2011
@@ -396,6 +396,26 @@
   SBDATA Horz;
   SBDATA Vert;
 } SBINFO, *PSBINFO;
+
+typedef struct tagSBCALC
+{
+  INT posMin;
+  INT posMax;
+  INT page;
+  INT pos;
+  INT pxTop;
+  INT pxBottom;
+  INT pxLeft;
+  INT pxRight;
+  INT cpxThumb;
+  INT pxUpArrow;
+  INT pxDownArrow;
+  INT pxStart;
+  INT pxThumbBottom;
+  INT pxThumbTop;
+  INT cpx;
+  INT pxMin;
+} SBCALC, *PSBCALC;
 typedef enum _GETCPD
 {
@@ -615,6 +635,14 @@
   /* Entry in the list of thread windows. */
   LIST_ENTRY ThreadListEntry;
 } WND, *PWND;
+
+typedef struct _SBWND
+{
+  WND    wnd;
+  BOOL   fVert;
+  UINT   wDisableFlags;
+  SBCALC SBCalc;
+} SBWND, *PSBWND;
 typedef struct _PFNCLIENT
 {
Modified: trunk/reactos/subsystems/win32/win32k/include/scroll.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/in…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/scroll.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/include/scroll.h [iso-8859-1] Thu Dec  1
03:20:02 2011
@@ -1,24 +1,4 @@
 #pragma once
-
-typedef struct tagSBCALC
-{
-    INT posMin;
-    INT posMax;
-    INT page;
-    INT pos;
-    INT pxTop;
-    INT pxBottom;
-    INT pxLeft;
-    INT pxRight;
-    INT cpxThumb;
-    INT pxUpArrow;
-    INT pxDownArrow;
-    INT pxStart;
-    INT pxThumbBottom;
-    INT pxThumbTop;
-    INT cpx;
-    INT pxMin;
-} SBCALC, *PSBCALC;
 typedef VOID (NEAR NTAPI *PFN_SCROLLBAR)(PWND, UINT, WPARAM, LPARAM, PSBCALC);
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/class.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/class.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/class.c [iso-8859-1] Thu Dec  1 03:20:02
2011
@@ -41,7 +41,7 @@
   { L"ScrollBar",
     CS_DBLCLKS|CS_VREDRAW|CS_HREDRAW|CS_PARENTDC,
     NULL, // Use User32 procs
-    0,
+    sizeof(SBWND)-sizeof(WND),
     IDC_ARROW,
     NULL,
     FNID_SCROLLBAR,
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/scrollbar.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/scrollbar.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/scrollbar.c [iso-8859-1] Thu Dec  1
03:20:02 2011
@@ -12,6 +12,12 @@
 #define MINTRACKTHUMB    8               /* Minimum size of the rectangle between the
arrows */
+ /* What to do after SetScrollInfo() */
+ #define SA_SSI_HIDE             0x0001
+ #define SA_SSI_SHOW             0x0002
+ #define SA_SSI_REFRESH          0x0004
+ #define SA_SSI_REPAINT_ARROWS   0x0008
+
 #define SBRG_SCROLLBAR     0 /* the scrollbar itself */
 #define SBRG_TOPRIGHTBTN   1 /* the top or right button */
 #define SBRG_PAGEUPRIGHT   2 /* the page up or page right region */
@@ -160,6 +166,7 @@
    LPSCROLLINFO psi;
    ASSERT(Window);
+   ASSERT(Window->pSBInfo);
    ASSERT(Window->pSBInfoex);
    sbi = IntGetScrollbarInfoFromWindow(Window, wBar);
@@ -183,10 +190,7 @@
       return FALSE;
    }
-   if(!co_IntCreateScrollBars(Window))
-   {
-      return FALSE;
-   }
+   if (!Window->pSBInfo) return FALSE;
    psi = IntGetScrollInfoFromWindow(Window, nBar);
@@ -239,6 +243,8 @@
      ERR("Trying to get scrollinfo for unknown scrollbar type %d\n", nBar);
      return FALSE;
   }
+
+  if (!pWnd->pSBInfo || !pSBTrack) return FALSE;
   Mask = lpsi->fMask;
@@ -280,7 +286,8 @@
    LPSCROLLINFO Info;
    PSCROLLBARINFO psbi;
-   /*   UINT new_flags;*/
+   UINT new_flags;
+   INT action = 0;
    BOOL bChangeParams = FALSE; /* don't show/hide scrollbar if params don't
change */
    ASSERT_REFS_CO(Window);
@@ -313,7 +320,7 @@
    Info = IntGetScrollInfoFromWindow(Window, nBar);
    /* Set the page size */
-   if (0 != (lpsi->fMask & SIF_PAGE))
+   if (lpsi->fMask & SIF_PAGE)
    {
       if (Info->nPage != lpsi->nPage)
       {
@@ -323,20 +330,21 @@
    }
    /* Set the scroll pos */
-   if (0 != (lpsi->fMask & SIF_POS))
+   if (lpsi->fMask & SIF_POS)
    {
       if (Info->nPos != lpsi->nPos)
       {
          Info->nPos = lpsi->nPos;
+         bChangeParams = TRUE;
       }
    }
    /* Set the scroll range */
-   if (0 != (lpsi->fMask & SIF_RANGE))
+   if (lpsi->fMask & SIF_RANGE)
    {
       /* Invalid range -> range is set to (0,0) */
-      if (lpsi->nMin > lpsi->nMax ||
-            0x80000000 <= (UINT)(lpsi->nMax - lpsi->nMin))
+      if ((lpsi->nMin > lpsi->nMax) ||
+                  ((UINT)(lpsi->nMax - lpsi->nMin) >= 0x80000000))
       {
          Info->nMin = 0;
          Info->nMax = 0;
@@ -351,7 +359,9 @@
    }
    /* Make sure the page size is valid */
-   if (Info->nMax - Info->nMin + 1 < Info->nPage)
+   if (Info->nPage < 0)
+      Info->nPage = 0;
+   else if (Info->nMax - Info->nMin + 1 < Info->nPage)
    {
       Info->nPage = Info->nMax - Info->nMin + 1;
    }
@@ -370,56 +380,77 @@
     * Don't change the scrollbar state if SetScrollInfo is just called
     * with SIF_DISABLENOSCROLL
     */
-   if (0 == (lpsi->fMask & SIF_ALL))
-   {
-      return Info->nPos;
+   if (!(lpsi->fMask & SIF_ALL))
+   {
+      goto done; //return Info->nPos;
    }
    /* Check if the scrollbar should be hidden or disabled */
-   if (0 != (lpsi->fMask & (SIF_RANGE | SIF_PAGE | SIF_DISABLENOSCROLL)))
-   {
+   if (lpsi->fMask & (SIF_RANGE | SIF_PAGE | SIF_DISABLENOSCROLL))
+   {
+      new_flags = Window->pSBInfo->WSBflags;
       if (Info->nMin >= (int)(Info->nMax - max(Info->nPage - 1, 0)))
       {
          /* Hide or disable scroll-bar */
-         if (0 != (lpsi->fMask & SIF_DISABLENOSCROLL))
-         {
-            /*            new_flags = ESB_DISABLE_BOTH;*/
+         if (lpsi->fMask & SIF_DISABLENOSCROLL)
+         {
+            new_flags = ESB_DISABLE_BOTH;
+            bChangeParams = TRUE;
          }
          else if ((nBar != SB_CTL) && bChangeParams)
          {
-            co_UserShowScrollBar(Window, nBar, FALSE);
-            return Info->nPos;
-         }
-      }
-      else  /* Show and enable scroll-bar */
-      {
-         /*         new_flags = 0;*/
+            action = SA_SSI_HIDE;
+            //co_UserShowScrollBar(Window, nBar, FALSE);
+            //return Info->nPos;
+         }
+      }
+      else /* Show and enable scroll-bar only if no page only changed. */
+      if (lpsi->fMask != SIF_PAGE)
+      {
+         new_flags = ESB_ENABLE_BOTH;
          if ((nBar != SB_CTL) && bChangeParams)
          {
-            co_UserShowScrollBar(Window, nBar, TRUE);
-         }
-      }
-
-#if 0
-      if (infoPtr->flags != new_flags) /* check arrow flags */
-      {
-         infoPtr->flags = new_flags;
-         *Action |= SA_SSI_REPAINT_ARROWS;
-      }
-#endif
-
-   }
-
-   if (bRedraw)
-   {
-      RECTL UpdateRect = psbi->rcScrollBar;
-      UpdateRect.left -= Window->rcClient.left - Window->rcWindow.left;
-      UpdateRect.right -= Window->rcClient.left - Window->rcWindow.left;
-      UpdateRect.top -= Window->rcClient.top - Window->rcWindow.top;
-      UpdateRect.bottom -= Window->rcClient.top - Window->rcWindow.top;
-      co_UserRedrawWindow(Window, &UpdateRect, 0, RDW_INVALIDATE | RDW_FRAME);
-   }
-
+            action |= SA_SSI_SHOW;
+            //co_UserShowScrollBar(Window, nBar, TRUE);
+         }
+      }
+
+      if (Window->pSBInfo->WSBflags != new_flags) /* check arrow flags */
+      {
+         Window->pSBInfo->WSBflags = new_flags;
+         action |= SA_SSI_REPAINT_ARROWS;
+      }
+   }
+
+done:
+   if ( action & SA_SSI_HIDE )
+   {
+      co_UserShowScrollBar(Window, nBar, FALSE);
+   }
+   else
+   {
+      if ( action & SA_SSI_SHOW )
+         if ( co_UserShowScrollBar(Window, nBar, TRUE) )
+            return Info->nPos; /* SetWindowPos() already did the painting */
+      if (bRedraw)
+      { // FIXME: Arrows and interior.
+         RECTL UpdateRect = psbi->rcScrollBar;
+         UpdateRect.left -= Window->rcClient.left - Window->rcWindow.left;
+         UpdateRect.right -= Window->rcClient.left - Window->rcWindow.left;
+         UpdateRect.top -= Window->rcClient.top - Window->rcWindow.top;
+         UpdateRect.bottom -= Window->rcClient.top - Window->rcWindow.top;
+         co_UserRedrawWindow(Window, &UpdateRect, 0, RDW_INVALIDATE | RDW_FRAME);
+      } // FIXME: Arrows
+      else if( action & SA_SSI_REPAINT_ARROWS )
+      {
+         RECTL UpdateRect = psbi->rcScrollBar;
+         UpdateRect.left -= Window->rcClient.left - Window->rcWindow.left;
+         UpdateRect.right -= Window->rcClient.left - Window->rcWindow.left;
+         UpdateRect.top -= Window->rcClient.top - Window->rcWindow.top;
+         UpdateRect.bottom -= Window->rcClient.top - Window->rcWindow.top;
+         co_UserRedrawWindow(Window, &UpdateRect, 0, RDW_INVALIDATE | RDW_FRAME);
+      }
+   }
    /* Return current position */
    return Info->nPos;
 }
@@ -430,7 +461,6 @@
    INT Bar;
    PSCROLLBARINFO sbi;
    LPSCROLLINFO psi;
-
    ASSERT_REFS_CO(Window);
    Bar = SBOBJ_TO_SBID(idObject);
@@ -468,7 +498,7 @@
    ASSERT_REFS_CO(Window);
-   if(Window->pSBInfoex)
+   if (Window->pSBInfo && Window->pSBInfoex)
    {
       /* no need to create it anymore */
       return TRUE;
@@ -483,6 +513,14 @@
    }
    RtlZeroMemory(Window->pSBInfoex, Size);
+
+   if(!(Window->pSBInfo = DesktopHeapAlloc( Window->head.rpdesk, sizeof(SBINFO))))
+   {
+      ERR("Unable to allocate memory for scrollbar information for window
0x%x\n", Window->head.h);
+      return FALSE;
+   }
+
+   RtlZeroMemory(Window->pSBInfo, sizeof(SBINFO));
    co_WinPosGetNonClientSize(Window,
                              &Window->rcWindow,
@@ -509,8 +547,10 @@
 BOOL FASTCALL
 IntDestroyScrollBars(PWND Window)
 {
-   if(Window->pSBInfoex)
-   {
+   if (Window->pSBInfo && Window->pSBInfoex)
+   {
+      DesktopHeapFree(Window->head.rpdesk, Window->pSBInfo);
+      Window->pSBInfo = NULL;
       ExFreePool(Window->pSBInfoex);
       Window->pSBInfoex = NULL;
       return TRUE;
@@ -662,7 +702,6 @@
    END_CLEANUP;
 }
-
 BOOL
 APIENTRY
 NtUserEnableScrollBar(
@@ -679,19 +718,23 @@
    TRACE("Enter NtUserEnableScrollBar\n");
    UserEnterExclusive();
-   if(!(Window = UserGetWindowObject(hWnd)))
+   if (!(Window = UserGetWindowObject(hWnd)))
    {
       RETURN(FALSE);
    }
    UserRefObjectCo(Window, &Ref);
-   if(wSBflags == SB_CTL)
-   {
-      /* FIXME Enable or Disable SB Ctrl*/
-      ERR("Enable Scrollbar SB_CTL\n");
-      InfoV = IntGetScrollbarInfoFromWindow(Window, SB_CTL);
-      Chg = IntEnableScrollBar(FALSE, InfoV ,wArrows);
-      /* Chg? Scrollbar is Refresh in user32/controls/scrollbar.c. */
+   if (!co_IntCreateScrollBars(Window))
+   {
+      RETURN( FALSE);
+   }
+
+   Window->pSBInfo->WSBflags = wArrows;
+
+   if (wSBflags == SB_CTL)
+   {
+      if ((wArrows == ESB_DISABLE_BOTH || wArrows == ESB_ENABLE_BOTH))
+         IntEnableWindow(hWnd, (wArrows == ESB_ENABLE_BOTH));
       RETURN(TRUE);
    }
@@ -707,6 +750,8 @@
    {
       RETURN( FALSE);
    }
+
+   Window->pSBInfo->WSBflags = wArrows;
    switch(wSBflags)
    {
@@ -728,10 +773,11 @@
    if(InfoH)
       Chg = (IntEnableScrollBar(TRUE, InfoH, wArrows) || Chg);
-
-   //if(Chg && (Window->style & WS_VISIBLE))
-   /* FIXME - repaint scrollbars */
-
+
+   ERR("FIXME: EnableScrollBar wSBflags %d wArrows %d\n",wSBflags,wArrows);
+// Done in user32:
+//   SCROLL_RefreshScrollBar( hwnd, nBar, TRUE, TRUE );
+
    RETURN( TRUE);
 CLEANUP:
@@ -875,14 +921,9 @@
          return( FALSE);
    }
-   if(!co_IntCreateScrollBars(Wnd))
-   {
-      return( FALSE);
-   }
-
    if (wBar == SB_CTL)
    {
-      IntUpdateSBInfo(Wnd, SB_CTL);
+      if (Wnd->pSBInfo) IntUpdateSBInfo(Wnd, SB_CTL);
       co_WinPosShowWindow(Wnd, bShow ? SW_SHOW : SW_HIDE);
       return( TRUE);