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/s... ============================================================================== --- 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/ntus... ============================================================================== --- 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/inc... ============================================================================== --- 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/ntu... ============================================================================== --- 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/ntu... ============================================================================== --- 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);