* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: scrollbar.c,v 1.10 2003/09/07 11:52:54 weiden Exp $
+/* $Id$
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PURPOSE: Scrollbars
* FILE: subsys/win32k/ntuser/scrollbar.c
- * PROGRAMER: Jason Filby (jasonfilby@yahoo.com)
+ * PROGRAMER: Thomas Weidenmueller (w3seek@users.sourceforge.net)
+ * Jason Filby (jasonfilby@yahoo.com)
* REVISION HISTORY:
* 16-11-2002 Jason Filby Created
*/
/* INCLUDES ******************************************************************/
-#include <ddk/ntddk.h>
-#include <win32k/win32k.h>
-#include <include/object.h>
-#include <include/window.h>
-#include <include/class.h>
-#include <include/error.h>
-#include <include/winsta.h>
-#include <include/winpos.h>
-#include <include/rect.h>
-#include <include/scroll.h>
-
-//#define NDEBUG
+#include <w32k.h>
+
+#define NDEBUG
#include <debug.h>
-#define SCROLL_MIN_RECT 4 /* Minimum size of the rectangle between the arrows */
-#define SCROLL_ARROW_THUMB_OVERLAP 0 /* Overlap between arrows and thumb */
+#define MINTRACKTHUMB 8 /* Minimum size of the rectangle between the arrows */
#define SBRG_SCROLLBAR 0 /* the scrollbar itself */
#define SBRG_TOPRIGHTBTN 1 /* the top or right button */
#define SBRG_PAGEDOWNLEFT 4 /* the page down or page left region */
#define SBRG_BOTTOMLEFTBTN 5 /* the bottom or left button */
+#define CHANGERGSTATE(item, status) \
+ if(Info->rgstate[(item)] != (status)) \
+ Chg = TRUE; \
+ Info->rgstate[(item)] = (status);
/* FUNCTIONS *****************************************************************/
* 'thumbSize' returns the size of the thumb, and 'thumbPos' returns the position of the thumb relative to the left or to
* the top. Return TRUE if the scrollbar is vertical, FALSE if horizontal.
*/
-BOOL STDCALL
+BOOL FASTCALL
IntGetScrollBarRect (PWINDOW_OBJECT Window, INT nBar, PRECT lprect)
{
BOOL vertical;
lprect->left = ClientRect.left - WindowRect.left;
lprect->top = ClientRect.bottom - WindowRect.top;
lprect->right = ClientRect.right - WindowRect.left;
- lprect->bottom = lprect->top + NtUserGetSystemMetrics (SM_CYHSCROLL);
- if (Window->Style & WS_BORDER)
- {
- lprect->left--;
- lprect->right++;
- }
- else if (Window->Style & WS_VSCROLL)
- lprect->right++;
+ lprect->bottom = lprect->top + UserGetSystemMetrics (SM_CYHSCROLL);
vertical = FALSE;
break;
case SB_VERT:
- lprect->left = (ClientRect.right - WindowRect.left);
- lprect->top = (ClientRect.top - WindowRect.top) + 1;
- lprect->right = (lprect->left + NtUserGetSystemMetrics (SM_CXVSCROLL));
- lprect->bottom = (ClientRect.bottom - WindowRect.top) - 1;
- if (Window->Style & WS_BORDER)
- {
- lprect->top--;
- lprect->bottom++;
- }
- else if (Window->Style & WS_HSCROLL)
- lprect->bottom++;
+ if(Window->ExStyle & WS_EX_LEFTSCROLLBAR)
+ {
+ lprect->right = ClientRect.left - WindowRect.left;
+ lprect->left = lprect->right - UserGetSystemMetrics(SM_CXVSCROLL);
+ }
+ else
+ {
+ lprect->left = ClientRect.right - WindowRect.left;
+ lprect->right = lprect->left + UserGetSystemMetrics(SM_CXVSCROLL);
+ }
+ lprect->top = ClientRect.top - WindowRect.top;
+ lprect->bottom = ClientRect.bottom - WindowRect.top;
vertical = TRUE;
break;
break;
default:
- IntReleaseWindowObject(Window);
return FALSE;
}
return vertical;
}
-DWORD FASTCALL
-IntCreateScrollBar(PWINDOW_OBJECT Window, LONG idObject)
+BOOL FASTCALL
+IntCalculateThumb(PWINDOW_OBJECT Window, LONG idObject, PSCROLLBARINFO psbi, LPSCROLLINFO psi)
{
- PSCROLLBARINFO psbi;
- LRESULT Result;
- INT i;
-
- psbi = ExAllocatePool(PagedPool, sizeof(SCROLLBARINFO));
- if(!psbi)
- return FALSE;
-
- Result = WinPosGetNonClientSize(Window->Self,
- &Window->WindowRect,
- &Window->ClientRect);
-
- psbi->cbSize = sizeof(SCROLLBARINFO);
-
- for (i = 0; i < CCHILDREN_SCROLLBAR + 1; i++)
- psbi->rgstate[i] = 0;
+ INT Thumb, ThumbBox, ThumbPos, cxy, mx;
+ RECT ClientRect;
switch(idObject)
{
case SB_HORZ:
- Window->pHScroll = psbi;
+ Thumb = UserGetSystemMetrics(SM_CXHSCROLL);
+ cxy = psbi->rcScrollBar.right - psbi->rcScrollBar.left;
break;
case SB_VERT:
- Window->pVScroll = psbi;
+ Thumb = UserGetSystemMetrics(SM_CYVSCROLL);
+ cxy = psbi->rcScrollBar.bottom - psbi->rcScrollBar.top;
break;
case SB_CTL:
- Window->wExtra = psbi;
+ IntGetClientRect (Window, &ClientRect);
+ if(Window->Style & SBS_VERT)
+ {
+ Thumb = UserGetSystemMetrics(SM_CYVSCROLL);
+ cxy = ClientRect.bottom - ClientRect.top;
+ }
+ else
+ {
+ Thumb = UserGetSystemMetrics(SM_CXHSCROLL);
+ cxy = ClientRect.right - ClientRect.left;
+ }
break;
default:
- ExFreePool(psbi);
return FALSE;
}
- IntGetScrollBarRect (Window, idObject, &(psbi->rcScrollBar));
+ ThumbPos = Thumb;
+ /* calculate Thumb */
+ if(cxy <= (2 * Thumb))
+ {
+ Thumb = cxy / 2;
+ psbi->xyThumbTop = 0;
+ psbi->xyThumbBottom = 0;
+ ThumbPos = Thumb;
+ }
+ else
+ {
+ ThumbBox = psi->nPage ? MINTRACKTHUMB : UserGetSystemMetrics(SM_CXHTHUMB);
+ cxy -= (2 * Thumb);
+ if(cxy >= ThumbBox)
+ {
+ if(psi->nPage)
+ {
+ ThumbBox = max(EngMulDiv(cxy, psi->nPage, psi->nMax - psi->nMin + 1), ThumbBox);
+ }
+
+ if(cxy > ThumbBox)
+ {
+ mx = psi->nMax - max(psi->nPage - 1, 0);
+ if(psi->nMin < mx)
+ ThumbPos = Thumb + EngMulDiv(cxy - ThumbBox, psi->nPos - psi->nMin, mx - psi->nMin);
+ else
+ ThumbPos = Thumb + ThumbBox;
+ }
+
+ psbi->xyThumbTop = ThumbPos;
+ psbi->xyThumbBottom = ThumbPos + ThumbBox;
+ }
+ else
+ {
+ psbi->xyThumbTop = 0;
+ psbi->xyThumbBottom = 0;
+ }
+ }
+ psbi->dxyLineButton = Thumb;
- return 0;
+ return TRUE;
}
-BOOL FASTCALL
-IntDestroyScrollBar(PWINDOW_OBJECT Window, LONG idObject)
+static VOID FASTCALL
+IntUpdateSBInfo(PWINDOW_OBJECT Window, int wBar)
{
- switch(idObject)
+ PSCROLLBARINFO sbi;
+ LPSCROLLINFO psi;
+
+ ASSERT(Window);
+ ASSERT(Window->Scroll);
+
+ sbi = IntGetScrollbarInfoFromWindow(Window, wBar);
+ psi = IntGetScrollInfoFromWindow(Window, wBar);
+ IntGetScrollBarRect(Window, wBar, &(sbi->rcScrollBar));
+ IntCalculateThumb(Window, wBar, sbi, psi);
+}
+
+static BOOL FASTCALL
+co_IntGetScrollInfo(PWINDOW_OBJECT Window, INT nBar, LPSCROLLINFO lpsi)
+{
+ UINT Mask;
+ LPSCROLLINFO psi;
+
+ ASSERT_REFS(Window);
+
+ if(!SBID_IS_VALID(nBar))
{
- case SB_HORZ:
- if(Window->pHScroll)
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ DPRINT1("Trying to get scrollinfo for unknown scrollbar type %d\n", nBar);
+ return FALSE;
+ }
+
+ if(!co_IntCreateScrollBars(Window))
+ {
+ return FALSE;
+ }
+
+ psi = IntGetScrollInfoFromWindow(Window, nBar);
+
+ if (lpsi->fMask == SIF_ALL)
+ {
+ Mask = SIF_PAGE | SIF_POS | SIF_RANGE | SIF_TRACKPOS;
+ }
+ else
+ {
+ Mask = lpsi->fMask;
+ }
+
+ if (0 != (Mask & SIF_PAGE))
+ {
+ lpsi->nPage = psi->nPage;
+ }
+
+ if (0 != (Mask & SIF_POS))
+ {
+ lpsi->nPos = psi->nPos;
+ }
+
+ if (0 != (Mask & SIF_RANGE))
+ {
+ lpsi->nMin = psi->nMin;
+ lpsi->nMax = psi->nMax;
+ }
+
+ if (0 != (Mask & SIF_TRACKPOS))
+ {
+ lpsi->nTrackPos = psi->nTrackPos;
+ }
+
+ return TRUE;
+}
+
+static DWORD FASTCALL
+co_IntSetScrollInfo(PWINDOW_OBJECT Window, INT nBar, LPCSCROLLINFO lpsi, BOOL bRedraw)
+{
+ /*
+ * Update the scrollbar state and set action flags according to
+ * what has to be done graphics wise.
+ */
+
+ LPSCROLLINFO Info;
+ PSCROLLBARINFO psbi;
+/* UINT new_flags;*/
+ BOOL bChangeParams = FALSE; /* don't show/hide scrollbar if params don't change */
+
+ ASSERT_REFS(Window);
+
+ if(!SBID_IS_VALID(nBar))
+ {
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ DPRINT1("Trying to set scrollinfo for unknown scrollbar type %d", nBar);
+ return FALSE;
+ }
+
+ if(!co_IntCreateScrollBars(Window))
+ {
+ return FALSE;
+ }
+
+ if (lpsi->cbSize != sizeof(SCROLLINFO) &&
+ lpsi->cbSize != (sizeof(SCROLLINFO) - sizeof(lpsi->nTrackPos)))
+ {
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return 0;
+ }
+ if (lpsi->fMask & ~(SIF_ALL | SIF_DISABLENOSCROLL))
+ {
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return 0;
+ }
+
+ psbi = IntGetScrollbarInfoFromWindow(Window, nBar);
+ Info = IntGetScrollInfoFromWindow(Window, nBar);
+
+ /* Set the page size */
+ if (0 != (lpsi->fMask & SIF_PAGE))
+ {
+ if (Info->nPage != lpsi->nPage)
+ {
+ Info->nPage = lpsi->nPage;
+ bChangeParams = TRUE;
+ }
+ }
+
+ /* Set the scroll pos */
+ if (0 != (lpsi->fMask & SIF_POS))
+ {
+ if (Info->nPos != lpsi->nPos)
+ {
+ Info->nPos = lpsi->nPos;
+ }
+ }
+
+ /* Set the scroll range */
+ if (0 != (lpsi->fMask & SIF_RANGE))
+ {
+ /* Invalid range -> range is set to (0,0) */
+ if (lpsi->nMin > lpsi->nMax ||
+ 0x80000000 <= (UINT)(lpsi->nMax - lpsi->nMin))
+ {
+ Info->nMin = 0;
+ Info->nMax = 0;
+ bChangeParams = TRUE;
+ }
+ else if (Info->nMin != lpsi->nMin || Info->nMax != lpsi->nMax)
+ {
+ Info->nMin = lpsi->nMin;
+ Info->nMax = lpsi->nMax;
+ bChangeParams = TRUE;
+ }
+ }
+
+ /* Make sure the page size is valid */
+ if (Info->nPage < 0)
+ {
+ Info->nPage = 0;
+ }
+ else if (Info->nMax - Info->nMin + 1 < Info->nPage)
+ {
+ Info->nPage = Info->nMax - Info->nMin + 1;
+ }
+
+ /* Make sure the pos is inside the range */
+ if (Info->nPos < Info->nMin)
+ {
+ Info->nPos = Info->nMin;
+ }
+ else if (Info->nPos > Info->nMax - max(Info->nPage - 1, 0))
+ {
+ Info->nPos = Info->nMax - max(Info->nPage - 1, 0);
+ }
+
+ /*
+ * Don't change the scrollbar state if SetScrollInfo is just called
+ * with SIF_DISABLENOSCROLL
+ */
+ if (0 == (lpsi->fMask & SIF_ALL))
+ {
+ return Info->nPos;
+ }
+
+ /* Check if the scrollbar should be hidden or disabled */
+ if (0 != (lpsi->fMask & (SIF_RANGE | SIF_PAGE | SIF_DISABLENOSCROLL)))
+ {
+ 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;*/
+ }
+ else if ((nBar != SB_CTL) && bChangeParams)
+ {
+ co_UserShowScrollBar(Window, nBar, FALSE);
+ return Info->nPos;
+ }
+ }
+ else /* Show and enable scroll-bar */
+ {
+/* new_flags = 0;*/
+ 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)
+ {
+ RECT UpdateRect = psbi->rcScrollBar;
+ UpdateRect.left -= Window->ClientRect.left - Window->WindowRect.left;
+ UpdateRect.right -= Window->ClientRect.left - Window->WindowRect.left;
+ UpdateRect.top -= Window->ClientRect.top - Window->WindowRect.top;
+ UpdateRect.bottom -= Window->ClientRect.top - Window->WindowRect.top;
+ co_UserRedrawWindow(Window, &UpdateRect, 0, RDW_INVALIDATE | RDW_FRAME);
+ }
+
+ /* Return current position */
+ return Info->nPos;
+}
+
+BOOL FASTCALL
+co_IntGetScrollBarInfo(PWINDOW_OBJECT Window, LONG idObject, PSCROLLBARINFO psbi)
+{
+ INT Bar;
+ PSCROLLBARINFO sbi;
+ LPSCROLLINFO psi;
+
+ ASSERT_REFS(Window);
+
+ Bar = SBOBJ_TO_SBID(idObject);
+
+ if(!SBID_IS_VALID(Bar))
+ {
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ DPRINT1("Trying to get scrollinfo for unknown scrollbar type %d\n", Bar);
+ return FALSE;
+ }
+
+ if(!co_IntCreateScrollBars(Window))
+ {
+ return FALSE;
+ }
+
+ sbi = IntGetScrollbarInfoFromWindow(Window, Bar);
+ psi = IntGetScrollInfoFromWindow(Window, Bar);
+
+ IntGetScrollBarRect(Window, Bar, &(sbi->rcScrollBar));
+ IntCalculateThumb(Window, Bar, sbi, psi);
+
+ RtlCopyMemory(psbi, sbi, sizeof(SCROLLBARINFO));
+
+ return TRUE;
+}
+
+BOOL FASTCALL
+co_IntCreateScrollBars(PWINDOW_OBJECT Window)
+{
+ PSCROLLBARINFO psbi;
+ LPSCROLLINFO psi;
+ LRESULT Result;
+ ULONG Size, s;
+ INT i;
+
+ ASSERT_REFS(Window);
+
+ if(Window->Scroll)
+ {
+ /* no need to create it anymore */
+ return TRUE;
+ }
+
+ /* allocate memory for all scrollbars (HORZ, VERT, CONTROL) */
+ Size = 3 * (sizeof(WINDOW_SCROLLINFO));
+ if(!(Window->Scroll = ExAllocatePoolWithTag(PagedPool, Size, TAG_SBARINFO)))
+ {
+ DPRINT1("Unable to allocate memory for scrollbar information for window 0x%x\n", Window->hSelf);
+ return FALSE;
+ }
+
+ RtlZeroMemory(Window->Scroll, Size);
+
+ Result = co_WinPosGetNonClientSize(Window->hSelf,
+ &Window->WindowRect,
+ &Window->ClientRect);
+
+ for(s = SB_HORZ; s <= SB_VERT; s++)
+ {
+ psbi = IntGetScrollbarInfoFromWindow(Window, s);
+ psbi->cbSize = sizeof(SCROLLBARINFO);
+ for (i = 0; i < CCHILDREN_SCROLLBAR + 1; i++)
+ psbi->rgstate[i] = 0;
+
+ psi = IntGetScrollInfoFromWindow(Window, s);
+ psi->cbSize = sizeof(LPSCROLLINFO);
+ psi->nMax = 100;
+
+ IntGetScrollBarRect(Window, s, &(psbi->rcScrollBar));
+ IntCalculateThumb(Window, s, psbi, psi);
+ }
+
+ return TRUE;
+}
+
+BOOL FASTCALL
+IntDestroyScrollBars(PWINDOW_OBJECT Window)
+{
+ if(Window->Scroll)
+ {
+ ExFreePool(Window->Scroll);
+ Window->Scroll = NULL;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+BOOL STDCALL
+IntEnableScrollBar(BOOL Horz, PSCROLLBARINFO Info, UINT wArrows)
+{
+ BOOL Chg = FALSE;
+ switch(wArrows)
+ {
+ case ESB_DISABLE_BOTH:
+ CHANGERGSTATE(SBRG_TOPRIGHTBTN, STATE_SYSTEM_UNAVAILABLE);
+ CHANGERGSTATE(SBRG_BOTTOMLEFTBTN, STATE_SYSTEM_UNAVAILABLE);
+ break;
+ case ESB_DISABLE_RTDN:
+ if(Horz)
{
- ExFreePool(Window->pHScroll);
- Window->pHScroll = NULL;
- return TRUE;
+ CHANGERGSTATE(SBRG_BOTTOMLEFTBTN, STATE_SYSTEM_UNAVAILABLE);
}
- return FALSE;
- case SB_VERT:
- if(Window->pVScroll)
+ else
{
- ExFreePool(Window->pVScroll);
- Window->pVScroll = NULL;
- return TRUE;
+ CHANGERGSTATE(SBRG_TOPRIGHTBTN, STATE_SYSTEM_UNAVAILABLE);
}
- return FALSE;
- case SB_CTL:
- if(Window->wExtra)
+ break;
+ case ESB_DISABLE_LTUP:
+ if(Horz)
{
- ExFreePool(Window->wExtra);
- Window->wExtra = NULL;
- return TRUE;
+ CHANGERGSTATE(SBRG_TOPRIGHTBTN, STATE_SYSTEM_UNAVAILABLE);
}
- return FALSE;
+ else
+ {
+ CHANGERGSTATE(SBRG_BOTTOMLEFTBTN, STATE_SYSTEM_UNAVAILABLE);
+ }
+ break;
+ case ESB_ENABLE_BOTH:
+ CHANGERGSTATE(SBRG_TOPRIGHTBTN, 0);
+ CHANGERGSTATE(SBRG_BOTTOMLEFTBTN, 0);
+ break;
}
- return FALSE;
+ return Chg;
}
STDCALL
NtUserGetScrollBarInfo(HWND hWnd, LONG idObject, PSCROLLBARINFO psbi)
{
+ NTSTATUS Status;
+ SCROLLBARINFO sbi;
PWINDOW_OBJECT Window;
+ BOOL Ret;
+ DECLARE_RETURN(BOOL);
- if(!psbi || (psbi->cbSize != sizeof(SCROLLBARINFO)))
+ DPRINT("Enter NtUserGetScrollBarInfo\n");
+ UserEnterExclusive();
+
+ Status = MmCopyFromCaller(&sbi, psbi, sizeof(SCROLLBARINFO));
+ if(!NT_SUCCESS(Status) || (sbi.cbSize != sizeof(SCROLLBARINFO)))
{
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return FALSE;
+ SetLastNtError(Status);
+ RETURN(FALSE);
}
-
- Window = IntGetWindowObject(hWnd);
- if(!Window)
+ if(!(Window = UserGetWindowObject(hWnd)))
{
- SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
- return FALSE;
+ RETURN(FALSE);
}
- switch(idObject)
+ UserReferenceWindowObjectCo(Window);
+ Ret = co_IntGetScrollBarInfo(Window, idObject, &sbi);
+ UserDereferenceWindowObjectCo(Window);
+
+ Status = MmCopyToCaller(psbi, &sbi, sizeof(SCROLLBARINFO));
+ if(!NT_SUCCESS(Status))
{
- case SB_HORZ:
- if(Window->pHScroll)
- {
- memcpy(psbi, Window->pHScroll, sizeof(SCROLLBARINFO));
- break;
- }
- /* fall through */
- case SB_VERT:
- if(Window->pVScroll)
- {
- memcpy(psbi, Window->pVScroll, sizeof(SCROLLBARINFO));
- break;
- }
- /* fall through */
- case SB_CTL:
- if(Window->wExtra)
- {
- memcpy(psbi, Window->wExtra, sizeof(SCROLLBARINFO));
- break;
- }
- /* fall through */
- default:
- IntReleaseWindowObject(Window);
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return FALSE;
+ SetLastNtError(Status);
+ Ret = FALSE;
}
- IntGetScrollBarRect (Window, idObject, &(psbi->rcScrollBar));
-
- IntReleaseWindowObject(Window);
- return TRUE;
+ RETURN( Ret);
+
+CLEANUP:
+ DPRINT("Leave NtUserGetScrollBarInfo, ret=%i\n",_ret_);
+ UserLeave();
+ END_CLEANUP;
+
}
BOOL
STDCALL
-NtUserGetScrollInfo(HWND hwnd, int fnBar, LPSCROLLINFO lpsi)
+NtUserGetScrollInfo(HWND hWnd, int fnBar, LPSCROLLINFO lpsi)
{
+ NTSTATUS Status;
PWINDOW_OBJECT Window;
- PSCROLLBARINFO Info = NULL;
+ SCROLLINFO psi;
+ DWORD sz;
+ BOOL Ret;
+ DECLARE_RETURN(BOOL);
- Window = IntGetWindowObject(hwnd);
+ DPRINT("Enter NtUserGetScrollInfo\n");
+ UserEnterShared();
- if(!Window)
+ Status = MmCopyFromCaller(&psi.cbSize, &(lpsi->cbSize), sizeof(UINT));
+ if(!NT_SUCCESS(Status) ||
+ !((psi.cbSize == sizeof(SCROLLINFO)) || (psi.cbSize == sizeof(SCROLLINFO) - sizeof(psi.nTrackPos))))
{
- SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
- return FALSE;
+ SetLastNtError(Status);
+ RETURN(FALSE);
}
-
- switch(fnBar)
+ sz = psi.cbSize;
+ Status = MmCopyFromCaller(&psi, lpsi, sz);
+ if (!NT_SUCCESS(Status))
{
- case SB_HORZ:
- Info = Window->pHScroll;
- break;
- case SB_VERT:
- Info = Window->pVScroll;
- break;
- case SB_CTL:
- Info = Window->wExtra;
- break;
- default:
- IntReleaseWindowObject(Window);
- return FALSE;
+ SetLastNtError(Status);
+ RETURN(FALSE);
}
+
+ if(!(Window = UserGetWindowObject(hWnd)))
+ {
+ RETURN(FALSE);
+ }
+
+ UserReferenceWindowObjectCo(Window);
+ Ret = co_IntGetScrollInfo(Window, fnBar, &psi);
+ UserDereferenceWindowObjectCo(Window);
+
+ Status = MmCopyToCaller(lpsi, &psi, sz);
+ if(!NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ RETURN( FALSE);
+ }
+
+ RETURN( Ret);
- IntReleaseWindowObject(Window);
- return FALSE;
+CLEANUP:
+ DPRINT("Leave NtUserGetScrollInfo, ret=%i\n",_ret_);
+ UserLeave();
+ END_CLEANUP;
}
-DWORD
+BOOL
STDCALL
NtUserEnableScrollBar(
- HWND hWnd,
- UINT wSBflags,
+ HWND hWnd,
+ UINT wSBflags,
UINT wArrows)
{
- PWINDOW_OBJECT Window;
+ PWINDOW_OBJECT Window = NULL;
PSCROLLBARINFO InfoV = NULL, InfoH = NULL;
+ BOOL Chg = FALSE;
+ DECLARE_RETURN(BOOL);
- Window = IntGetWindowObject(hWnd);
+ DPRINT("Enter NtUserEnableScrollBar\n");
+ UserEnterExclusive();
- if(!Window)
+ if(!(Window = UserGetWindowObject(hWnd)))
{
- SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
- return FALSE;
+ RETURN(FALSE);
}
-
+ UserReferenceWindowObjectCo(Window);
+
+ if(wSBflags == SB_CTL)
+ {
+ /* FIXME Enable or Disable SB Ctrl*/
+ DPRINT1("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(TRUE);
+ }
+
+ if(wSBflags != SB_BOTH && !SBID_IS_VALID(wSBflags))
+ {
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ DPRINT1("Trying to set scrollinfo for unknown scrollbar type %d", wSBflags);
+ RETURN(FALSE);
+ }
+
+ if(!co_IntCreateScrollBars(Window))
+ {
+ RETURN( FALSE);
+ }
+
switch(wSBflags)
{
case SB_BOTH:
- InfoV = Window->pVScroll;
+ InfoV = IntGetScrollbarInfoFromWindow(Window, SB_VERT);
/* fall through */
case SB_HORZ:
- InfoH = Window->pHScroll;
+ InfoH = IntGetScrollbarInfoFromWindow(Window, SB_HORZ);
break;
case SB_VERT:
- InfoV = Window->pVScroll;
- break;
- case SB_CTL:
- InfoV = Window->wExtra;
+ InfoV = IntGetScrollbarInfoFromWindow(Window, SB_VERT);
break;
default:
- IntReleaseWindowObject(Window);
- return FALSE;
+ RETURN(FALSE);
}
+
+ if(InfoV)
+ Chg = IntEnableScrollBar(FALSE, InfoV, wArrows);
+
+ if(InfoH)
+ Chg = (IntEnableScrollBar(TRUE, InfoH, wArrows) || Chg);
+
+ //if(Chg && (Window->Style & WS_VISIBLE))
+ /* FIXME - repaint scrollbars */
+
+ RETURN( TRUE);
- IntReleaseWindowObject(Window);
- return TRUE;
+CLEANUP:
+ if (Window) UserDereferenceWindowObjectCo(Window);
+
+ DPRINT("Leave NtUserEnableScrollBar, ret=%i\n",_ret_);
+ UserLeave();
+ END_CLEANUP;
}
-DWORD
+BOOL
STDCALL
-NtUserScrollDC(
- HDC hDC,
- int dx,
- int dy,
- CONST RECT *lprcScroll,
- CONST RECT *lprcClip ,
- HRGN hrgnUpdate,
- LPRECT lprcUpdate)
-
+NtUserSetScrollBarInfo(
+ HWND hWnd,
+ LONG idObject,
+ SETSCROLLBARINFO *info)
{
- UNIMPLEMENTED
+ PWINDOW_OBJECT Window = NULL;
+ SETSCROLLBARINFO Safeinfo;
+ PSCROLLBARINFO sbi;
+ LPSCROLLINFO psi;
+ NTSTATUS Status;
+ LONG Obj;
+ DECLARE_RETURN(BOOL);
+
+ DPRINT("Enter NtUserSetScrollBarInfo\n");
+ UserEnterExclusive();
+
+ if(!(Window = UserGetWindowObject(hWnd)))
+ {
+ RETURN( FALSE);
+ }
+ UserReferenceWindowObjectCo(Window);
+
+ Obj = SBOBJ_TO_SBID(idObject);
+ if(!SBID_IS_VALID(Obj))
+ {
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ DPRINT1("Trying to set scrollinfo for unknown scrollbar type %d", Obj);
+ RETURN( FALSE);
+ }
+
+ if(!co_IntCreateScrollBars(Window))
+ {
+ RETURN(FALSE);
+ }
+
+ Status = MmCopyFromCaller(&Safeinfo, info, sizeof(SETSCROLLBARINFO));
+ if(!NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ RETURN(FALSE);
+ }
- return 0;
+ sbi = IntGetScrollbarInfoFromWindow(Window, Obj);
+ psi = IntGetScrollInfoFromWindow(Window, Obj);
+
+ psi->nTrackPos = Safeinfo.nTrackPos;
+ sbi->reserved = Safeinfo.reserved;
+ RtlCopyMemory(&sbi->rgstate, &Safeinfo.rgstate, sizeof(Safeinfo.rgstate));
+
+ RETURN(TRUE);
+
+CLEANUP:
+ if (Window) UserDereferenceWindowObjectCo(Window);
+
+ DPRINT("Leave NtUserSetScrollBarInfo, ret=%i\n",_ret_);
+ UserLeave();
+ END_CLEANUP;
}
DWORD
STDCALL
NtUserSetScrollInfo(
- HWND hwnd,
- int fnBar,
- LPCSCROLLINFO lpsi,
- WINBOOL fRedraw)
+ HWND hWnd,
+ int fnBar,
+ LPCSCROLLINFO lpsi,
+ BOOL bRedraw)
{
- PWINDOW_OBJECT Window;
- PSCROLLBARINFO Info = NULL;
+ PWINDOW_OBJECT Window = NULL;
+ NTSTATUS Status;
+ SCROLLINFO ScrollInfo;
+ DECLARE_RETURN(DWORD);
- Window = IntGetWindowObject(hwnd);
+ DPRINT("Enter NtUserSetScrollInfo\n");
+ UserEnterExclusive();
- if(!Window)
+ if(!(Window = UserGetWindowObject(hWnd)))
{
- SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
- return 0;
+ RETURN( 0);
}
-
- switch(fnBar)
+ UserReferenceWindowObjectCo(Window);
+
+ Status = MmCopyFromCaller(&ScrollInfo, lpsi, sizeof(SCROLLINFO) - sizeof(ScrollInfo.nTrackPos));
+ if(!NT_SUCCESS(Status))
{
- case SB_HORZ:
- Info = Window->pHScroll;
- break;
- case SB_VERT:
- Info = Window->pVScroll;
- break;
- case SB_CTL:
- Info = Window->wExtra;
- break;
- default:
- IntReleaseWindowObject(Window);
- return 0;
+ SetLastNtError(Status);
+ RETURN( 0);
}
+
+ RETURN(co_IntSetScrollInfo(Window, fnBar, &ScrollInfo, bRedraw));
+
+CLEANUP:
+ if (Window) UserDereferenceWindowObjectCo(Window);
+
+ DPRINT("Leave NtUserSetScrollInfo, ret=%i\n",_ret_);
+ UserLeave();
+ END_CLEANUP;
- IntReleaseWindowObject(Window);
- return 0;
}
/* Ported from WINE20020904 (SCROLL_ShowScrollBar) */
-DWORD
-STDCALL
-NtUserShowScrollBar(HWND hWnd, int wBar, DWORD bShow)
+DWORD FASTCALL
+co_UserShowScrollBar(PWINDOW_OBJECT Window, int wBar, DWORD bShow)
{
- BOOL fShowV = (wBar == SB_VERT) ? 0 : bShow;
- BOOL fShowH = (wBar == SB_HORZ) ? 0 : bShow;
- PWINDOW_OBJECT Window = IntGetWindowObject(hWnd);
- if(!Window)
- {
- SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
- return FALSE;
- }
-
- switch (wBar)
+ DWORD Style, OldStyle;
+
+ ASSERT_REFS(Window);
+
+ 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:
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return( FALSE);
+ }
+
+ if(!co_IntCreateScrollBars(Window))
{
- case SB_CTL:
- WinPosShowWindow (hWnd, fShowH ? SW_SHOW : SW_HIDE);
- return TRUE;
+ return( FALSE);
+ }
- case SB_BOTH:
- case SB_HORZ:
- if (fShowH)
- {
- fShowH = !(Window->Style & WS_HSCROLL);
- Window->Style |= WS_HSCROLL;
- }
- else /* hide it */
- {
- fShowH = (Window->Style & WS_HSCROLL);
- Window->Style &= ~WS_HSCROLL;
- }
- if (wBar == SB_HORZ)
- {
- fShowV = FALSE;
- break;
- }
- /* fall through */
+ if (wBar == SB_CTL)
+ {
+ IntUpdateSBInfo(Window, SB_CTL);
+
+ co_WinPosShowWindow(Window->hSelf, bShow ? SW_SHOW : SW_HIDE);
+ return( TRUE);
+ }
+
+ OldStyle = Window->Style;
+ if(bShow)
+ Window->Style |= Style;
+ else
+ Window->Style &= ~Style;
+
+ if(Window->Style != OldStyle)
+ {
+ if(Window->Style & WS_HSCROLL)
+ IntUpdateSBInfo(Window, SB_HORZ);
+ if(Window->Style & WS_VSCROLL)
+ IntUpdateSBInfo(Window, SB_VERT);
+
+ if(Window->Style & WS_VISIBLE)
+ {
+ /* Frame has been changed, let the window redraw itself */
+ co_WinPosSetWindowPos(Window->hSelf, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
+ SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOSENDCHANGING);
+ }
+ }
+
+ return( TRUE);
+}
- case SB_VERT:
- if (fShowV)
- {
- fShowV = !(Window->Style & WS_VSCROLL);
- Window->Style |= WS_VSCROLL;
- }
- else /* hide it */
- {
- fShowV = (Window->Style & WS_VSCROLL);
- Window->Style &= ~WS_VSCROLL;
- }
- if (wBar == SB_VERT)
- fShowH = FALSE;
- break;
- default:
- return FALSE; /* Nothing to do! */
- }
+DWORD STDCALL
+NtUserShowScrollBar(HWND hWnd, int wBar, DWORD bShow)
+{
+ PWINDOW_OBJECT Window;
+ DECLARE_RETURN(DWORD);
+ DWORD ret;
+
+ DPRINT("Enter NtUserShowScrollBar\n");
+ UserEnterExclusive();
+
+ if (!(Window = UserGetWindowObject(hWnd)))
+ {
+ RETURN(0);
+ }
+
+ UserReferenceWindowObjectCo(Window);
+ ret = co_UserShowScrollBar(Window, wBar, bShow);
+ UserDereferenceWindowObjectCo(Window);
+
+ RETURN(ret);
+
+CLEANUP:
+ DPRINT("Leave NtUserShowScrollBar, ret%i\n",_ret_);
+ UserLeave();
+ END_CLEANUP;
- if (fShowH || fShowV) /* frame has been changed, let the window redraw itself */
- {
- WinPosSetWindowPos (hWnd, 0, 0, 0, 0, 0,
- SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED);
- return TRUE;
- }
- return FALSE; /* no frame changes */
}
-
/* EOF */