X-Git-Url: http://git.jankratochvil.net/?a=blobdiff_plain;f=lib%2Fuser32%2Fcontrols%2Fscrollbar.c;h=935871a3ba54e6378ca344e3585fed8cc4f986b6;hb=HEAD;hp=393c56ccf6895fc804a627861865a9549028148c;hpb=e3ed2d773259cc445c7ff8181ebd934931365328;p=reactos.git diff --git a/lib/user32/controls/scrollbar.c b/lib/user32/controls/scrollbar.c index 393c56c..935871a 100644 --- a/lib/user32/controls/scrollbar.c +++ b/lib/user32/controls/scrollbar.c @@ -5,16 +5,18 @@ * PURPOSE: Windows * FILE: subsys/win32k/ntuser/window.c * PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net) + * Thomas Weidenmueller (w3seek@users.sourceforge.net) * REVISION HISTORY: * 06-06-2001 CSH Created */ /* INCLUDES ******************************************************************/ -/* INCLUDES ******************************************************************/ - #include #include #include +#include +#include +#include /* GLOBAL VARIABLES **********************************************************/ /* @@ -40,7 +42,6 @@ static HBITMAP hRgArrowI; #define RIGHT_ARROW(flags,pressed) \ (((flags)&ESB_DISABLE_RIGHT) ? hRgArrowI : ((pressed) ? hRgArrowD:hRgArrow)) -#define SCROLL_ARROW_THUMB_OVERLAP 0 /* Overlap between arrows and thumb */ #define SCROLL_MIN_THUMB 6 /* Minimum size of the thumb in pixels */ #define SCROLL_FIRST_DELAY 200 /* Delay (in ms) before first repetition when holding the button down */ #define SCROLL_REPEAT_DELAY 50 /* Delay (in ms) between scroll repetitions */ @@ -52,16 +53,13 @@ static HBITMAP hRgArrowI; #define SA_SSI_REFRESH 0x0004 #define SA_SSI_REPAINT_ARROWS 0x0008 - /* Scroll-bar hit testing */ -enum SCROLL_HITTEST -{ - SCROLL_NOWHERE, /* Outside the scroll bar */ - SCROLL_TOP_ARROW, /* Top or left arrow */ - SCROLL_TOP_RECT, /* Rectangle between the top arrow and the thumb */ - SCROLL_THUMB, /* Thumb rectangle */ - SCROLL_BOTTOM_RECT, /* Rectangle between the thumb and the bottom arrow */ - SCROLL_BOTTOM_ARROW /* Bottom or right arrow */ -}; +/* Scroll-bar hit testing */ +#define SCROLL_NOWHERE 0x00 /* Outside the scroll bar */ +#define SCROLL_TOP_ARROW 0x01 /* Top or left arrow */ +#define SCROLL_TOP_RECT 0x02 /* Rectangle between the top arrow and the thumb */ +#define SCROLL_THUMB 0x03 /* Thumb rectangle */ +#define SCROLL_BOTTOM_RECT 0x04 /* Rectangle between the thumb and the bottom arrow */ +#define SCROLL_BOTTOM_ARROW 0x05 /* Bottom or right arrow */ static BOOL SCROLL_MovingThumb = FALSE; /* Is the moving thumb being displayed? */ @@ -70,39 +68,30 @@ static HWND SCROLL_TrackingWin = 0; static INT SCROLL_TrackingBar = 0; static INT SCROLL_TrackingPos = 0; /* static INT SCROLL_TrackingVal = 0; */ -static enum SCROLL_HITTEST SCROLL_trackHitTest; /* Hit test code of the last button-down event */ +static DWORD SCROLL_trackHitTest; /* Hit test code of the last button-down event */ static BOOL SCROLL_trackVertical; -/* FUNCTIONS *****************************************************************/ +/* INTERNAL FUNCTIONS *********************************************************/ HBRUSH DefWndControlColor (HDC hDC, UINT ctlType); -HPEN STDCALL GetSysColorPen (int nIndex); - - - -WINBOOL STDCALL -GetScrollBarInfo (HWND hwnd, LONG idObject, PSCROLLBARINFO psbi) -{ - int ret = NtUserGetScrollBarInfo (hwnd, idObject, psbi); - - return ret; -} /* Ported from WINE20020904 */ /* Draw the scroll bar interior (everything except the arrows). */ static void -SCROLL_DrawInterior (HWND hwnd, HDC hdc, INT nBar, INT arrowSize, PSCROLLBARINFO psbi) +SCROLL_DrawInterior (HWND hwnd, HDC hdc, INT nBar, BOOL vertical, INT +arrowSize, PSCROLLBARINFO psbi) { INT thumbSize = psbi->xyThumbBottom - psbi->xyThumbTop; + RECT rc; HPEN hSavePen; HBRUSH hSaveBrush, hBrush; BOOLEAN top_selected = FALSE, bottom_selected = FALSE; DbgPrint("[SCROLL_DrawInterior:%d]\n", nBar); - if(psbi->rgstate[2] & STATE_SYSTEM_PRESSED) + if(psbi->rgstate[SCROLL_TOP_RECT] & STATE_SYSTEM_PRESSED) { top_selected = TRUE; } - if(psbi->rgstate[4] & STATE_SYSTEM_PRESSED) + if(psbi->rgstate[SCROLL_BOTTOM_RECT] & STATE_SYSTEM_PRESSED) { bottom_selected = TRUE; } @@ -111,85 +100,93 @@ DbgPrint("[SCROLL_DrawInterior:%d]\n", nBar); * The window-owned scrollbars need to call DefWndControlColor * to correctly setup default scrollbar colors */ - if (nBar == SB_CTL) - { - hBrush = (HBRUSH) NtUserSendMessage (GetParent (hwnd), WM_CTLCOLORSCROLLBAR, - (WPARAM) hdc, (LPARAM) hwnd); - } - else - { -/* hBrush = NtUserGetControlColor (hdc, CTLCOLOR_SCROLLBAR); FIXME */ /* DefWndControlColor */ + if ( nBar == SB_CTL ) + { + hBrush = (HBRUSH) NtUserSendMessage (GetParent (hwnd), WM_CTLCOLORSCROLLBAR, (WPARAM) hdc, (LPARAM) hwnd); + if(!hBrush) hBrush = GetSysColorBrush(COLOR_SCROLLBAR); - } + } + else + { +/* hBrush = NtUserGetControlColor (hdc, CTLCOLOR_SCROLLBAR); FIXME +*/ /* DefWndControlColor */ + hBrush = GetSysColorBrush(COLOR_SCROLLBAR); + } hSavePen = SelectObject (hdc, GetSysColorPen (COLOR_WINDOWFRAME)); hSaveBrush = SelectObject (hdc, hBrush); /* Calculate the scroll rectangle */ - if (nBar == SB_VERT) - { - psbi->rcScrollBar.top += arrowSize - SCROLL_ARROW_THUMB_OVERLAP; - psbi->rcScrollBar.bottom -= (arrowSize - SCROLL_ARROW_THUMB_OVERLAP); - } - else if (nBar == SB_HORZ) - { - psbi->rcScrollBar.left += arrowSize - SCROLL_ARROW_THUMB_OVERLAP; - psbi->rcScrollBar.right -= (arrowSize - SCROLL_ARROW_THUMB_OVERLAP); - } + if (vertical) + { + rc.top = psbi->rcScrollBar.top + arrowSize; + rc.bottom = psbi->rcScrollBar.bottom - arrowSize; + rc.left = psbi->rcScrollBar.left; + rc.right = psbi->rcScrollBar.right; + } + else + { + rc.top = psbi->rcScrollBar.top; + rc.bottom = psbi->rcScrollBar.bottom; + rc.left = psbi->rcScrollBar.left + arrowSize; + rc.right = psbi->rcScrollBar.right - arrowSize; + } /* Draw the scroll rectangles and thumb */ - if (!psbi->dxyLineButton) /* No thumb to draw */ - { - PatBlt (hdc, - psbi->rcScrollBar.left, - psbi->rcScrollBar.top, - psbi->rcScrollBar.right - psbi->rcScrollBar.left, - psbi->rcScrollBar.bottom - psbi->rcScrollBar.top, - PATCOPY); - - /* cleanup and return */ - SelectObject (hdc, hSavePen); - SelectObject (hdc, hSaveBrush); - return; - } + if (!psbi->xyThumbBottom) /* No thumb to draw */ + { + PatBlt (hdc, + rc.left, + rc.top, + rc.right - rc.left, + rc.bottom - rc.top, + PATCOPY); + + /* cleanup and return */ + SelectObject (hdc, hSavePen); + SelectObject (hdc, hSaveBrush); + return; + } + + psbi->xyThumbTop -= arrowSize; - if (nBar == SB_VERT) - { - PatBlt (hdc, - psbi->rcScrollBar.left, - psbi->rcScrollBar.top, - psbi->rcScrollBar.right - psbi->rcScrollBar.left, - psbi->dxyLineButton - (arrowSize - SCROLL_ARROW_THUMB_OVERLAP), - top_selected ? 0x0f0000 : PATCOPY); - psbi->rcScrollBar.top += psbi->dxyLineButton - (arrowSize - SCROLL_ARROW_THUMB_OVERLAP); - PatBlt (hdc, - psbi->rcScrollBar.left, - psbi->rcScrollBar.top + thumbSize, - psbi->rcScrollBar.right - psbi->rcScrollBar.left, - psbi->rcScrollBar.bottom - psbi->rcScrollBar.top - thumbSize, - bottom_selected ? 0x0f0000 : PATCOPY); - psbi->rcScrollBar.bottom = psbi->rcScrollBar.top + thumbSize; - } - else if (nBar == SB_HORZ) - { - PatBlt (hdc, - psbi->rcScrollBar.left, - psbi->rcScrollBar.top, - psbi->dxyLineButton - (arrowSize - SCROLL_ARROW_THUMB_OVERLAP), - psbi->rcScrollBar.bottom - psbi->rcScrollBar.top, - top_selected ? 0x0f0000 : PATCOPY); - psbi->rcScrollBar.left += psbi->dxyLineButton - (arrowSize - SCROLL_ARROW_THUMB_OVERLAP); - PatBlt (hdc, - psbi->rcScrollBar.left + thumbSize, - psbi->rcScrollBar.top, - psbi->rcScrollBar.right - psbi->rcScrollBar.left - thumbSize, - psbi->rcScrollBar.bottom - psbi->rcScrollBar.top, - bottom_selected ? 0x0f0000 : PATCOPY); - psbi->rcScrollBar.right = psbi->rcScrollBar.left + thumbSize; - } + if (vertical) + { + PatBlt (hdc, + rc.left, + rc.top, + rc.right - rc.left, + psbi->dxyLineButton, + top_selected ? 0x0f0000 : PATCOPY); + rc.top += psbi->xyThumbTop; + PatBlt (hdc, + rc.left, + rc.top + thumbSize, + rc.right - rc.left, + rc.bottom - rc.top - thumbSize, + bottom_selected ? 0x0f0000 : PATCOPY); + rc.bottom = rc.top + thumbSize; + } + else + { + PatBlt (hdc, + rc.left, + rc.top, + psbi->xyThumbTop, + rc.bottom - rc.top, + top_selected ? 0x0f0000 : PATCOPY); + rc.left += psbi->xyThumbTop; + PatBlt (hdc, + rc.left + thumbSize, + rc.top, + rc.right - rc.left - thumbSize, + rc.bottom - rc.top, + bottom_selected ? 0x0f0000 : PATCOPY); + rc.right = rc.left + thumbSize; + } /* Draw the thumb */ - DrawEdge (hdc, &psbi->rcScrollBar, EDGE_RAISED, BF_RECT | BF_MIDDLE); + DrawEdge (hdc, &rc, EDGE_RAISED, BF_RECT | BF_MIDDLE); /* cleanup */ SelectObject (hdc, hSavePen); @@ -198,24 +195,24 @@ DbgPrint("[SCROLL_DrawInterior:%d]\n", nBar); /* Ported from WINE20020904 */ static void -SCROLL_DrawMovingThumb (HDC hdc, RECT * rect, int nBar, int arrowSize, int thumbSize, PSCROLLBARINFO psbi) +SCROLL_DrawMovingThumb (HDC hdc, RECT * rect, BOOL vertical, int arrowSize, int thumbSize, PSCROLLBARINFO psbi) { INT pos = SCROLL_TrackingPos; INT max_size; - if (nBar == SB_VERT) + if ( vertical ) max_size = psbi->rcScrollBar.bottom - psbi->rcScrollBar.top; - else if (nBar == SB_HORZ) + else max_size = psbi->rcScrollBar.right - psbi->rcScrollBar.left; - max_size -= (arrowSize - SCROLL_ARROW_THUMB_OVERLAP) + thumbSize; + max_size -= arrowSize + thumbSize; - if (pos < (arrowSize - SCROLL_ARROW_THUMB_OVERLAP)) - pos = (arrowSize - SCROLL_ARROW_THUMB_OVERLAP); + if (pos < arrowSize) + pos = arrowSize; else if (pos > max_size) pos = max_size; - SCROLL_DrawInterior (SCROLL_TrackingWin, hdc, SCROLL_TrackingBar, arrowSize, psbi); + SCROLL_DrawInterior (SCROLL_TrackingWin, hdc, SCROLL_TrackingBar, vertical, arrowSize, psbi); SCROLL_MovingThumb = !SCROLL_MovingThumb; } @@ -224,41 +221,35 @@ SCROLL_DrawMovingThumb (HDC hdc, RECT * rect, int nBar, int arrowSize, int thumb /* Draw the scroll bar arrows. */ static void SCROLL_DrawArrows (HDC hdc, PSCROLLBARINFO info, - RECT * rect, INT arrowSize, int nBar, - BOOL top_pressed, BOOL bottom_pressed) + RECT * rect, INT arrowSize, BOOL vertical, + BOOL top_pressed, BOOL bottom_pressed) { - RECT r; + RECT r1, r2; int scrollDirFlag1, scrollDirFlag2; - if (nBar == SB_VERT) + r1 = r2 = *rect; + if (vertical) { scrollDirFlag1 = DFCS_SCROLLUP; scrollDirFlag2 = DFCS_SCROLLDOWN; + r1.bottom = r1.top + arrowSize; + r2.top = r2.bottom - arrowSize; } - else if (nBar == SB_HORZ) + else { scrollDirFlag1 = DFCS_SCROLLLEFT; scrollDirFlag2 = DFCS_SCROLLRIGHT; + r1.right = r1.left + arrowSize; + r2.left = r2.right - arrowSize; } - r = *rect; - if (nBar == SB_VERT) - r.bottom = r.top + arrowSize; - else if (nBar == SB_HORZ) - r.right = r.left + arrowSize; - - DrawFrameControl (hdc, &r, DFC_SCROLL, - scrollDirFlag1 | (top_pressed ? (DFCS_PUSHED | DFCS_FLAT) : 0) - /* | (info.flags&ESB_DISABLE_LTUP ? DFCS_INACTIVE : 0) */ + DrawFrameControl (hdc, &r1, DFC_SCROLL, + scrollDirFlag1 | (top_pressed ? (DFCS_PUSHED | DFCS_FLAT) : 0) + /* | (info.flags&ESB_DISABLE_LTUP ? DFCS_INACTIVE : 0) */ ); - r = *rect; - if (nBar == SB_VERT) - r.top = r.bottom - arrowSize; - else if (nBar == SB_HORZ) - r.left = r.right - arrowSize; - DrawFrameControl (hdc, &r, DFC_SCROLL, - scrollDirFlag2 | (bottom_pressed ? (DFCS_PUSHED | DFCS_FLAT) : 0) - /* | (info.flags&ESB_DISABLE_RTDN ? DFCS_INACTIVE : 0) */ + DrawFrameControl (hdc, &r2, DFC_SCROLL, + scrollDirFlag2 | (bottom_pressed ? (DFCS_PUSHED | DFCS_FLAT) : 0) + /* | (info.flags&ESB_DISABLE_RTDN ? DFCS_INACTIVE : 0) */ ); } @@ -266,32 +257,49 @@ SCROLL_DrawArrows (HDC hdc, PSCROLLBARINFO info, /* Redraw the whole scrollbar. */ void SCROLL_DrawScrollBar (HWND hwnd, HDC hdc, INT nBar, - BOOL arrows, BOOL interior) + BOOL arrows, BOOL interior) { INT arrowSize = 0; INT thumbSize; SCROLLBARINFO info; BOOL Save_SCROLL_MovingThumb = SCROLL_MovingThumb; + BOOL vertical; info.cbSize = sizeof(SCROLLBARINFO); - GetScrollBarInfo (hwnd, nBar, &info); + switch ( nBar ) + { + case SB_HORZ: + vertical = FALSE; + NtUserGetScrollBarInfo (hwnd, OBJID_HSCROLL, &info); + break; + case SB_VERT: + vertical = TRUE; + NtUserGetScrollBarInfo (hwnd, OBJID_VSCROLL, &info); + break; + case SB_CTL: + vertical = (GetWindowLongW(hwnd,GWL_STYLE)&SBS_VERT) != 0; + NtUserGetScrollBarInfo (hwnd, OBJID_CLIENT, &info); + break; +#ifdef DBG + default: + DASSERT(!"SCROLL_DrawScrollBar() called with invalid nBar"); + break; +#endif /* DBG */ + } + thumbSize = info.xyThumbBottom - info.xyThumbTop; - if (nBar == SB_HORZ) - { - arrowSize = GetSystemMetrics(SM_CYHSCROLL); - } else - if (nBar == SB_VERT) - { + if (vertical) arrowSize = GetSystemMetrics(SM_CXVSCROLL); - } + else + arrowSize = GetSystemMetrics(SM_CYHSCROLL); if (IsRectEmpty (&(info.rcScrollBar))) goto END; if (Save_SCROLL_MovingThumb && (SCROLL_TrackingWin == hwnd) && (SCROLL_TrackingBar == nBar)) { - SCROLL_DrawMovingThumb (hdc, &(info.rcScrollBar), nBar, arrowSize, thumbSize, &info); + SCROLL_DrawMovingThumb (hdc, &(info.rcScrollBar), vertical, arrowSize, thumbSize, &info); } /* Draw the arrows */ @@ -299,88 +307,297 @@ SCROLL_DrawScrollBar (HWND hwnd, HDC hdc, INT nBar, { if (SCROLL_trackVertical == TRUE /* && GetCapture () == hwnd */) { - SCROLL_DrawArrows (hdc, &info, &(info.rcScrollBar), arrowSize, nBar, + SCROLL_DrawArrows (hdc, &info, &(info.rcScrollBar), arrowSize, vertical, (SCROLL_trackHitTest == SCROLL_TOP_ARROW), (SCROLL_trackHitTest == SCROLL_BOTTOM_ARROW)); } else { - SCROLL_DrawArrows (hdc, &info, &(info.rcScrollBar), arrowSize, nBar, FALSE, FALSE); + SCROLL_DrawArrows (hdc, &info, &(info.rcScrollBar), arrowSize, vertical, FALSE, FALSE); } } if (interior) { - SCROLL_DrawInterior (hwnd, hdc, nBar, arrowSize, &info); + SCROLL_DrawInterior (hwnd, hdc, nBar, vertical, arrowSize, &info); } if (Save_SCROLL_MovingThumb && (SCROLL_TrackingWin == hwnd) && (SCROLL_TrackingBar == nBar)) - SCROLL_DrawMovingThumb (hdc, &info.rcScrollBar, nBar, arrowSize, thumbSize, &info); + SCROLL_DrawMovingThumb (hdc, &info.rcScrollBar, vertical, arrowSize, thumbSize, &info); /* if scroll bar has focus, reposition the caret */ /* if (hwnd == GetFocus () && (nBar == SB_CTL)) { if (nBar == SB_HORZ) - { - SetCaretPos (info.dxyLineButton + 1, info.rcScrollBar.top + 1); - } + { + SetCaretPos (info.dxyLineButton + 1, info.rcScrollBar.top + 1); + } else if (nBAR == SB_VERT) - { - SetCaretPos (info.rcScrollBar.top + 1, info.dxyLineButton + 1); - } + { + SetCaretPos (info.rcScrollBar.top + 1, info.dxyLineButton + 1); + } } */ END:; /* WIN_ReleaseWndPtr(wndPtr); */ } +static BOOL +SCROLL_PtInRectEx( LPRECT lpRect, POINT pt, BOOL vertical ) +{ + RECT rect = *lpRect; + + if (vertical) + { + rect.left -= lpRect->right - lpRect->left; + rect.right += lpRect->right - lpRect->left; + } + else + { + rect.top -= lpRect->bottom - lpRect->top; + rect.bottom += lpRect->bottom - lpRect->top; + } + return PtInRect( &rect, pt ); +} + +DWORD +SCROLL_HitTest( HWND hwnd, INT nBar, POINT pt, BOOL bDragging ) +{ + SCROLLBARINFO sbi; + RECT wndrect; + INT arrowSize, thumbSize, thumbPos; + BOOL vertical = (nBar == SB_VERT); /* FIXME - ((Window->Style & SBS_VERT) != 0) */ + + NtUserGetWindowRect(hwnd, &wndrect); + + sbi.cbSize = sizeof(SCROLLBARINFO); + NtUserGetScrollBarInfo(hwnd, vertical ? OBJID_VSCROLL : OBJID_HSCROLL, &sbi); + + OffsetRect(&sbi.rcScrollBar, wndrect.left, wndrect.top); + + if ( (bDragging && !SCROLL_PtInRectEx( &sbi.rcScrollBar, pt, vertical )) || + (!PtInRect( &sbi.rcScrollBar, pt )) ) return SCROLL_NOWHERE; + + thumbPos = sbi.xyThumbTop; + thumbSize = sbi.xyThumbBottom - thumbPos; + arrowSize = sbi.dxyLineButton; + + if (vertical) + { + if (pt.y < sbi.rcScrollBar.top + arrowSize) return SCROLL_TOP_ARROW; + if (pt.y >= sbi.rcScrollBar.bottom - arrowSize) return SCROLL_BOTTOM_ARROW; + if (!thumbPos) return SCROLL_TOP_RECT; + pt.y -= sbi.rcScrollBar.top; + if (pt.y < thumbPos) return SCROLL_TOP_RECT; + if (pt.y >= thumbPos + thumbSize) return SCROLL_BOTTOM_RECT; + } + else /* horizontal */ + { + if (pt.x < sbi.rcScrollBar.left + arrowSize) return SCROLL_TOP_ARROW; + if (pt.x >= sbi.rcScrollBar.right - arrowSize) return SCROLL_BOTTOM_ARROW; + if (!thumbPos) return SCROLL_TOP_RECT; + pt.x -= sbi.rcScrollBar.left; + if (pt.x < thumbPos) return SCROLL_TOP_RECT; + if (pt.x >= thumbPos + thumbSize) return SCROLL_BOTTOM_RECT; + } + return SCROLL_THUMB; +} + + +/* FUNCTIONS ******************************************************************/ + + +/* + * @implemented + */ +WINBOOL STDCALL +EnableScrollBar(HWND hWnd, UINT wSBflags, UINT wArrows) +{ + return NtUserEnableScrollBar(hWnd, wSBflags, wArrows); +} + + +/* + * @implemented + */ +WINBOOL STDCALL +GetScrollBarInfo(HWND hwnd, LONG idObject, PSCROLLBARINFO psbi) +{ + SCROLLBARINFO sbi; + WINBOOL ret; + + if(!psbi) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + RtlCopyMemory(&sbi, psbi, sizeof(SCROLLBARINFO)); + ret = NtUserGetScrollBarInfo (hwnd, idObject, psbi); + if(ret) + { + RtlCopyMemory(psbi, &sbi, sizeof(SCROLLBARINFO)); + } + + return ret; +} + + +/* + * @implemented + */ WINBOOL STDCALL GetScrollInfo (HWND hwnd, int fnBar, LPSCROLLINFO lpsi) { - UNIMPLEMENTED; - return FALSE; + WINBOOL res; + SCROLLINFO si; + + if(!lpsi || + ((lpsi->cbSize != sizeof(SCROLLINFO)) && (lpsi->cbSize != sizeof(SCROLLINFO) - sizeof(si.nTrackPos)))) + { + SetLastError(ERROR_INVALID_PARAMETER); + return 0; + } + + RtlZeroMemory(&si, sizeof(SCROLLINFO)); + si.cbSize = lpsi->cbSize; + si.fMask = lpsi->fMask; + + res = (WINBOOL)NtUserGetScrollInfo(hwnd, fnBar, &si); + + if(res) + { + RtlCopyMemory(lpsi, &si, lpsi->cbSize); + } + + return res; } + +/* + * @implemented + */ int STDCALL GetScrollPos (HWND hWnd, int nBar) { - UNIMPLEMENTED; - return 0; + SCROLLINFO si; + BOOL ret; + int res = 0; + + si.cbSize = sizeof(SCROLLINFO); + si.fMask = SIF_POS; + ret = NtUserGetScrollInfo(hWnd, nBar, &si); + if(ret) + res = si.nPos; + return res; } + +/* + * @implemented + */ WINBOOL STDCALL GetScrollRange (HWND hWnd, int nBar, LPINT lpMinPos, LPINT lpMaxPos) { - UNIMPLEMENTED; - return FALSE; + WINBOOL ret; + SCROLLINFO si; + + if(!lpMinPos || !lpMaxPos) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + si.cbSize = sizeof(SCROLLINFO); + si.fMask = SIF_RANGE; + ret = NtUserGetScrollInfo(hWnd, nBar, &si); + if(ret) + { + *lpMinPos = si.nMin; + *lpMaxPos = si.nMax; + } + + return ret; } + +/* + * @implemented + */ int STDCALL SetScrollInfo (HWND hwnd, int fnBar, LPCSCROLLINFO lpsi, WINBOOL fRedraw) { - UNIMPLEMENTED; - return 0; + SCROLLINFO si; + + if(!lpsi || + ((lpsi->cbSize != sizeof(SCROLLINFO)) && (lpsi->cbSize != sizeof(SCROLLINFO) - sizeof(si.nTrackPos)))) + { + SetLastError(ERROR_INVALID_PARAMETER); + return 0; + } + RtlCopyMemory(&si, lpsi, lpsi->cbSize); + return (int)NtUserSetScrollInfo(hwnd, fnBar, &si, fRedraw); } + +/* + * @implemented + */ int STDCALL SetScrollPos (HWND hWnd, int nBar, int nPos, WINBOOL bRedraw) { - UNIMPLEMENTED; - return 0; + int Res = 0; + BOOL ret; + SCROLLINFO si; + + si.cbSize = sizeof(SCROLLINFO); + si.fMask = SIF_POS; + + /* call NtUserGetScrollInfo() because we need to return the previous position */ + ret = NtUserGetScrollInfo(hWnd, nBar, &si); + + if(ret) + { + Res = si.nPos; + + if(Res != nPos) + { + si.nPos = nPos; + /* finally set the new position */ + NtUserSetScrollInfo(hWnd, nBar, &si, bRedraw); + } + } + + return Res; } + +/* + * @implemented + */ WINBOOL STDCALL SetScrollRange (HWND hWnd, int nBar, int nMinPos, int nMaxPos, WINBOOL bRedraw) { - UNIMPLEMENTED; - return FALSE; + SCROLLINFO si; + + si.cbSize = sizeof(SCROLLINFO); + si.fMask = SIF_RANGE; + si.nMin = nMinPos; + si.nMax = nMaxPos; + + NtUserSetScrollInfo(hWnd, nBar, &si, bRedraw); + /* FIXME - check if called successfully */ + + return TRUE; } -/* Ported from WINE20020904 */ + +/* + * @implemented + */ WINBOOL STDCALL ShowScrollBar (HWND hWnd, int wBar, WINBOOL bShow) { - NtUserShowScrollBar (hWnd, wBar, bShow); - return TRUE; + return (WINBOOL)NtUserShowScrollBar (hWnd, wBar, bShow); }