From eb9eb149da86965f08415244c59ab5e03378fcb3 Mon Sep 17 00:00:00 2001 From: James Tabor Date: Thu, 1 Dec 2011 12:42:05 +0000 Subject: [PATCH] [Win32k|User32] - Fix regressions, running RegEdit. Adding more support for scroll bar controls. Pass all but 7 tests including the two wine todos. svn path=/trunk/; revision=54556 --- reactos/dll/win32/user32/controls/scrollbar.c | 76 +++-- .../win32/win32k/include/userfuncs.h | 2 +- .../subsystems/win32/win32k/ntuser/message.c | 16 + .../win32/win32k/ntuser/scrollbar.c | 283 +++++++++--------- .../subsystems/win32/win32k/ntuser/window.c | 4 +- 5 files changed, 206 insertions(+), 175 deletions(-) diff --git a/reactos/dll/win32/user32/controls/scrollbar.c b/reactos/dll/win32/user32/controls/scrollbar.c index cdfcbcdd4b2..ae471ad04e8 100644 --- a/reactos/dll/win32/user32/controls/scrollbar.c +++ b/reactos/dll/win32/user32/controls/scrollbar.c @@ -309,7 +309,7 @@ IntGetScrollBarInfo(HWND Wnd, INT Bar, PSCROLLBARINFO ScrollBarInfo) void IntDrawScrollBar(HWND Wnd, HDC DC, INT Bar) { - //PSBTRACK pSBTrack; + //PSBWND pSBWnd; //INT ThumbSize; SCROLLBARINFO Info; BOOL Vertical; @@ -344,7 +344,7 @@ IntDrawScrollBar(HWND Wnd, HDC DC, INT Bar) return; } - //ThumbSize = pSBTrack->pSBCalc->pxThumbBottom - pSBTrack->pSBCalc->pxThumbTop; + //ThumbSize = pSBWnd->pSBCalc->pxThumbBottom - pSBWnd->pSBCalc->pxThumbTop; /* * Draw the arrows. @@ -482,6 +482,11 @@ IntScrollGetScrollBarRect(HWND Wnd, INT Bar, RECT *Rect, RECT ClientRect; RECT WindowRect; DWORD Style, ExStyle; + PWND pWnd; + PSBINFO pSBInfo; + + pWnd = ValidateHwnd( Wnd ); + pSBInfo = DesktopPtrToUser(pWnd->pSBInfo); GetClientRect(Wnd, &ClientRect); if (SB_HORZ == Bar || SB_VERT == Bar) @@ -587,12 +592,8 @@ IntScrollGetScrollBarRect(HWND Wnd, INT Bar, RECT *Rect, *ThumbSize = GetSystemMetrics(SM_CXVSCROLL); } -#if 0 /* FIXME */ - if (((pixels -= *ThumbSize ) < 0) || - ((info->flags & ESB_DISABLE_BOTH) == ESB_DISABLE_BOTH)) -#else - if ((Pixels -= *ThumbSize ) < 0) -#endif + if (((Pixels -= *ThumbSize ) < 0) || + (( pSBInfo->WSBflags & ESB_DISABLE_BOTH) == ESB_DISABLE_BOTH)) { /* Rectangle too small or scrollbar disabled -> no thumb */ *ThumbPos = *ThumbSize = 0; @@ -1090,13 +1091,13 @@ static void IntScrollCreateScrollBar( TRACE("hwnd=%p lpCreate=%p\n", Wnd, lpCreate); -#if 0 /* FIXME */ if (lpCreate->style & WS_DISABLED) - { - info->flags = ESB_DISABLE_BOTH; - TRACE("Created WS_DISABLED scrollbar\n"); - } -#endif + { + // info->flags = ESB_DISABLE_BOTH; + //NtUserEnableScrollBar(Wnd,SB_CTL,(wParam ? ESB_ENABLE_BOTH : ESB_DISABLE_BOTH)); + NtUserMessageCall( Wnd, WM_ENABLE, FALSE, 0, 0, FNID_SCROLLBAR, FALSE); + ERR("Created WS_DISABLED scrollbar\n"); + } if (0 != (lpCreate->style & (SBS_SIZEGRIP | SBS_SIZEBOX))) { @@ -1152,10 +1153,10 @@ IntScrollGetScrollPos(HWND Wnd, INT Bar) ScrollInfo.cbSize = sizeof(SCROLLINFO); ScrollInfo.fMask = SIF_POS; - if (! NtUserSBGetParms(Wnd, Bar, NULL, &ScrollInfo)) - { + if (!NtUserSBGetParms(Wnd, Bar, NULL, &ScrollInfo)) + { return 0; - } + } return ScrollInfo.nPos; } @@ -1167,10 +1168,10 @@ IntScrollGetScrollRange(HWND Wnd, int Bar, LPINT MinPos, LPINT MaxPos) SCROLLINFO ScrollInfo; if (NULL == MinPos || NULL == MaxPos) - { + { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; - } + } ScrollInfo.cbSize = sizeof(SCROLLINFO); ScrollInfo.fMask = SIF_RANGE; @@ -1276,10 +1277,15 @@ ScrollBarWndProc_common(WNDPROC DefWindowProc, HWND Wnd, UINT Msg, WPARAM wParam case WM_ENABLE: { - TRACE("ScrollBarWndProc WM_ENABLE\n"); - NtUserEnableScrollBar(Wnd,SB_CTL,(wParam ? ESB_ENABLE_BOTH : ESB_DISABLE_BOTH)); - /* Refresh Scrollbars. */ - SCROLL_RefreshScrollBar(Wnd, SB_CTL, TRUE, TRUE); + PWND pWnd = ValidateHwnd(Wnd); + if (pWnd->pSBInfo) + { + ERR("ScrollBarWndProc WM_ENABLE\n"); + //NtUserEnableScrollBar(Wnd,SB_CTL,(wParam ? ESB_ENABLE_BOTH : ESB_DISABLE_BOTH)); + NtUserMessageCall( Wnd, Msg, wParam, lParam, 0, FNID_SCROLLBAR, !unicode); + /* Refresh Scrollbars. */ + SCROLL_RefreshScrollBar(Wnd, SB_CTL, TRUE, TRUE); + } } return 0; @@ -1641,9 +1647,13 @@ SetScrollInfo(HWND Wnd, int SBType, LPCSCROLLINFO Info, BOOL bRedraw) INT WINAPI SetScrollPos(HWND hWnd, INT nBar, INT nPos, BOOL bRedraw) { + PWND pWnd; INT Result = 0; SCROLLINFO ScrollInfo; + pWnd = ValidateHwnd(hWnd); + if ( !pWnd || !pWnd->pSBInfo ) return 0; + ScrollInfo.cbSize = sizeof(SCROLLINFO); ScrollInfo.fMask = SIF_POS; @@ -1652,15 +1662,15 @@ SetScrollPos(HWND hWnd, INT nBar, INT nPos, BOOL bRedraw) * we will later return. */ if (NtUserSBGetParms(hWnd, nBar, NULL, &ScrollInfo)) - { + { Result = ScrollInfo.nPos; if (Result != nPos) - { + { ScrollInfo.nPos = nPos; /* Finally set the new position */ NtUserSetScrollInfo(hWnd, nBar, &ScrollInfo, bRedraw); - } - } + } + } return Result; } @@ -1671,13 +1681,23 @@ SetScrollPos(HWND hWnd, INT nBar, INT nPos, BOOL bRedraw) BOOL WINAPI SetScrollRange(HWND hWnd, INT nBar, INT nMinPos, INT nMaxPos, BOOL bRedraw) { + PWND pWnd; SCROLLINFO ScrollInfo; + pWnd = ValidateHwnd(hWnd); + if ( !pWnd ) return FALSE; + + if ((nMaxPos - nMinPos) > MAXLONG) + { + SetLastError(ERROR_INVALID_SCROLLBAR_RANGE); + return FALSE; + } + ScrollInfo.cbSize = sizeof(SCROLLINFO); ScrollInfo.fMask = SIF_RANGE; ScrollInfo.nMin = nMinPos; ScrollInfo.nMax = nMaxPos; - NtUserSetScrollInfo(hWnd, nBar, &ScrollInfo, bRedraw); + SetScrollInfo(hWnd, nBar, &ScrollInfo, bRedraw); // do not bypass themes. return TRUE; } diff --git a/reactos/subsystems/win32/win32k/include/userfuncs.h b/reactos/subsystems/win32/win32k/include/userfuncs.h index 17b64542382..4d467a0e70e 100644 --- a/reactos/subsystems/win32/win32k/include/userfuncs.h +++ b/reactos/subsystems/win32/win32k/include/userfuncs.h @@ -107,6 +107,6 @@ BOOL FASTCALL UserDestroyMenu(HMENU hMenu); /*************** SCROLLBAR.C ***************/ DWORD FASTCALL -co_UserShowScrollBar(PWND Window, int wBar, DWORD bShow); +co_UserShowScrollBar(PWND Wnd, int nBar, BOOL fShowH, BOOL fShowV); /* EOF */ diff --git a/reactos/subsystems/win32/win32k/ntuser/message.c b/reactos/subsystems/win32/win32k/ntuser/message.c index ff138fbd61b..af3187d2f6f 100644 --- a/reactos/subsystems/win32/win32k/ntuser/message.c +++ b/reactos/subsystems/win32/win32k/ntuser/message.c @@ -2044,6 +2044,22 @@ NtUserMessageCall( HWND hWnd, switch(dwType) { + case FNID_SCROLLBAR: + { + switch(Msg) + { + case WM_ENABLE: + { + Window = UserGetWindowObject(hWnd); + if (Window->pSBInfo) + { + Window->pSBInfo->WSBflags = wParam ? ESB_ENABLE_BOTH : ESB_DISABLE_BOTH; + } + } + break; + } + break; + } case FNID_DEFWINDOWPROC: /* Validate input */ if (hWnd) diff --git a/reactos/subsystems/win32/win32k/ntuser/scrollbar.c b/reactos/subsystems/win32/win32k/ntuser/scrollbar.c index 8bdd8eb9867..f5d2c22b517 100644 --- a/reactos/subsystems/win32/win32k/ntuser/scrollbar.c +++ b/reactos/subsystems/win32/win32k/ntuser/scrollbar.c @@ -400,8 +400,6 @@ co_IntSetScrollInfo(PWND Window, INT nBar, LPCSCROLLINFO lpsi, BOOL bRedraw) else if ((nBar != SB_CTL) && bChangeParams) { action = SA_SSI_HIDE; - //co_UserShowScrollBar(Window, nBar, FALSE); - //return Info->nPos; } } else /* Show and enable scroll-bar only if no page only changed. */ @@ -411,7 +409,6 @@ co_IntSetScrollInfo(PWND Window, INT nBar, LPCSCROLLINFO lpsi, BOOL bRedraw) if ((nBar != SB_CTL) && bChangeParams) { action |= SA_SSI_SHOW; - //co_UserShowScrollBar(Window, nBar, TRUE); } } @@ -425,12 +422,12 @@ co_IntSetScrollInfo(PWND Window, INT nBar, LPCSCROLLINFO lpsi, BOOL bRedraw) done: if ( action & SA_SSI_HIDE ) { - co_UserShowScrollBar(Window, nBar, FALSE); + co_UserShowScrollBar(Window, nBar, FALSE, FALSE); } else { if ( action & SA_SSI_SHOW ) - if ( co_UserShowScrollBar(Window, nBar, TRUE) ) + if ( co_UserShowScrollBar(Window, nBar, TRUE, TRUE) ) return Info->nPos; /* SetWindowPos() already did the painting */ if (bRedraw) { // FIXME: Arrows and interior. @@ -521,6 +518,8 @@ co_IntCreateScrollBars(PWND Window) } RtlZeroMemory(Window->pSBInfo, sizeof(SBINFO)); + Window->pSBInfo->Vert.posMax = 100; + Window->pSBInfo->Horz.posMax = 100; co_WinPosGetNonClientSize(Window, &Window->rcWindow, @@ -596,6 +595,62 @@ IntEnableScrollBar(BOOL Horz, PSCROLLBARINFO Info, UINT wArrows) return Chg; } +/* Ported from WINE20020904 (SCROLL_ShowScrollBar) */ +DWORD FASTCALL +co_UserShowScrollBar(PWND Wnd, int nBar, BOOL fShowH, BOOL fShowV) +{ + ULONG old_style, set_bits = 0, clear_bits = 0; + + ASSERT_REFS_CO(Wnd); + + switch(nBar) + { + case SB_CTL: + { + if (Wnd->pSBInfo) IntUpdateSBInfo(Wnd, SB_CTL); // Is this needed? Was tested w/o! + + co_WinPosShowWindow(Wnd, fShowH ? SW_SHOW : SW_HIDE); + return TRUE; + } + case SB_BOTH: + case SB_HORZ: + if (fShowH) set_bits |= WS_HSCROLL; + else clear_bits |= WS_HSCROLL; + if( nBar == SB_HORZ ) break; + /* fall through */ + case SB_VERT: + if (fShowV) set_bits |= WS_VSCROLL; + else clear_bits |= WS_VSCROLL; + break; + default: + EngSetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + + old_style = Wnd->style; + Wnd->style = (Wnd->style | set_bits) & ~clear_bits; + + if (fShowH || fShowV) + { + if (!Wnd->pSBInfo) co_IntCreateScrollBars(Wnd); + } + + if ((old_style & clear_bits) != 0 || (old_style & set_bits) != set_bits) + { + ///// Is this needed? Was tested w/o! + if (Wnd->style & WS_HSCROLL) IntUpdateSBInfo(Wnd, SB_HORZ); + if (Wnd->style & WS_VSCROLL) IntUpdateSBInfo(Wnd, SB_VERT); + ///// + /* Frame has been changed, let the window redraw itself */ + co_WinPosSetWindowPos(Wnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | + SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOSENDCHANGING); + return TRUE; + } + return FALSE; +} + +//// BOOL APIENTRY @@ -643,7 +698,6 @@ CLEANUP: } - BOOL APIENTRY NtUserSBGetParms( @@ -709,6 +763,7 @@ NtUserEnableScrollBar( UINT wSBflags, UINT wArrows) { + UINT OrigArrows; PWND Window = NULL; PSCROLLBARINFO InfoV = NULL, InfoH = NULL; BOOL Chg = FALSE; @@ -729,6 +784,7 @@ NtUserEnableScrollBar( RETURN( FALSE); } + OrigArrows = Window->pSBInfo->WSBflags; Window->pSBInfo->WSBflags = wArrows; if (wSBflags == SB_CTL) @@ -746,13 +802,6 @@ NtUserEnableScrollBar( RETURN(FALSE); } - if(!co_IntCreateScrollBars(Window)) - { - RETURN( FALSE); - } - - Window->pSBInfo->WSBflags = wArrows; - switch(wSBflags) { case SB_BOTH: @@ -774,10 +823,11 @@ NtUserEnableScrollBar( if(InfoH) Chg = (IntEnableScrollBar(TRUE, InfoH, wArrows) || Chg); - ERR("FIXME: EnableScrollBar wSBflags %d wArrows %d\n",wSBflags,wArrows); + ERR("FIXME: EnableScrollBar wSBflags %d wArrows %d Chg %d\n",wSBflags,wArrows, Chg); // Done in user32: // SCROLL_RefreshScrollBar( hwnd, nBar, TRUE, TRUE ); + if (OrigArrows == wArrows) RETURN( FALSE); RETURN( TRUE); CLEANUP: @@ -789,6 +839,81 @@ CLEANUP: END_CLEANUP; } +DWORD +APIENTRY +NtUserSetScrollInfo( + HWND hWnd, + int fnBar, + LPCSCROLLINFO lpsi, + BOOL bRedraw) +{ + PWND Window = NULL; + NTSTATUS Status; + SCROLLINFO ScrollInfo; + DECLARE_RETURN(DWORD); + USER_REFERENCE_ENTRY Ref; + + TRACE("Enter NtUserSetScrollInfo\n"); + UserEnterExclusive(); + + if(!(Window = UserGetWindowObject(hWnd))) + { + RETURN( 0); + } + UserRefObjectCo(Window, &Ref); + + Status = MmCopyFromCaller(&ScrollInfo, lpsi, sizeof(SCROLLINFO) - sizeof(ScrollInfo.nTrackPos)); + if(!NT_SUCCESS(Status)) + { + SetLastNtError(Status); + RETURN( 0); + } + + RETURN(co_IntSetScrollInfo(Window, fnBar, &ScrollInfo, bRedraw)); + +CLEANUP: + if (Window) + UserDerefObjectCo(Window); + + TRACE("Leave NtUserSetScrollInfo, ret=%i\n",_ret_); + UserLeave(); + END_CLEANUP; + +} + +DWORD APIENTRY +NtUserShowScrollBar(HWND hWnd, int nBar, DWORD bShow) +{ + PWND Window; + DECLARE_RETURN(DWORD); + DWORD ret; + USER_REFERENCE_ENTRY Ref; + + TRACE("Enter NtUserShowScrollBar\n"); + UserEnterExclusive(); + + if (!(Window = UserGetWindowObject(hWnd))) + { + RETURN(0); + } + + UserRefObjectCo(Window, &Ref); + ret = co_UserShowScrollBar(Window, nBar, (nBar == SB_VERT) ? 0 : bShow, + (nBar == SB_HORZ) ? 0 : bShow); + UserDerefObjectCo(Window); + + RETURN(ret); + +CLEANUP: + TRACE("Leave NtUserShowScrollBar, ret%i\n",_ret_); + UserLeave(); + END_CLEANUP; + +} + + +//// Ugly NtUser API //// + BOOL APIENTRY NtUserSetScrollBarInfo( @@ -852,134 +977,4 @@ CLEANUP: END_CLEANUP; } -DWORD -APIENTRY -NtUserSetScrollInfo( - HWND hWnd, - int fnBar, - LPCSCROLLINFO lpsi, - BOOL bRedraw) -{ - PWND Window = NULL; - NTSTATUS Status; - SCROLLINFO ScrollInfo; - DECLARE_RETURN(DWORD); - USER_REFERENCE_ENTRY Ref; - - TRACE("Enter NtUserSetScrollInfo\n"); - UserEnterExclusive(); - - if(!(Window = UserGetWindowObject(hWnd))) - { - RETURN( 0); - } - UserRefObjectCo(Window, &Ref); - - Status = MmCopyFromCaller(&ScrollInfo, lpsi, sizeof(SCROLLINFO) - sizeof(ScrollInfo.nTrackPos)); - if(!NT_SUCCESS(Status)) - { - SetLastNtError(Status); - RETURN( 0); - } - - RETURN(co_IntSetScrollInfo(Window, fnBar, &ScrollInfo, bRedraw)); - -CLEANUP: - if (Window) - UserDerefObjectCo(Window); - - TRACE("Leave NtUserSetScrollInfo, ret=%i\n",_ret_); - UserLeave(); - END_CLEANUP; - -} - -/* Ported from WINE20020904 (SCROLL_ShowScrollBar) */ -DWORD FASTCALL -co_UserShowScrollBar(PWND Wnd, int wBar, DWORD bShow) -{ - DWORD Style, OldStyle; - - ASSERT_REFS_CO(Wnd); - - switch(wBar) - { - case SB_HORZ: - Style = WS_HSCROLL; - break; - case SB_VERT: - Style = WS_VSCROLL; - break; - case SB_BOTH: - Style = WS_HSCROLL | WS_VSCROLL; - break; - case SB_CTL: - Style = 0; - break; - default: - EngSetLastError(ERROR_INVALID_PARAMETER); - return( FALSE); - } - - if (wBar == SB_CTL) - { - if (Wnd->pSBInfo) IntUpdateSBInfo(Wnd, SB_CTL); - - co_WinPosShowWindow(Wnd, bShow ? SW_SHOW : SW_HIDE); - return( TRUE); - } - - OldStyle = Wnd->style; - if(bShow) - Wnd->style |= Style; - else - Wnd->style &= ~Style; - - if(Wnd->style != OldStyle) - { - if(Wnd->style & WS_HSCROLL) - IntUpdateSBInfo(Wnd, SB_HORZ); - if(Wnd->style & WS_VSCROLL) - IntUpdateSBInfo(Wnd, SB_VERT); - - if(Wnd->style & WS_VISIBLE) - { - /* Frame has been changed, let the window redraw itself */ - co_WinPosSetWindowPos(Wnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | - SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOSENDCHANGING); - } - } - - return( TRUE); -} - - -DWORD APIENTRY -NtUserShowScrollBar(HWND hWnd, int wBar, DWORD bShow) -{ - PWND Window; - DECLARE_RETURN(DWORD); - DWORD ret; - USER_REFERENCE_ENTRY Ref; - - TRACE("Enter NtUserShowScrollBar\n"); - UserEnterExclusive(); - - if (!(Window = UserGetWindowObject(hWnd))) - { - RETURN(0); - } - - UserRefObjectCo(Window, &Ref); - ret = co_UserShowScrollBar(Window, wBar, bShow); - UserDerefObjectCo(Window); - - RETURN(ret); - -CLEANUP: - TRACE("Leave NtUserShowScrollBar, ret%i\n",_ret_); - UserLeave(); - END_CLEANUP; - -} /* EOF */ diff --git a/reactos/subsystems/win32/win32k/ntuser/window.c b/reactos/subsystems/win32/win32k/ntuser/window.c index 91f79191d39..a6a9007c664 100644 --- a/reactos/subsystems/win32/win32k/ntuser/window.c +++ b/reactos/subsystems/win32/win32k/ntuser/window.c @@ -2148,11 +2148,11 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs, /* Initialize and show the window's scrollbars */ if (Window->style & WS_VSCROLL) { - co_UserShowScrollBar(Window, SB_VERT, TRUE); + co_UserShowScrollBar(Window, SB_VERT, FALSE, TRUE); } if (Window->style & WS_HSCROLL) { - co_UserShowScrollBar(Window, SB_HORZ, TRUE); + co_UserShowScrollBar(Window, SB_HORZ, TRUE, FALSE); } /* Show the new window */