[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.

svn path=/trunk/; revision=54555
This commit is contained in:
James Tabor 2011-12-01 03:20:02 +00:00
parent b1b439d600
commit c156702b26
5 changed files with 155 additions and 114 deletions

View file

@ -1,5 +1,4 @@
/* $Id $
*
/*
* ReactOS User32 Library
* - ScrollBar control
*
@ -80,7 +79,7 @@ const struct builtin_class_descr SCROLL_builtin_class =
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 @@ IntGetScrollBarInfo(HWND Wnd, INT Bar, PSCROLLBARINFO ScrollBarInfo)
void
IntDrawScrollBar(HWND Wnd, HDC DC, INT Bar)
{
//PSBTRACK pSBTrack;
//INT ThumbSize;
SCROLLBARINFO Info;
BOOL Vertical;
@ -344,7 +344,7 @@ IntDrawScrollBar(HWND Wnd, HDC DC, INT Bar)
return;
}
//ThumbSize = Info.xyThumbBottom - Info.xyThumbTop;
//ThumbSize = pSBTrack->pSBCalc->pxThumbBottom - pSBTrack->pSBCalc->pxThumbTop;
/*
* Draw the arrows.
@ -1175,11 +1175,8 @@ IntScrollGetScrollRange(HWND Wnd, int Bar, LPINT MinPos, LPINT MaxPos)
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 @@ ScrollTrackScrollBar(HWND Wnd, INT SBType, POINT Pt)
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 @@ ScrollTrackScrollBar(HWND Wnd, INT SBType, POINT Pt)
* 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 @@ ScrollBarWndProc(WNDPROC DefWindowProc, HWND Wnd, UINT Msg, WPARAM wParam, LPARA
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 @@ ScrollBarWndProc(WNDPROC DefWindowProc, HWND Wnd, UINT Msg, WPARAM wParam, LPARA
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 @@ ScrollBarWndProc(WNDPROC DefWindowProc, HWND Wnd, UINT Msg, WPARAM wParam, LPARA
{
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 @@ ScrollBarWndProc(WNDPROC DefWindowProc, HWND Wnd, UINT Msg, WPARAM wParam, LPARA
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 @@ BOOL WINAPI EnableScrollBar( HWND hwnd, UINT nBar, UINT flags )
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);

View file

@ -397,6 +397,26 @@ typedef struct tagSBINFO
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
{
UserGetCPDA2U = 0x01, // " Unicode "
@ -616,6 +636,14 @@ typedef struct _WND
LIST_ENTRY ThreadListEntry;
} WND, *PWND;
typedef struct _SBWND
{
WND wnd;
BOOL fVert;
UINT wDisableFlags;
SBCALC SBCalc;
} SBWND, *PSBWND;
typedef struct _PFNCLIENT
{
WNDPROC pfnScrollBarWndProc;

View file

@ -1,25 +1,5 @@
#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);
typedef struct tagSBTRACK

View file

@ -41,7 +41,7 @@ REGISTER_SYSCLASS DefaultServerClasses[] =
{ L"ScrollBar",
CS_DBLCLKS|CS_VREDRAW|CS_HREDRAW|CS_PARENTDC,
NULL, // Use User32 procs
0,
sizeof(SBWND)-sizeof(WND),
IDC_ARROW,
NULL,
FNID_SCROLLBAR,

View file

@ -12,6 +12,12 @@ DBG_DEFAULT_CHANNEL(UserScrollbar);
#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 @@ IntUpdateSBInfo(PWND Window, int wBar)
LPSCROLLINFO psi;
ASSERT(Window);
ASSERT(Window->pSBInfo);
ASSERT(Window->pSBInfoex);
sbi = IntGetScrollbarInfoFromWindow(Window, wBar);
@ -183,10 +190,7 @@ co_IntGetScrollInfo(PWND Window, INT nBar, LPSCROLLINFO lpsi)
return FALSE;
}
if(!co_IntCreateScrollBars(Window))
{
return FALSE;
}
if (!Window->pSBInfo) return FALSE;
psi = IntGetScrollInfoFromWindow(Window, nBar);
@ -240,6 +244,8 @@ NEWco_IntGetScrollInfo(
return FALSE;
}
if (!pWnd->pSBInfo || !pSBTrack) return FALSE;
Mask = lpsi->fMask;
if (0 != (Mask & SIF_PAGE))
@ -280,7 +286,8 @@ co_IntSetScrollInfo(PWND Window, INT nBar, LPCSCROLLINFO lpsi, BOOL bRedraw)
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 @@ co_IntSetScrollInfo(PWND Window, INT nBar, LPCSCROLLINFO lpsi, BOOL bRedraw)
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 @@ co_IntSetScrollInfo(PWND Window, INT nBar, LPCSCROLLINFO lpsi, BOOL bRedraw)
}
/* 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 @@ co_IntSetScrollInfo(PWND Window, INT nBar, LPCSCROLLINFO lpsi, BOOL bRedraw)
}
/* 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 @@ co_IntSetScrollInfo(PWND Window, INT nBar, LPCSCROLLINFO lpsi, BOOL bRedraw)
* Don't change the scrollbar state if SetScrollInfo is just called
* with SIF_DISABLENOSCROLL
*/
if (0 == (lpsi->fMask & SIF_ALL))
if (!(lpsi->fMask & SIF_ALL))
{
return Info->nPos;
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))
if (lpsi->fMask & SIF_DISABLENOSCROLL)
{
/* new_flags = ESB_DISABLE_BOTH;*/
new_flags = ESB_DISABLE_BOTH;
bChangeParams = TRUE;
}
else if ((nBar != SB_CTL) && bChangeParams)
{
co_UserShowScrollBar(Window, nBar, FALSE);
return Info->nPos;
action = SA_SSI_HIDE;
//co_UserShowScrollBar(Window, nBar, FALSE);
//return Info->nPos;
}
}
else /* Show and enable scroll-bar */
else /* Show and enable scroll-bar only if no page only changed. */
if (lpsi->fMask != SIF_PAGE)
{
/* new_flags = 0;*/
new_flags = ESB_ENABLE_BOTH;
if ((nBar != SB_CTL) && bChangeParams)
{
co_UserShowScrollBar(Window, nBar, TRUE);
action |= SA_SSI_SHOW;
//co_UserShowScrollBar(Window, nBar, TRUE);
}
}
#if 0
if (infoPtr->flags != new_flags) /* check arrow flags */
if (Window->pSBInfo->WSBflags != new_flags) /* check arrow flags */
{
infoPtr->flags = new_flags;
*Action |= SA_SSI_REPAINT_ARROWS;
Window->pSBInfo->WSBflags = new_flags;
action |= SA_SSI_REPAINT_ARROWS;
}
#endif
}
if (bRedraw)
done:
if ( action & SA_SSI_HIDE )
{
co_UserShowScrollBar(Window, nBar, FALSE);
}
else
{
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);
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 @@ co_IntGetScrollBarInfo(PWND Window, LONG idObject, PSCROLLBARINFO psbi)
INT Bar;
PSCROLLBARINFO sbi;
LPSCROLLINFO psi;
ASSERT_REFS_CO(Window);
Bar = SBOBJ_TO_SBID(idObject);
@ -468,7 +498,7 @@ co_IntCreateScrollBars(PWND Window)
ASSERT_REFS_CO(Window);
if(Window->pSBInfoex)
if (Window->pSBInfo && Window->pSBInfoex)
{
/* no need to create it anymore */
return TRUE;
@ -484,6 +514,14 @@ co_IntCreateScrollBars(PWND Window)
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,
&Window->rcClient);
@ -509,8 +547,10 @@ co_IntCreateScrollBars(PWND Window)
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 @@ CLEANUP:
END_CLEANUP;
}
BOOL
APIENTRY
NtUserEnableScrollBar(
@ -679,19 +718,23 @@ NtUserEnableScrollBar(
TRACE("Enter NtUserEnableScrollBar\n");
UserEnterExclusive();
if(!(Window = UserGetWindowObject(hWnd)))
if (!(Window = UserGetWindowObject(hWnd)))
{
RETURN(FALSE);
}
UserRefObjectCo(Window, &Ref);
if(wSBflags == SB_CTL)
if (!co_IntCreateScrollBars(Window))
{
/* 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. */
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);
}
@ -708,6 +751,8 @@ NtUserEnableScrollBar(
RETURN( FALSE);
}
Window->pSBInfo->WSBflags = wArrows;
switch(wSBflags)
{
case SB_BOTH:
@ -728,10 +773,11 @@ NtUserEnableScrollBar(
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 @@ co_UserShowScrollBar(PWND Wnd, int wBar, DWORD bShow)
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);