2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
5 * FILE: subsys/win32k/ntuser/scrollbar.c
6 * PROGRAMER: Thomas Weidenmueller (w3seek@users.sourceforge.net)
7 * Jason Filby (jasonfilby@yahoo.com)
11 DBG_DEFAULT_CHANNEL(UserScrollbar
);
13 #define MINTRACKTHUMB 8 /* Minimum size of the rectangle between the arrows */
15 /* What to do after SetScrollInfo() */
16 #define SA_SSI_HIDE 0x0001
17 #define SA_SSI_SHOW 0x0002
18 #define SA_SSI_REFRESH 0x0004
19 #define SA_SSI_REPAINT_ARROWS 0x0008
21 #define SBRG_SCROLLBAR 0 /* The scrollbar itself */
22 #define SBRG_TOPRIGHTBTN 1 /* The top or right button */
23 #define SBRG_PAGEUPRIGHT 2 /* The page up or page right region */
24 #define SBRG_SCROLLBOX 3 /* The scroll box */
25 #define SBRG_PAGEDOWNLEFT 4 /* The page down or page left region */
26 #define SBRG_BOTTOMLEFTBTN 5 /* The bottom or left button */
28 #define CHANGERGSTATE(item, status) \
29 if(Info->rgstate[(item)] != (status)) \
31 Info->rgstate[(item)] = (status);
33 /* FUNCTIONS *****************************************************************/
35 /* Ported from WINE20020904 */
36 /* Compute the scroll bar rectangle, in drawing coordinates (i.e. client coords for SB_CTL, window coords for SB_VERT and
37 * SB_HORZ). 'arrowSize' returns the width or height of an arrow (depending on * the orientation of the scrollbar),
38 * 'thumbSize' returns the size of the thumb, and 'thumbPos' returns the position of the thumb relative to the left or to
39 * the top. Return TRUE if the scrollbar is vertical, FALSE if horizontal.
41 static inline void mirror_rect( const RECT
*window_rect
, RECT
*rect
)
43 int width
= window_rect
->right
- window_rect
->left
;
45 rect
->left
= width
- rect
->right
;
46 rect
->right
= width
- tmp
;
50 IntGetSBData(PWND pwnd
, INT Bar
)
55 pSBInfo
= pwnd
->pSBInfo
;
59 return &pSBInfo
->Horz
;
61 return &pSBInfo
->Vert
;
63 if ( pwnd
->cbwndExtra
!= (sizeof(SBWND
)-sizeof(WND
)) )
65 ERR("IntGetSBData Wrong Extra bytes for CTL Scrollbar!\n");
68 pSBWnd
= (PSBWND
)pwnd
;
69 return (PSBDATA
)&pSBWnd
->SBCalc
;
71 ERR("IntGetSBData Bad Bar!\n");
77 IntGetScrollBarRect (PWND Wnd
, INT nBar
, RECTL
*lprect
)
80 *lprect
= Wnd
->rcClient
;
82 RECTL_vOffsetRect( lprect
, -Wnd
->rcWindow
.left
, -Wnd
->rcWindow
.top
);
83 if (Wnd
->ExStyle
& WS_EX_LAYOUTRTL
)
84 mirror_rect( &Wnd
->rcWindow
, lprect
);
89 lprect
->top
= lprect
->bottom
;
90 lprect
->bottom
+= UserGetSystemMetrics (SM_CYHSCROLL
);
91 if (Wnd
->style
& WS_BORDER
)
96 else if (Wnd
->style
& WS_VSCROLL
)
104 if(Wnd
->ExStyle
& WS_EX_LEFTSCROLLBAR
)
106 lprect
->right
= lprect
->right
;;
107 lprect
->left
-= UserGetSystemMetrics(SM_CXVSCROLL
);
111 lprect
->left
= lprect
->right
;
112 lprect
->right
+= UserGetSystemMetrics(SM_CXVSCROLL
);
114 if (Wnd
->style
& WS_BORDER
)
119 else if (Wnd
->style
& WS_HSCROLL
)
127 IntGetClientRect (Wnd
, lprect
);
128 vertical
= !!(Wnd
->style
& SBS_VERT
);
139 IntCalculateThumb(PWND Wnd
, LONG idObject
, PSCROLLBARINFO psbi
, PSBDATA pSBData
)
141 INT Thumb
, ThumbBox
, ThumbPos
, cxy
, mx
;
147 Thumb
= UserGetSystemMetrics(SM_CXHSCROLL
);
148 cxy
= psbi
->rcScrollBar
.right
- psbi
->rcScrollBar
.left
;
151 Thumb
= UserGetSystemMetrics(SM_CYVSCROLL
);
152 cxy
= psbi
->rcScrollBar
.bottom
- psbi
->rcScrollBar
.top
;
155 IntGetClientRect(Wnd
, &ClientRect
);
156 if(Wnd
->style
& SBS_VERT
)
158 Thumb
= UserGetSystemMetrics(SM_CYVSCROLL
);
159 cxy
= ClientRect
.bottom
- ClientRect
.top
;
163 Thumb
= UserGetSystemMetrics(SM_CXHSCROLL
);
164 cxy
= ClientRect
.right
- ClientRect
.left
;
172 /* Calculate Thumb */
173 if(cxy
<= (2 * Thumb
))
176 psbi
->xyThumbTop
= 0;
177 psbi
->xyThumbBottom
= 0;
182 ThumbBox
= pSBData
->page
? MINTRACKTHUMB
: UserGetSystemMetrics(SM_CXHTHUMB
);
188 ThumbBox
= max(EngMulDiv(cxy
, pSBData
->page
, pSBData
->posMax
- pSBData
->posMin
+ 1), ThumbBox
);
193 mx
= pSBData
->posMax
- max(pSBData
->page
- 1, 0);
194 if(pSBData
->posMin
< mx
)
195 ThumbPos
= Thumb
+ EngMulDiv(cxy
- ThumbBox
, pSBData
->pos
- pSBData
->posMin
, mx
- pSBData
->posMin
);
197 ThumbPos
= Thumb
+ ThumbBox
;
200 psbi
->xyThumbTop
= ThumbPos
;
201 psbi
->xyThumbBottom
= ThumbPos
+ ThumbBox
;
205 psbi
->xyThumbTop
= 0;
206 psbi
->xyThumbBottom
= 0;
209 psbi
->dxyLineButton
= Thumb
;
215 IntUpdateSBInfo(PWND Window, int wBar)
221 ASSERT(Window->pSBInfo);
222 ASSERT(Window->pSBInfoex);
224 sbi = IntGetScrollbarInfoFromWindow(Window, wBar);
225 pSBData = IntGetSBData(Window, wBar);
226 IntGetScrollBarRect(Window, wBar, &(sbi->rcScrollBar));
227 IntCalculateThumb(Window, wBar, sbi, pSBData);
231 co_IntGetScrollInfo(PWND Window
, INT nBar
, PSBDATA pSBData
, LPSCROLLINFO lpsi
)
236 ASSERT_REFS_CO(Window
);
238 if(!SBID_IS_VALID(nBar
))
240 EngSetLastError(ERROR_INVALID_PARAMETER
);
241 ERR("Trying to get scrollinfo for unknown scrollbar type %d\n", nBar
);
245 if (!Window
->pSBInfo
)
247 ERR("IntGetScrollInfo No window scrollbar info!\n");
251 psi
= IntGetScrollInfoFromWindow(Window
, nBar
);
253 if (lpsi
->fMask
== SIF_ALL
)
255 Mask
= SIF_PAGE
| SIF_POS
| SIF_RANGE
| SIF_TRACKPOS
;
262 if (0 != (Mask
& SIF_PAGE
))
264 lpsi
->nPage
= psi
->nPage
;
267 if (0 != (Mask
& SIF_POS
))
269 lpsi
->nPos
= psi
->nPos
;
272 if (0 != (Mask
& SIF_RANGE
))
274 lpsi
->nMin
= psi
->nMin
;
275 lpsi
->nMax
= psi
->nMax
;
278 if (0 != (Mask
& SIF_TRACKPOS
))
280 lpsi
->nTrackPos
= psi
->nTrackPos
;
287 NEWco_IntGetScrollInfo(
294 PSBTRACK pSBTrack
= pWnd
->head
.pti
->pSBTrack
;
296 if (!SBID_IS_VALID(nBar
))
298 EngSetLastError(ERROR_INVALID_PARAMETER
);
299 ERR("Trying to get scrollinfo for unknown scrollbar type %d\n", nBar
);
303 if (!pWnd
->pSBInfo
|| !pSBTrack
) return FALSE
;
307 if (0 != (Mask
& SIF_PAGE
))
309 lpsi
->nPage
= pSBData
->page
;
312 if (0 != (Mask
& SIF_POS
))
314 lpsi
->nPos
= pSBData
->pos
;
317 if (0 != (Mask
& SIF_RANGE
))
319 lpsi
->nMin
= pSBData
->posMin
;
320 lpsi
->nMax
= pSBData
->posMax
;
323 if (0 != (Mask
& SIF_TRACKPOS
))
326 pSBTrack
->nBar
== nBar
&&
327 pSBTrack
->spwndTrack
== pWnd
)
328 lpsi
->nTrackPos
= pSBTrack
->posNew
;
330 lpsi
->nTrackPos
= pSBData
->pos
;
332 return (Mask
& SIF_ALL
) !=0;
335 static DWORD FASTCALL
336 co_IntSetScrollInfo(PWND Window
, INT nBar
, LPCSCROLLINFO lpsi
, BOOL bRedraw
)
339 * Update the scrollbar state and set action flags according to
340 * what has to be done graphics wise.
349 BOOL bChangeParams
= FALSE
; /* Don't show/hide scrollbar if params don't change */
351 ASSERT_REFS_CO(Window
);
353 if(!SBID_IS_VALID(nBar
))
355 EngSetLastError(ERROR_INVALID_PARAMETER
);
356 ERR("Trying to set scrollinfo for unknown scrollbar type %d", nBar
);
360 if(!co_IntCreateScrollBars(Window
))
365 if (lpsi
->cbSize
!= sizeof(SCROLLINFO
) &&
366 lpsi
->cbSize
!= (sizeof(SCROLLINFO
) - sizeof(lpsi
->nTrackPos
)))
368 EngSetLastError(ERROR_INVALID_PARAMETER
);
371 if (lpsi
->fMask
& ~(SIF_ALL
| SIF_DISABLENOSCROLL
| SIF_PREVIOUSPOS
))
373 EngSetLastError(ERROR_INVALID_PARAMETER
);
377 psbi
= IntGetScrollbarInfoFromWindow(Window
, nBar
);
378 Info
= IntGetScrollInfoFromWindow(Window
, nBar
);
379 pSBData
= IntGetSBData(Window
, nBar
);
381 /* Set the page size */
382 if (lpsi
->fMask
& SIF_PAGE
)
384 if (Info
->nPage
!= lpsi
->nPage
)
386 Info
->nPage
= lpsi
->nPage
;
387 pSBData
->page
= lpsi
->nPage
;
388 bChangeParams
= TRUE
;
392 /* Set the scroll pos */
393 if (lpsi
->fMask
& SIF_POS
)
395 if (Info
->nPos
!= lpsi
->nPos
)
398 Info
->nPos
= lpsi
->nPos
;
399 pSBData
->pos
= lpsi
->nPos
;
400 bChangeParams
= TRUE
;
404 /* Set the scroll range */
405 if (lpsi
->fMask
& SIF_RANGE
)
407 /* Invalid range -> range is set to (0,0) */
408 if ((lpsi
->nMin
> lpsi
->nMax
) ||
409 ((UINT
)(lpsi
->nMax
- lpsi
->nMin
) >= 0x80000000))
415 bChangeParams
= TRUE
;
417 else if (Info
->nMin
!= lpsi
->nMin
|| Info
->nMax
!= lpsi
->nMax
)
419 Info
->nMin
= lpsi
->nMin
;
420 Info
->nMax
= lpsi
->nMax
;
421 pSBData
->posMin
= lpsi
->nMin
;
422 pSBData
->posMax
= lpsi
->nMax
;
423 bChangeParams
= TRUE
;
427 /* Make sure the page size is valid */
430 pSBData
->page
= Info
->nPage
= 0;
432 else if ((Info
->nMax
- Info
->nMin
+ 1UL) < Info
->nPage
)
434 pSBData
->page
= Info
->nPage
= Info
->nMax
- Info
->nMin
+ 1;
437 /* Make sure the pos is inside the range */
438 if (Info
->nPos
< Info
->nMin
)
440 pSBData
->pos
= Info
->nPos
= Info
->nMin
;
442 else if (Info
->nPos
> (Info
->nMax
- max((int)Info
->nPage
- 1, 0)))
444 pSBData
->pos
= Info
->nPos
= Info
->nMax
- max(Info
->nPage
- 1, 0);
448 * Don't change the scrollbar state if SetScrollInfo is just called
449 * with SIF_DISABLENOSCROLL
451 if (!(lpsi
->fMask
& SIF_ALL
))
454 return lpsi
->fMask
& SIF_PREVIOUSPOS
? OldPos
: pSBData
->pos
;
457 /* Check if the scrollbar should be hidden or disabled */
458 if (lpsi
->fMask
& (SIF_RANGE
| SIF_PAGE
| SIF_DISABLENOSCROLL
))
460 new_flags
= Window
->pSBInfo
->WSBflags
;
461 if (Info
->nMin
>= (int)(Info
->nMax
- max(Info
->nPage
- 1, 0)))
463 /* Hide or disable scroll-bar */
464 if (lpsi
->fMask
& SIF_DISABLENOSCROLL
)
466 new_flags
= ESB_DISABLE_BOTH
;
467 bChangeParams
= TRUE
;
469 else if ((nBar
!= SB_CTL
) && bChangeParams
)
471 action
= SA_SSI_HIDE
;
474 else /* Show and enable scroll-bar only if no page only changed. */
475 if (lpsi
->fMask
!= SIF_PAGE
)
477 new_flags
= ESB_ENABLE_BOTH
;
478 if ((nBar
!= SB_CTL
) && bChangeParams
)
480 action
|= SA_SSI_SHOW
;
484 if (Window
->pSBInfo
->WSBflags
!= new_flags
) /* Check arrow flags */
486 Window
->pSBInfo
->WSBflags
= new_flags
;
487 action
|= SA_SSI_REPAINT_ARROWS
;
492 if ( action
& SA_SSI_HIDE
)
494 co_UserShowScrollBar(Window
, nBar
, FALSE
, FALSE
);
498 if ( action
& SA_SSI_SHOW
)
499 if ( co_UserShowScrollBar(Window
, nBar
, TRUE
, TRUE
) )
500 return lpsi
->fMask
& SIF_PREVIOUSPOS
? OldPos
: pSBData
->pos
; /* SetWindowPos() already did the painting */
502 { // FIXME: Arrows and interior.
503 RECTL UpdateRect
= psbi
->rcScrollBar
;
504 UpdateRect
.left
-= Window
->rcClient
.left
- Window
->rcWindow
.left
;
505 UpdateRect
.right
-= Window
->rcClient
.left
- Window
->rcWindow
.left
;
506 UpdateRect
.top
-= Window
->rcClient
.top
- Window
->rcWindow
.top
;
507 UpdateRect
.bottom
-= Window
->rcClient
.top
- Window
->rcWindow
.top
;
508 co_UserRedrawWindow(Window
, &UpdateRect
, 0, RDW_INVALIDATE
| RDW_FRAME
);
510 /* else if( action & SA_SSI_REPAINT_ARROWS )
512 RECTL UpdateRect = psbi->rcScrollBar;
513 UpdateRect.left -= Window->rcClient.left - Window->rcWindow.left;
514 UpdateRect.right -= Window->rcClient.left - Window->rcWindow.left;
515 UpdateRect.top -= Window->rcClient.top - Window->rcWindow.top;
516 UpdateRect.bottom -= Window->rcClient.top - Window->rcWindow.top;
517 co_UserRedrawWindow(Window, &UpdateRect, 0, RDW_INVALIDATE | RDW_FRAME);
520 /* Return current position */
521 return lpsi
->fMask
& SIF_PREVIOUSPOS
? OldPos
: pSBData
->pos
;
525 co_IntGetScrollBarInfo(PWND Window
, LONG idObject
, PSCROLLBARINFO psbi
)
530 ASSERT_REFS_CO(Window
);
532 Bar
= SBOBJ_TO_SBID(idObject
);
534 if(!SBID_IS_VALID(Bar
))
536 EngSetLastError(ERROR_INVALID_PARAMETER
);
537 ERR("Trying to get scrollinfo for unknown scrollbar type %d\n", Bar
);
541 if(!co_IntCreateScrollBars(Window
))
543 ERR("Failed to create scrollbars for window.\n");
547 sbi
= IntGetScrollbarInfoFromWindow(Window
, Bar
);
548 pSBData
= IntGetSBData(Window
, Bar
);
550 IntGetScrollBarRect(Window
, Bar
, &(sbi
->rcScrollBar
));
551 IntCalculateThumb(Window
, Bar
, sbi
, pSBData
);
553 RtlCopyMemory(psbi
, sbi
, sizeof(SCROLLBARINFO
));
559 co_IntCreateScrollBars(PWND Window
)
566 ASSERT_REFS_CO(Window
);
568 if (Window
->pSBInfo
&& Window
->pSBInfoex
)
570 /* No need to create it anymore */
574 /* Allocate memory for all scrollbars (HORZ, VERT, CONTROL) */
575 Size
= 3 * (sizeof(SBINFOEX
));
576 if(!(Window
->pSBInfoex
= ExAllocatePoolWithTag(PagedPool
, Size
, TAG_SBARINFO
)))
578 ERR("Unable to allocate memory for scrollbar information for window 0x%x\n", Window
->head
.h
);
582 RtlZeroMemory(Window
->pSBInfoex
, Size
);
584 if(!(Window
->pSBInfo
= DesktopHeapAlloc( Window
->head
.rpdesk
, sizeof(SBINFO
))))
586 ERR("Unable to allocate memory for scrollbar information for window 0x%x\n", Window
->head
.h
);
590 RtlZeroMemory(Window
->pSBInfo
, sizeof(SBINFO
));
591 Window
->pSBInfo
->Vert
.posMax
= 100;
592 Window
->pSBInfo
->Horz
.posMax
= 100;
594 co_WinPosGetNonClientSize(Window
,
598 for(s
= SB_HORZ
; s
<= SB_VERT
; s
++)
600 psbi
= IntGetScrollbarInfoFromWindow(Window
, s
);
601 psbi
->cbSize
= sizeof(SCROLLBARINFO
);
602 for (i
= 0; i
< CCHILDREN_SCROLLBAR
+ 1; i
++)
603 psbi
->rgstate
[i
] = 0;
605 pSBData
= IntGetSBData(Window
, s
);
607 IntGetScrollBarRect(Window
, s
, &(psbi
->rcScrollBar
));
608 IntCalculateThumb(Window
, s
, psbi
, pSBData
);
615 IntDestroyScrollBars(PWND Window
)
617 if (Window
->pSBInfo
&& Window
->pSBInfoex
)
619 DesktopHeapFree(Window
->head
.rpdesk
, Window
->pSBInfo
);
620 Window
->pSBInfo
= NULL
;
621 ExFreePoolWithTag(Window
->pSBInfoex
, TAG_SBARINFO
);
622 Window
->pSBInfoex
= NULL
;
629 IntEnableScrollBar(BOOL Horz
, PSCROLLBARINFO Info
, UINT wArrows
)
634 case ESB_DISABLE_BOTH
:
635 CHANGERGSTATE(SBRG_TOPRIGHTBTN
, STATE_SYSTEM_UNAVAILABLE
);
636 CHANGERGSTATE(SBRG_BOTTOMLEFTBTN
, STATE_SYSTEM_UNAVAILABLE
);
638 case ESB_DISABLE_RTDN
:
641 CHANGERGSTATE(SBRG_BOTTOMLEFTBTN
, STATE_SYSTEM_UNAVAILABLE
);
645 CHANGERGSTATE(SBRG_TOPRIGHTBTN
, STATE_SYSTEM_UNAVAILABLE
);
648 case ESB_DISABLE_LTUP
:
651 CHANGERGSTATE(SBRG_TOPRIGHTBTN
, STATE_SYSTEM_UNAVAILABLE
);
655 CHANGERGSTATE(SBRG_BOTTOMLEFTBTN
, STATE_SYSTEM_UNAVAILABLE
);
658 case ESB_ENABLE_BOTH
:
659 CHANGERGSTATE(SBRG_TOPRIGHTBTN
, 0);
660 CHANGERGSTATE(SBRG_BOTTOMLEFTBTN
, 0);
666 /* Ported from WINE20020904 (SCROLL_ShowScrollBar) */
668 co_UserShowScrollBar(PWND Wnd
, int nBar
, BOOL fShowH
, BOOL fShowV
)
670 ULONG old_style
, set_bits
= 0, clear_bits
= 0;
678 //IntUpdateSBInfo(Wnd, SB_CTL); // Is this needed? Was tested w/o!
680 co_WinPosShowWindow(Wnd
, fShowH
? SW_SHOW
: SW_HIDE
);
685 if (fShowH
) set_bits
|= WS_HSCROLL
;
686 else clear_bits
|= WS_HSCROLL
;
687 if( nBar
== SB_HORZ
) break;
690 if (fShowV
) set_bits
|= WS_VSCROLL
;
691 else clear_bits
|= WS_VSCROLL
;
694 EngSetLastError(ERROR_INVALID_PARAMETER
);
698 old_style
= IntSetStyle( Wnd
, set_bits
, clear_bits
);
699 if ((old_style
& clear_bits
) != 0 || (old_style
& set_bits
) != set_bits
)
701 ///// Is this needed? Was tested w/o!
702 //if (Wnd->style & WS_HSCROLL) IntUpdateSBInfo(Wnd, SB_HORZ);
703 //if (Wnd->style & WS_VSCROLL) IntUpdateSBInfo(Wnd, SB_VERT);
705 /* Frame has been changed, let the window redraw itself */
706 co_WinPosSetWindowPos(Wnd
, 0, 0, 0, 0, 0, SWP_NOSIZE
| SWP_NOMOVE
|
707 SWP_NOACTIVATE
| SWP_NOZORDER
| SWP_FRAMECHANGED
| SWP_NOSENDCHANGING
);
714 ScrollBarWndProc(HWND hWnd
, UINT Msg
, WPARAM wParam
, LPARAM lParam
)
718 pWnd
= UserGetWindowObject(hWnd
);
727 pWnd
->pSBInfo
->WSBflags
= wParam
? ESB_ENABLE_BOTH
: ESB_DISABLE_BOTH
;
739 NtUserGetScrollBarInfo(HWND hWnd
, LONG idObject
, PSCROLLBARINFO psbi
)
745 DECLARE_RETURN(BOOL
);
746 USER_REFERENCE_ENTRY Ref
;
748 TRACE("Enter NtUserGetScrollBarInfo\n");
749 UserEnterExclusive();
751 Status
= MmCopyFromCaller(&sbi
, psbi
, sizeof(SCROLLBARINFO
));
752 if(!NT_SUCCESS(Status
) || (sbi
.cbSize
!= sizeof(SCROLLBARINFO
)))
754 SetLastNtError(Status
);
758 if(!(Window
= UserGetWindowObject(hWnd
)))
763 UserRefObjectCo(Window
, &Ref
);
764 Ret
= co_IntGetScrollBarInfo(Window
, idObject
, &sbi
);
765 UserDerefObjectCo(Window
);
767 Status
= MmCopyToCaller(psbi
, &sbi
, sizeof(SCROLLBARINFO
));
768 if(!NT_SUCCESS(Status
))
770 SetLastNtError(Status
);
777 TRACE("Leave NtUserGetScrollBarInfo, ret=%i\n",_ret_
);
795 DECLARE_RETURN(BOOL
);
796 USER_REFERENCE_ENTRY Ref
;
798 TRACE("Enter NtUserGetScrollInfo\n");
803 RtlCopyMemory(&psi
, lpsi
, sizeof(SCROLLINFO
));
806 RtlCopyMemory(&SBDataSafe
, pSBData
, sizeof(SBDATA
));
809 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
811 ERR("NtUserGetScrollInfo Failed size.\n");
812 SetLastNtError(_SEH2_GetExceptionCode());
813 _SEH2_YIELD(RETURN(FALSE
));
817 if(!(Window
= UserGetWindowObject(hWnd
)))
819 ERR("NtUserGetScrollInfo Bad window.\n");
823 UserRefObjectCo(Window
, &Ref
);
824 Ret
= co_IntGetScrollInfo(Window
, fnBar
, &SBDataSafe
, &psi
);
825 UserDerefObjectCo(Window
);
829 RtlCopyMemory(lpsi
, &psi
, sizeof(SCROLLINFO
));
831 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
833 ERR("NtUserGetScrollInfo Failed copy to user.\n");
834 SetLastNtError(_SEH2_GetExceptionCode());
835 _SEH2_YIELD(RETURN(FALSE
));
842 TRACE("Leave NtUserGetScrollInfo, ret=%i\n",_ret_
);
849 NtUserEnableScrollBar(
856 PSCROLLBARINFO InfoV
= NULL
, InfoH
= NULL
;
858 DECLARE_RETURN(BOOL
);
859 USER_REFERENCE_ENTRY Ref
;
861 TRACE("Enter NtUserEnableScrollBar\n");
862 UserEnterExclusive();
864 if (!(Window
= UserGetWindowObject(hWnd
)) || // FIXME:
865 Window
== UserGetDesktopWindow() || // pWnd->fnid == FNID_DESKTOP
866 Window
== UserGetMessageWindow() ) // pWnd->fnid == FNID_MESSAGEWND
870 UserRefObjectCo(Window
, &Ref
);
872 if (!co_IntCreateScrollBars(Window
))
877 OrigArrows
= Window
->pSBInfo
->WSBflags
;
878 Window
->pSBInfo
->WSBflags
= wArrows
;
880 if (wSBflags
== SB_CTL
)
882 if ((wArrows
== ESB_DISABLE_BOTH
|| wArrows
== ESB_ENABLE_BOTH
))
883 IntEnableWindow(hWnd
, (wArrows
== ESB_ENABLE_BOTH
));
888 if(wSBflags
!= SB_BOTH
&& !SBID_IS_VALID(wSBflags
))
890 EngSetLastError(ERROR_INVALID_PARAMETER
);
891 ERR("Trying to set scrollinfo for unknown scrollbar type %d", wSBflags
);
898 InfoV
= IntGetScrollbarInfoFromWindow(Window
, SB_VERT
);
901 InfoH
= IntGetScrollbarInfoFromWindow(Window
, SB_HORZ
);
904 InfoV
= IntGetScrollbarInfoFromWindow(Window
, SB_VERT
);
911 Chg
= IntEnableScrollBar(FALSE
, InfoV
, wArrows
);
914 Chg
= (IntEnableScrollBar(TRUE
, InfoH
, wArrows
) || Chg
);
916 ERR("FIXME: EnableScrollBar wSBflags %d wArrows %d Chg %d\n",wSBflags
,wArrows
, Chg
);
918 // SCROLL_RefreshScrollBar( hwnd, nBar, TRUE, TRUE );
921 if (OrigArrows
== wArrows
) RETURN( FALSE
);
926 UserDerefObjectCo(Window
);
928 TRACE("Leave NtUserEnableScrollBar, ret=%i\n",_ret_
);
943 SCROLLINFO ScrollInfo
;
944 DECLARE_RETURN(DWORD
);
945 USER_REFERENCE_ENTRY Ref
;
947 TRACE("Enter NtUserSetScrollInfo\n");
948 UserEnterExclusive();
950 if(!(Window
= UserGetWindowObject(hWnd
)) || // FIXME:
951 Window
== UserGetDesktopWindow() || // pWnd->fnid == FNID_DESKTOP
952 Window
== UserGetMessageWindow() ) // pWnd->fnid == FNID_MESSAGEWND
956 UserRefObjectCo(Window
, &Ref
);
958 Status
= MmCopyFromCaller(&ScrollInfo
, lpsi
, sizeof(SCROLLINFO
) - sizeof(ScrollInfo
.nTrackPos
));
959 if(!NT_SUCCESS(Status
))
961 SetLastNtError(Status
);
965 RETURN(co_IntSetScrollInfo(Window
, fnBar
, &ScrollInfo
, bRedraw
));
969 UserDerefObjectCo(Window
);
971 TRACE("Leave NtUserSetScrollInfo, ret=%i\n",_ret_
);
978 NtUserShowScrollBar(HWND hWnd
, int nBar
, DWORD bShow
)
981 DECLARE_RETURN(DWORD
);
983 USER_REFERENCE_ENTRY Ref
;
985 TRACE("Enter NtUserShowScrollBar\n");
986 UserEnterExclusive();
988 if (!(Window
= UserGetWindowObject(hWnd
)))
993 UserRefObjectCo(Window
, &Ref
);
994 ret
= co_UserShowScrollBar(Window
, nBar
, (nBar
== SB_VERT
) ? 0 : bShow
,
995 (nBar
== SB_HORZ
) ? 0 : bShow
);
996 UserDerefObjectCo(Window
);
1001 TRACE("Leave NtUserShowScrollBar, ret%i\n",_ret_
);
1008 //// Ugly NtUser API ////
1012 NtUserSetScrollBarInfo(
1015 SETSCROLLBARINFO
*info
)
1018 SETSCROLLBARINFO Safeinfo
;
1023 DECLARE_RETURN(BOOL
);
1024 USER_REFERENCE_ENTRY Ref
;
1026 TRACE("Enter NtUserSetScrollBarInfo\n");
1027 UserEnterExclusive();
1029 if(!(Window
= UserGetWindowObject(hWnd
)))
1033 UserRefObjectCo(Window
, &Ref
);
1035 Obj
= SBOBJ_TO_SBID(idObject
);
1036 if(!SBID_IS_VALID(Obj
))
1038 EngSetLastError(ERROR_INVALID_PARAMETER
);
1039 ERR("Trying to set scrollinfo for unknown scrollbar type %d\n", Obj
);
1043 if(!co_IntCreateScrollBars(Window
))
1048 Status
= MmCopyFromCaller(&Safeinfo
, info
, sizeof(SETSCROLLBARINFO
));
1049 if(!NT_SUCCESS(Status
))
1051 SetLastNtError(Status
);
1055 sbi
= IntGetScrollbarInfoFromWindow(Window
, Obj
);
1056 psi
= IntGetScrollInfoFromWindow(Window
, Obj
);
1058 psi
->nTrackPos
= Safeinfo
.nTrackPos
;
1059 sbi
->reserved
= Safeinfo
.reserved
;
1060 RtlCopyMemory(&sbi
->rgstate
, &Safeinfo
.rgstate
, sizeof(Safeinfo
.rgstate
));
1066 UserDerefObjectCo(Window
);
1068 TRACE("Leave NtUserSetScrollBarInfo, ret=%i\n",_ret_
);