3 * ReactOS User32 Library
6 * Copyright 2001 Casper S. Hornstrup
7 * Copyright 2003 Thomas Weidenmueller
8 * Copyright 2003 Filip Navara
12 * Copyright 1993 Martin Ayotte
13 * Copyright 1994, 1996 Alexandre Julliard
15 * This library is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU Lesser General Public
17 * License as published by the Free Software Foundation; either
18 * version 2.1 of the License, or (at your option) any later version.
20 * This library is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 * Lesser General Public License for more details.
25 * You should have received a copy of the GNU Lesser General Public
26 * License along with this library; if not, write to the Free Software
27 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30 /* INCLUDES *******************************************************************/
34 #include <wine/debug.h>
35 WINE_DEFAULT_DEBUG_CHANNEL(scrollbar
);
37 /* GLOBAL VARIABLES ***********************************************************/
39 /* Definitions for scrollbar hit testing [See SCROLLBARINFO in MSDN] */
40 #define SCROLL_NOWHERE 0x00 /* Outside the scroll bar */
41 #define SCROLL_TOP_ARROW 0x01 /* Top or left arrow */
42 #define SCROLL_TOP_RECT 0x02 /* Rectangle between the top arrow and the thumb */
43 #define SCROLL_THUMB 0x03 /* Thumb rectangle */
44 #define SCROLL_BOTTOM_RECT 0x04 /* Rectangle between the thumb and the bottom arrow */
45 #define SCROLL_BOTTOM_ARROW 0x05 /* Bottom or right arrow */
47 #define SCROLL_FIRST_DELAY 200 /* Delay (in ms) before first repetition when
48 holding the button down */
49 #define SCROLL_REPEAT_DELAY 50 /* Delay (in ms) between scroll repetitions */
51 #define SCROLL_TIMER 0 /* Scroll timer id */
53 /* Minimum size of the rectangle between the arrows */
54 #define SCROLL_MIN_RECT 4
56 /* Minimum size of the thumb in pixels */
57 #define SCROLL_MIN_THUMB 6
59 /* Thumb-tracking info */
60 static HWND ScrollTrackingWin
= 0;
61 static INT ScrollTrackingBar
= 0;
62 static INT ScrollTrackingPos
= 0;
63 static INT ScrollTrackingVal
= 0;
64 static BOOL ScrollMovingThumb
= FALSE
;
66 static DWORD ScrollTrackHitTest
= SCROLL_NOWHERE
;
67 static BOOL ScrollTrackVertical
;
69 HBRUSH
DefWndControlColor(HDC hDC
, UINT ctlType
);
71 UINT WINAPI
SetSystemTimer(HWND
,UINT_PTR
,UINT
,TIMERPROC
);
72 BOOL WINAPI
KillSystemTimer(HWND
,UINT_PTR
);
74 /*********************************************************************
75 * scrollbar class descriptor
77 const struct builtin_class_descr SCROLL_builtin_class
=
79 L
"ScrollBar", /* name */
80 CS_DBLCLKS
| CS_VREDRAW
| CS_HREDRAW
| CS_PARENTDC
, /* style */
81 ScrollBarWndProcA
, /* procA */
82 ScrollBarWndProcW
, /* procW */
84 IDC_ARROW
, /* cursor */
88 /* PRIVATE FUNCTIONS **********************************************************/
92 IntDrawScrollInterior(HWND hWnd
, HDC hDC
, INT nBar
, BOOL Vertical
,
93 PSCROLLBARINFO ScrollBarInfo
)
95 INT ThumbSize
= ScrollBarInfo
->xyThumbBottom
- ScrollBarInfo
->xyThumbTop
;
96 INT ThumbTop
= ScrollBarInfo
->xyThumbTop
;
98 HBRUSH hSaveBrush
, hBrush
;
99 BOOL TopSelected
= FALSE
, BottomSelected
= FALSE
;
101 if (ScrollBarInfo
->rgstate
[SCROLL_TOP_RECT
] & STATE_SYSTEM_PRESSED
)
103 if (ScrollBarInfo
->rgstate
[SCROLL_BOTTOM_RECT
] & STATE_SYSTEM_PRESSED
)
104 BottomSelected
= TRUE
;
107 * Only scrollbar controls send WM_CTLCOLORSCROLLBAR.
108 * The window-owned scrollbars need to call DefWndControlColor
109 * to correctly setup default scrollbar colors
113 hBrush
= (HBRUSH
)SendMessageW(GetParent(hWnd
), WM_CTLCOLORSCROLLBAR
, (WPARAM
)hDC
, (LPARAM
)hWnd
);
115 hBrush
= GetSysColorBrush(COLOR_SCROLLBAR
);
119 hBrush
= DefWndControlColor(hDC
, CTLCOLOR_SCROLLBAR
);
122 hSaveBrush
= SelectObject(hDC
, hBrush
);
124 /* Calculate the scroll rectangle */
127 Rect
.top
= ScrollBarInfo
->rcScrollBar
.top
+ ScrollBarInfo
->dxyLineButton
;
128 Rect
.bottom
= ScrollBarInfo
->rcScrollBar
.bottom
- ScrollBarInfo
->dxyLineButton
;
129 Rect
.left
= ScrollBarInfo
->rcScrollBar
.left
;
130 Rect
.right
= ScrollBarInfo
->rcScrollBar
.right
;
134 Rect
.top
= ScrollBarInfo
->rcScrollBar
.top
;
135 Rect
.bottom
= ScrollBarInfo
->rcScrollBar
.bottom
;
136 Rect
.left
= ScrollBarInfo
->rcScrollBar
.left
+ ScrollBarInfo
->dxyLineButton
;
137 Rect
.right
= ScrollBarInfo
->rcScrollBar
.right
- ScrollBarInfo
->dxyLineButton
;
140 /* Draw the scroll rectangles and thumb */
141 if (!ScrollBarInfo
->xyThumbBottom
)
143 PatBlt(hDC
, Rect
.left
, Rect
.top
, Rect
.right
- Rect
.left
,
144 Rect
.bottom
- Rect
.top
, PATCOPY
);
146 /* Cleanup and return */
147 SelectObject(hDC
, hSaveBrush
);
151 ThumbTop
-= ScrollBarInfo
->dxyLineButton
;
153 if (ScrollBarInfo
->dxyLineButton
)
159 PatBlt(hDC
, Rect
.left
, Rect
.top
, Rect
.right
- Rect
.left
,
160 ThumbTop
, TopSelected
? BLACKNESS
: PATCOPY
);
161 Rect
.top
+= ThumbTop
;
162 PatBlt(hDC
, Rect
.left
, Rect
.top
+ ThumbSize
, Rect
.right
- Rect
.left
,
163 Rect
.bottom
- Rect
.top
- ThumbSize
, BottomSelected
? BLACKNESS
: PATCOPY
);
164 Rect
.bottom
= Rect
.top
+ ThumbSize
;
170 PatBlt(hDC
, Rect
.left
, ScrollBarInfo
->dxyLineButton
,
171 Rect
.right
- Rect
.left
, Rect
.bottom
- Rect
.top
, PATCOPY
);
179 PatBlt(hDC
, Rect
.left
, Rect
.top
, ThumbTop
,
180 Rect
.bottom
- Rect
.top
, TopSelected
? BLACKNESS
: PATCOPY
);
181 Rect
.left
+= ThumbTop
;
182 PatBlt(hDC
, Rect
.left
+ ThumbSize
, Rect
.top
,
183 Rect
.right
- Rect
.left
- ThumbSize
, Rect
.bottom
- Rect
.top
,
184 BottomSelected
? BLACKNESS
: PATCOPY
);
185 Rect
.right
= Rect
.left
+ ThumbSize
;
191 PatBlt(hDC
, ScrollBarInfo
->dxyLineButton
, Rect
.top
,
192 Rect
.right
- Rect
.left
, Rect
.bottom
- Rect
.top
, PATCOPY
);
200 DrawEdge(hDC
, &Rect
, EDGE_RAISED
, BF_RECT
| BF_MIDDLE
);
203 SelectObject(hDC
, hSaveBrush
);
207 IntDrawScrollArrows(HDC hDC
, PSCROLLBARINFO ScrollBarInfo
, BOOL Vertical
)
210 INT ScrollDirFlagLT
, ScrollDirFlagRB
;
212 RectLT
= RectRB
= ScrollBarInfo
->rcScrollBar
;
215 ScrollDirFlagLT
= DFCS_SCROLLUP
;
216 ScrollDirFlagRB
= DFCS_SCROLLDOWN
;
217 RectLT
.bottom
= RectLT
.top
+ ScrollBarInfo
->dxyLineButton
;
218 RectRB
.top
= RectRB
.bottom
- ScrollBarInfo
->dxyLineButton
;
222 ScrollDirFlagLT
= DFCS_SCROLLLEFT
;
223 ScrollDirFlagRB
= DFCS_SCROLLRIGHT
;
224 RectLT
.right
= RectLT
.left
+ ScrollBarInfo
->dxyLineButton
;
225 RectRB
.left
= RectRB
.right
- ScrollBarInfo
->dxyLineButton
;
228 if (ScrollBarInfo
->rgstate
[SCROLL_TOP_ARROW
] & STATE_SYSTEM_PRESSED
)
230 ScrollDirFlagLT
|= DFCS_PUSHED
| DFCS_FLAT
;
232 if (ScrollBarInfo
->rgstate
[SCROLL_TOP_ARROW
] & STATE_SYSTEM_UNAVAILABLE
)
234 ScrollDirFlagLT
|= DFCS_INACTIVE
;
236 if (ScrollBarInfo
->rgstate
[SCROLL_BOTTOM_ARROW
] & STATE_SYSTEM_PRESSED
)
238 ScrollDirFlagRB
|= DFCS_PUSHED
| DFCS_FLAT
;
240 if (ScrollBarInfo
->rgstate
[SCROLL_BOTTOM_ARROW
] & STATE_SYSTEM_UNAVAILABLE
)
242 ScrollDirFlagRB
|= DFCS_INACTIVE
;
245 DrawFrameControl(hDC
, &RectLT
, DFC_SCROLL
, ScrollDirFlagLT
);
246 DrawFrameControl(hDC
, &RectRB
, DFC_SCROLL
, ScrollDirFlagRB
);
250 IntScrollDrawMovingThumb(HDC Dc
, PSCROLLBARINFO ScrollBarInfo
, BOOL Vertical
)
252 INT Pos
= ScrollTrackingPos
;
258 MaxSize
= ScrollBarInfo
->rcScrollBar
.bottom
- ScrollBarInfo
->rcScrollBar
.top
;
262 MaxSize
= ScrollBarInfo
->rcScrollBar
.right
- ScrollBarInfo
->rcScrollBar
.left
;
265 MaxSize
-= ScrollBarInfo
->dxyLineButton
+ ScrollBarInfo
->xyThumbBottom
266 - ScrollBarInfo
->xyThumbTop
;
268 if (Pos
< ScrollBarInfo
->dxyLineButton
)
270 Pos
= ScrollBarInfo
->dxyLineButton
;
272 else if (MaxSize
< Pos
)
277 OldTop
= ScrollBarInfo
->xyThumbTop
;
278 ScrollBarInfo
->xyThumbBottom
= Pos
+ ScrollBarInfo
->xyThumbBottom
- ScrollBarInfo
->xyThumbTop
;
279 ScrollBarInfo
->xyThumbTop
= Pos
;
280 IntDrawScrollInterior(ScrollTrackingWin
, Dc
, ScrollTrackingBar
, Vertical
, ScrollBarInfo
);
281 ScrollBarInfo
->xyThumbBottom
= OldTop
+ ScrollBarInfo
->xyThumbBottom
- ScrollBarInfo
->xyThumbTop
;
282 ScrollBarInfo
->xyThumbTop
= OldTop
;
284 ScrollMovingThumb
= ! ScrollMovingThumb
;
288 IntScrollGetObjectId(INT SBType
)
290 if (SB_VERT
== SBType
)
292 return OBJID_VSCROLL
;
294 if (SB_HORZ
== SBType
)
296 return OBJID_HSCROLL
;
303 IntGetScrollBarInfo(HWND Wnd
, INT Bar
, PSCROLLBARINFO ScrollBarInfo
)
305 ScrollBarInfo
->cbSize
= sizeof(SCROLLBARINFO
);
307 return NtUserGetScrollBarInfo(Wnd
, IntScrollGetObjectId(Bar
), ScrollBarInfo
);
311 IntDrawScrollBar(HWND Wnd
, HDC DC
, INT Bar
)
318 * Get scroll bar info.
331 Vertical
= (GetWindowLongPtrW(Wnd
, GWL_STYLE
) & SBS_VERT
) != 0;
337 if (! IntGetScrollBarInfo(Wnd
, Bar
, &Info
))
342 if (IsRectEmpty(&Info
.rcScrollBar
))
347 ThumbSize
= Info
.xyThumbBottom
- Info
.xyThumbTop
;
352 if (Info
.dxyLineButton
)
354 IntDrawScrollArrows(DC
, &Info
, Vertical
);
360 IntDrawScrollInterior(Wnd
, DC
, Bar
, Vertical
, &Info
);
363 * If scroll bar has focus, reposition the caret.
365 if (Wnd
== GetFocus() && SB_CTL
== Bar
)
369 SetCaretPos(Info
.rcScrollBar
.top
+ 1, Info
.dxyLineButton
+ 1);
373 SetCaretPos(Info
.dxyLineButton
+ 1, Info
.rcScrollBar
.top
+ 1);
379 IntScrollPtInRectEx(LPRECT Rect
, POINT Pt
, BOOL Vertical
)
381 RECT TempRect
= *Rect
;
384 TempRect
.left
-= Rect
->right
- Rect
->left
;
385 TempRect
.right
+= Rect
->right
- Rect
->left
;
389 TempRect
.top
-= Rect
->bottom
- Rect
->top
;
390 TempRect
.bottom
+= Rect
->bottom
- Rect
->top
;
393 return PtInRect(&TempRect
, Pt
);
396 static DWORD FASTCALL
397 IntScrollHitTest(PSCROLLBARINFO ScrollBarInfo
, BOOL Vertical
, POINT Pt
, BOOL Dragging
)
399 INT ArrowSize
, ThumbSize
, ThumbPos
;
401 if ((Dragging
&& ! IntScrollPtInRectEx(&ScrollBarInfo
->rcScrollBar
, Pt
, Vertical
)) ||
402 ! PtInRect(&ScrollBarInfo
->rcScrollBar
, Pt
))
404 return SCROLL_NOWHERE
;
407 ThumbPos
= ScrollBarInfo
->xyThumbTop
;
408 ThumbSize
= ScrollBarInfo
->xyThumbBottom
- ThumbPos
;
409 ArrowSize
= ScrollBarInfo
->dxyLineButton
;
413 if (Pt
.y
< ScrollBarInfo
->rcScrollBar
.top
+ ArrowSize
)
415 return SCROLL_TOP_ARROW
;
417 if (ScrollBarInfo
->rcScrollBar
.bottom
- ArrowSize
<= Pt
.y
)
419 return SCROLL_BOTTOM_ARROW
;
423 return SCROLL_TOP_RECT
;
425 Pt
.y
-= ScrollBarInfo
->rcScrollBar
.top
;
428 return SCROLL_TOP_RECT
;
430 if (ThumbPos
+ ThumbSize
<= Pt
.y
)
432 return SCROLL_BOTTOM_RECT
;
437 if (Pt
.x
< ScrollBarInfo
->rcScrollBar
.left
+ ArrowSize
)
439 return SCROLL_TOP_ARROW
;
441 if (ScrollBarInfo
->rcScrollBar
.right
- ArrowSize
<= Pt
.x
)
443 return SCROLL_BOTTOM_ARROW
;
447 return SCROLL_TOP_RECT
;
449 Pt
.x
-= ScrollBarInfo
->rcScrollBar
.left
;
452 return SCROLL_TOP_RECT
;
454 if (ThumbPos
+ ThumbSize
<= Pt
.x
)
456 return SCROLL_BOTTOM_RECT
;
464 /***********************************************************************
465 * IntScrollGetScrollBarRect
467 * Compute the scroll bar rectangle, in drawing coordinates (i.e. client
468 * coords for SB_CTL, window coords for SB_VERT and SB_HORZ).
469 * 'arrowSize' returns the width or height of an arrow (depending on
470 * the orientation of the scrollbar), 'thumbSize' returns the size of
471 * the thumb, and 'thumbPos' returns the position of the thumb
472 * relative to the left or to the top.
473 * Return TRUE if the scrollbar is vertical, FALSE if horizontal.
476 IntScrollGetScrollBarRect(HWND Wnd
, INT Bar
, RECT
*Rect
,
477 INT
*ArrowSize
, INT
*ThumbSize
,
484 DWORD Style
, ExStyle
;
486 GetClientRect(Wnd
, &ClientRect
);
487 if (SB_HORZ
== Bar
|| SB_VERT
== Bar
)
489 ClientToScreen(Wnd
, (LPPOINT
) &ClientRect
.left
);
490 ClientToScreen(Wnd
, (LPPOINT
) &ClientRect
.right
);
491 GetWindowRect(Wnd
, &WindowRect
);
493 Style
= GetWindowLongPtrW(Wnd
, GWL_STYLE
);
498 Rect
->left
= ClientRect
.left
- WindowRect
.left
;
499 Rect
->top
= ClientRect
.bottom
- WindowRect
.top
;
500 Rect
->right
= ClientRect
.right
- WindowRect
.left
;
501 Rect
->bottom
= Rect
->top
+ GetSystemMetrics(SM_CYHSCROLL
);
502 if (0 != (Style
& WS_BORDER
))
507 else if (0 != (Style
& WS_VSCROLL
))
515 ExStyle
= GetWindowLongPtrW(Wnd
, GWL_EXSTYLE
);
516 if (0 != (ExStyle
& WS_EX_LEFTSCROLLBAR
))
518 Rect
->left
= ClientRect
.left
- WindowRect
.left
- GetSystemMetrics(SM_CXVSCROLL
);
522 Rect
->left
= ClientRect
.right
- WindowRect
.left
;
524 Rect
->top
= ClientRect
.top
- WindowRect
.top
;
525 Rect
->right
= Rect
->left
+ GetSystemMetrics(SM_CXVSCROLL
);
526 Rect
->bottom
= ClientRect
.bottom
- WindowRect
.top
;
527 if (0 != (Style
& WS_BORDER
))
532 else if (0 != (Style
& WS_HSCROLL
))
541 Vertical
= (0 != (Style
& SBS_VERT
));
550 Pixels
= Rect
->bottom
- Rect
->top
;
554 Pixels
= Rect
->right
- Rect
->left
;
557 if (Pixels
<= 2 * GetSystemMetrics(SM_CXVSCROLL
) + SCROLL_MIN_RECT
)
559 if (SCROLL_MIN_RECT
< Pixels
)
561 *ArrowSize
= (Pixels
- SCROLL_MIN_RECT
) / 2;
567 *ThumbPos
= *ThumbSize
= 0;
573 NtUserSBGetParms(Wnd
, Bar
, NULL
, &Info
);
574 *ArrowSize
= GetSystemMetrics(SM_CXVSCROLL
);
575 Pixels
-= (2 * GetSystemMetrics(SM_CXVSCROLL
));
579 *ThumbSize
= MulDiv(Pixels
, Info
.nPage
, (Info
.nMax
- Info
.nMin
+ 1));
580 if (*ThumbSize
< SCROLL_MIN_THUMB
)
582 *ThumbSize
= SCROLL_MIN_THUMB
;
587 *ThumbSize
= GetSystemMetrics(SM_CXVSCROLL
);
591 if (((pixels
-= *ThumbSize
) < 0) ||
592 ((info
->flags
& ESB_DISABLE_BOTH
) == ESB_DISABLE_BOTH
))
594 if ((Pixels
-= *ThumbSize
) < 0)
597 /* Rectangle too small or scrollbar disabled -> no thumb */
598 *ThumbPos
= *ThumbSize
= 0;
602 INT Max
= Info
.nMax
- max(Info
.nPage
- 1, 0);
603 if (Max
<= Info
.nMin
)
605 *ThumbPos
= *ArrowSize
;
609 *ThumbPos
= *ArrowSize
610 + MulDiv(Pixels
, (Info
.nPos
- Info
.nMin
),
619 /***********************************************************************
620 * IntScrollGetThumbVal
622 * Compute the current scroll position based on the thumb position in pixels
623 * from the top of the scroll-bar.
626 IntScrollGetThumbVal(HWND Wnd
, INT SBType
, PSCROLLBARINFO ScrollBarInfo
,
627 BOOL Vertical
, INT Pos
)
630 INT Pixels
= Vertical
? ScrollBarInfo
->rcScrollBar
.bottom
631 - ScrollBarInfo
->rcScrollBar
.top
632 : ScrollBarInfo
->rcScrollBar
.right
633 - ScrollBarInfo
->rcScrollBar
.left
;
635 si
.cbSize
= sizeof(SCROLLINFO
);
636 si
.fMask
= SIF_RANGE
| SIF_PAGE
;
637 NtUserSBGetParms(Wnd
, SBType
, NULL
, &si
);
638 if ((Pixels
-= 2 * ScrollBarInfo
->dxyLineButton
) <= 0)
643 if ((Pixels
-= (ScrollBarInfo
->xyThumbBottom
- ScrollBarInfo
->xyThumbTop
)) <= 0)
648 Pos
= Pos
- ScrollBarInfo
->dxyLineButton
;
660 Pos
*= si
.nMax
- si
.nMin
;
664 Pos
*= si
.nMax
- si
.nMin
- si
.nPage
+ 1;
666 return si
.nMin
+ ((Pos
+ Pixels
/ 2) / Pixels
);
669 /***********************************************************************
672 static POINT
IntScrollClipPos(PRECT Rect
, POINT Pt
)
674 if (Pt
.x
< Rect
->left
)
678 else if (Rect
->right
< Pt
.x
)
683 if (Pt
.y
< Rect
->top
)
687 else if (Rect
->bottom
< Pt
.y
)
695 /***********************************************************************
696 * IntScrollDrawSizeGrip
698 * Draw the size grip.
701 IntScrollDrawSizeGrip(HWND Wnd
, HDC Dc
)
705 GetClientRect(Wnd
, &Rect
);
706 FillRect(Dc
, &Rect
, GetSysColorBrush(COLOR_SCROLLBAR
));
707 Rect
.left
= max(Rect
.left
, Rect
.right
- GetSystemMetrics(SM_CXVSCROLL
) - 1);
708 Rect
.top
= max(Rect
.top
, Rect
.bottom
- GetSystemMetrics(SM_CYHSCROLL
) - 1);
709 DrawFrameControl(Dc
, &Rect
, DFC_SCROLL
, DFCS_SCROLLSIZEGRIP
);
712 /***********************************************************************
713 * SCROLL_RefreshScrollBar
715 * Repaint the scroll bar interior after a SetScrollRange() or
716 * SetScrollPos() call.
718 static void SCROLL_RefreshScrollBar( HWND hwnd
, INT nBar
,
719 BOOL arrows
, BOOL interior
)
721 HDC hdc
= GetDCEx( hwnd
, 0,
722 DCX_CACHE
| ((nBar
== SB_CTL
) ? 0 : DCX_WINDOW
) );
725 IntDrawScrollBar( hwnd
, hdc
, nBar
);//, arrows, interior );
726 ReleaseDC( hwnd
, hdc
);
730 /***********************************************************************
731 * IntScrollHandleKbdEvent
733 * Handle a keyboard event (only for SB_CTL scrollbars with focus).
736 IntScrollHandleKbdEvent(
737 HWND Wnd
/* [in] Handle of window with scrollbar(s) */,
738 WPARAM wParam
/* [in] Variable input including enable state */,
739 LPARAM lParam
/* [in] Variable input including input point */)
741 TRACE("Wnd=%p wParam=%ld lParam=%ld\n", Wnd
, wParam
, lParam
);
743 /* hide caret on first KEYDOWN to prevent flicker */
744 if (0 == (lParam
& PFD_DOUBLEBUFFER_DONTCARE
))
756 wParam
= SB_PAGEDOWN
;
772 wParam
= SB_LINEDOWN
;
779 SendMessageW(GetParent(Wnd
),
780 (0 != (GetWindowLongPtrW(Wnd
, GWL_STYLE
) & SBS_VERT
) ?
781 WM_VSCROLL
: WM_HSCROLL
), wParam
, (LPARAM
) Wnd
);
784 /***********************************************************************
785 * IntScrollHandleScrollEvent
787 * Handle a mouse or timer event for the scrollbar.
788 * 'Pt' is the location of the mouse event in drawing coordinates
791 IntScrollHandleScrollEvent(HWND Wnd
, INT SBType
, UINT Msg
, POINT Pt
)
793 static POINT PrevPt
; /* Previous mouse position for timer events */
794 static UINT TrackThumbPos
; /* Thumb position when tracking started. */
795 static INT LastClickPos
; /* Position in the scroll-bar of the last
796 button-down event. */
797 static INT LastMousePos
; /* Position in the scroll-bar of the last
801 HWND WndOwner
, WndCtl
;
804 SCROLLBARINFO ScrollBarInfo
;
805 SETSCROLLBARINFO NewInfo
;
807 if (! IntGetScrollBarInfo(Wnd
, SBType
, &ScrollBarInfo
))
811 if (SCROLL_NOWHERE
== ScrollTrackHitTest
&& WM_LBUTTONDOWN
!= Msg
)
816 NewInfo
.nTrackPos
= ScrollTrackingVal
;
817 NewInfo
.reserved
= ScrollBarInfo
.reserved
;
818 memcpy(NewInfo
.rgstate
, ScrollBarInfo
.rgstate
, (CCHILDREN_SCROLLBAR
+ 1) * sizeof(DWORD
));
821 && 0 != (GetWindowLongPtrW(Wnd
, GWL_STYLE
) & (SBS_SIZEGRIP
| SBS_SIZEBOX
)))
825 case WM_LBUTTONDOWN
: /* Initialise mouse tracking */
826 HideCaret(Wnd
); /* hide caret while holding down LBUTTON */
829 ScrollTrackHitTest
= HitTest
= SCROLL_THUMB
;
832 GetClientRect(GetParent(GetParent(Wnd
)), &ScrollBarInfo
.rcScrollBar
);
837 ScrollTrackHitTest
= HitTest
= SCROLL_NOWHERE
;
838 if (Wnd
== GetFocus())
850 Dc
= GetDCEx(Wnd
, 0, DCX_CACHE
| ((SB_CTL
== SBType
) ? 0 : DCX_WINDOW
));
851 if (SB_VERT
== SBType
)
855 else if (SB_HORZ
== SBType
)
861 Vertical
= (0 != (GetWindowLongPtrW(Wnd
, GWL_STYLE
) & SBS_VERT
));
863 WndOwner
= (SB_CTL
== SBType
) ? GetParent(Wnd
) : Wnd
;
864 WndCtl
= (SB_CTL
== SBType
) ? Wnd
: NULL
;
868 case WM_LBUTTONDOWN
: /* Initialise mouse tracking */
869 HideCaret(Wnd
); /* hide caret while holding down LBUTTON */
870 ScrollTrackVertical
= Vertical
;
871 ScrollTrackHitTest
= HitTest
= IntScrollHitTest(&ScrollBarInfo
, Vertical
, Pt
, FALSE
);
872 LastClickPos
= Vertical
? (Pt
.y
- ScrollBarInfo
.rcScrollBar
.top
)
873 : (Pt
.x
- ScrollBarInfo
.rcScrollBar
.left
);
874 LastMousePos
= LastClickPos
;
875 TrackThumbPos
= ScrollBarInfo
.xyThumbTop
;
877 if (SB_CTL
== SBType
&& 0 != (GetWindowLongPtrW(Wnd
, GWL_STYLE
) & WS_TABSTOP
))
882 ScrollBarInfo
.rgstate
[ScrollTrackHitTest
] |= STATE_SYSTEM_PRESSED
;
883 NewInfo
.rgstate
[ScrollTrackHitTest
] = ScrollBarInfo
.rgstate
[ScrollTrackHitTest
];
884 NtUserSetScrollBarInfo(Wnd
, IntScrollGetObjectId(SBType
), &NewInfo
);
888 HitTest
= IntScrollHitTest(&ScrollBarInfo
, Vertical
, Pt
, TRUE
);
893 HitTest
= SCROLL_NOWHERE
;
895 /* if scrollbar has focus, show back caret */
896 if (Wnd
== GetFocus())
900 ScrollBarInfo
.rgstate
[ScrollTrackHitTest
] &= ~STATE_SYSTEM_PRESSED
;
901 NewInfo
.rgstate
[ScrollTrackHitTest
] = ScrollBarInfo
.rgstate
[ScrollTrackHitTest
];
902 NtUserSetScrollBarInfo(Wnd
, IntScrollGetObjectId(SBType
), &NewInfo
);
907 HitTest
= IntScrollHitTest(&ScrollBarInfo
, Vertical
, Pt
, FALSE
);
911 return; /* Should never happen */
914 switch (ScrollTrackHitTest
)
916 case SCROLL_NOWHERE
: /* No tracking in progress */
919 case SCROLL_TOP_ARROW
:
920 if (HitTest
== ScrollTrackHitTest
)
922 if ((WM_LBUTTONDOWN
== Msg
) || (WM_SYSTIMER
== Msg
))
924 SendMessageW(WndOwner
, Vertical
? WM_VSCROLL
: WM_HSCROLL
,
925 SB_LINEUP
, (LPARAM
) WndCtl
);
927 SetSystemTimer(Wnd
, SCROLL_TIMER
, (WM_LBUTTONDOWN
== Msg
) ?
928 SCROLL_FIRST_DELAY
: SCROLL_REPEAT_DELAY
,
933 KillSystemTimer(Wnd
, SCROLL_TIMER
);
937 case SCROLL_TOP_RECT
:
938 if (HitTest
== ScrollTrackHitTest
)
940 if ((WM_LBUTTONDOWN
== Msg
) || (WM_SYSTIMER
== Msg
))
942 SendMessageW(WndOwner
, Vertical
? WM_VSCROLL
: WM_HSCROLL
,
943 SB_PAGEUP
, (LPARAM
) WndCtl
);
945 SetSystemTimer(Wnd
, SCROLL_TIMER
, (WM_LBUTTONDOWN
== Msg
) ?
946 SCROLL_FIRST_DELAY
: SCROLL_REPEAT_DELAY
,
951 KillSystemTimer(Wnd
, SCROLL_TIMER
);
956 if (WM_LBUTTONDOWN
== Msg
)
958 ScrollTrackingWin
= Wnd
;
959 ScrollTrackingBar
= SBType
;
960 ScrollTrackingPos
= TrackThumbPos
+ LastMousePos
- LastClickPos
;
961 ScrollTrackingVal
= IntScrollGetThumbVal(Wnd
, SBType
, &ScrollBarInfo
,
962 Vertical
, ScrollTrackingPos
);
963 NewInfo
.nTrackPos
= ScrollTrackingVal
;
964 NtUserSetScrollBarInfo(Wnd
, IntScrollGetObjectId(SBType
), &NewInfo
);
965 IntScrollDrawMovingThumb(Dc
, &ScrollBarInfo
, Vertical
);
967 else if (WM_LBUTTONUP
== Msg
)
969 ScrollTrackingWin
= 0;
970 ScrollTrackingVal
= 0;
971 IntDrawScrollInterior(Wnd
, Dc
, SBType
, Vertical
, &ScrollBarInfo
);
973 else /* WM_MOUSEMOVE */
977 if (! IntScrollPtInRectEx(&ScrollBarInfo
.rcScrollBar
, Pt
, Vertical
))
983 Pt
= IntScrollClipPos(&ScrollBarInfo
.rcScrollBar
, Pt
);
984 Pos
= Vertical
? (Pt
.y
- ScrollBarInfo
.rcScrollBar
.top
)
985 : (Pt
.x
- ScrollBarInfo
.rcScrollBar
.left
);
987 if (Pos
!= LastMousePos
|| ! ScrollMovingThumb
)
990 ScrollTrackingPos
= TrackThumbPos
+ Pos
- LastClickPos
;
991 ScrollTrackingVal
= IntScrollGetThumbVal(Wnd
, SBType
, &ScrollBarInfo
,
992 Vertical
, ScrollTrackingPos
);
993 NewInfo
.nTrackPos
= ScrollTrackingVal
;
994 NtUserSetScrollBarInfo(Wnd
, IntScrollGetObjectId(SBType
), &NewInfo
);
995 IntScrollDrawMovingThumb(Dc
, &ScrollBarInfo
, Vertical
);
996 SendMessageW(WndOwner
, Vertical
? WM_VSCROLL
: WM_HSCROLL
,
997 MAKEWPARAM(SB_THUMBTRACK
, ScrollTrackingVal
),
1003 case SCROLL_BOTTOM_RECT
:
1004 if (HitTest
== ScrollTrackHitTest
)
1006 if ((WM_LBUTTONDOWN
== Msg
) || (WM_SYSTIMER
== Msg
))
1008 SendMessageW(WndOwner
, Vertical
? WM_VSCROLL
: WM_HSCROLL
,
1009 SB_PAGEDOWN
, (LPARAM
) WndCtl
);
1011 SetSystemTimer(Wnd
, SCROLL_TIMER
, (WM_LBUTTONDOWN
== Msg
) ?
1012 SCROLL_FIRST_DELAY
: SCROLL_REPEAT_DELAY
,
1017 KillSystemTimer(Wnd
, SCROLL_TIMER
);
1021 case SCROLL_BOTTOM_ARROW
:
1022 if (HitTest
== ScrollTrackHitTest
)
1024 if ((WM_LBUTTONDOWN
== Msg
) || (WM_SYSTIMER
== Msg
))
1026 SendMessageW(WndOwner
, Vertical
? WM_VSCROLL
: WM_HSCROLL
,
1027 SB_LINEDOWN
, (LPARAM
) WndCtl
);
1029 SetSystemTimer(Wnd
, SCROLL_TIMER
, (WM_LBUTTONDOWN
== Msg
) ?
1030 SCROLL_FIRST_DELAY
: SCROLL_REPEAT_DELAY
,
1035 KillSystemTimer(Wnd
, SCROLL_TIMER
);
1040 if (WM_LBUTTONDOWN
== Msg
)
1042 if (SCROLL_THUMB
== HitTest
)
1044 UINT Val
= IntScrollGetThumbVal(Wnd
, SBType
, &ScrollBarInfo
, Vertical
,
1045 TrackThumbPos
+ LastMousePos
- LastClickPos
);
1046 SendMessageW(WndOwner
, Vertical
? WM_VSCROLL
: WM_HSCROLL
,
1047 MAKEWPARAM(SB_THUMBTRACK
, Val
), (LPARAM
) WndCtl
);
1051 if (WM_LBUTTONUP
== Msg
)
1053 HitTest
= ScrollTrackHitTest
;
1054 ScrollTrackHitTest
= SCROLL_NOWHERE
; /* Terminate tracking */
1056 if (SCROLL_THUMB
== HitTest
)
1058 UINT Val
= IntScrollGetThumbVal(Wnd
, SBType
, &ScrollBarInfo
, Vertical
,
1059 TrackThumbPos
+ LastMousePos
- LastClickPos
);
1060 SendMessageW(WndOwner
, Vertical
? WM_VSCROLL
: WM_HSCROLL
,
1061 MAKEWPARAM(SB_THUMBPOSITION
, Val
), (LPARAM
) WndCtl
);
1063 SendMessageW(WndOwner
, Vertical
? WM_VSCROLL
: WM_HSCROLL
,
1064 SB_ENDSCROLL
, (LPARAM
) WndCtl
);
1071 /***********************************************************************
1072 * IntScrollCreateScrollBar
1074 * Create a scroll bar
1076 static void IntScrollCreateScrollBar(
1077 HWND Wnd
/* [in] Handle of window with scrollbar(s) */,
1078 LPCREATESTRUCTW lpCreate
/* [in] The style and place of the scroll bar */)
1082 Info
.cbSize
= sizeof(SCROLLINFO
);
1083 Info
.fMask
= SIF_RANGE
| SIF_PAGE
| SIF_POS
;
1089 NtUserSetScrollInfo(Wnd
, SB_CTL
, &Info
, FALSE
);
1091 TRACE("hwnd=%p lpCreate=%p\n", Wnd
, lpCreate
);
1094 if (lpCreate
->style
& WS_DISABLED
)
1096 info
->flags
= ESB_DISABLE_BOTH
;
1097 TRACE("Created WS_DISABLED scrollbar\n");
1101 if (0 != (lpCreate
->style
& (SBS_SIZEGRIP
| SBS_SIZEBOX
)))
1103 if (0 != (lpCreate
->style
& SBS_SIZEBOXTOPLEFTALIGN
))
1105 MoveWindow(Wnd
, lpCreate
->x
, lpCreate
->y
, GetSystemMetrics(SM_CXVSCROLL
) + 1,
1106 GetSystemMetrics(SM_CYHSCROLL
) + 1, FALSE
);
1108 else if (0 != (lpCreate
->style
& SBS_SIZEBOXBOTTOMRIGHTALIGN
))
1110 MoveWindow(Wnd
, lpCreate
->x
+ lpCreate
->cx
- GetSystemMetrics(SM_CXVSCROLL
) - 1,
1111 lpCreate
->y
+ lpCreate
->cy
- GetSystemMetrics(SM_CYHSCROLL
) - 1,
1112 GetSystemMetrics(SM_CXVSCROLL
) + 1,
1113 GetSystemMetrics(SM_CYHSCROLL
) + 1, FALSE
);
1116 else if (0 != (lpCreate
->style
& SBS_VERT
))
1118 if (0 != (lpCreate
->style
& SBS_LEFTALIGN
))
1120 MoveWindow(Wnd
, lpCreate
->x
, lpCreate
->y
,
1121 GetSystemMetrics(SM_CXVSCROLL
) + 1, lpCreate
->cy
, FALSE
);
1123 else if (0 != (lpCreate
->style
& SBS_RIGHTALIGN
))
1126 lpCreate
->x
+ lpCreate
->cx
- GetSystemMetrics(SM_CXVSCROLL
) - 1,
1128 GetSystemMetrics(SM_CXVSCROLL
) + 1, lpCreate
->cy
, FALSE
);
1133 if (0 != (lpCreate
->style
& SBS_TOPALIGN
))
1135 MoveWindow(Wnd
, lpCreate
->x
, lpCreate
->y
,
1136 lpCreate
->cx
, GetSystemMetrics(SM_CYHSCROLL
) + 1, FALSE
);
1138 else if (0 != (lpCreate
->style
& SBS_BOTTOMALIGN
))
1142 lpCreate
->y
+ lpCreate
->cy
- GetSystemMetrics(SM_CYHSCROLL
) - 1,
1143 lpCreate
->cx
, GetSystemMetrics(SM_CYHSCROLL
) + 1, FALSE
);
1149 IntScrollGetScrollPos(HWND Wnd
, INT Bar
)
1151 SCROLLINFO ScrollInfo
;
1153 ScrollInfo
.cbSize
= sizeof(SCROLLINFO
);
1154 ScrollInfo
.fMask
= SIF_POS
;
1155 if (! NtUserSBGetParms(Wnd
, Bar
, NULL
, &ScrollInfo
))
1160 return ScrollInfo
.nPos
;
1163 static BOOL FASTCALL
1164 IntScrollGetScrollRange(HWND Wnd
, int Bar
, LPINT MinPos
, LPINT MaxPos
)
1167 SCROLLINFO ScrollInfo
;
1169 if (NULL
== MinPos
|| NULL
== MaxPos
)
1171 SetLastError(ERROR_INVALID_PARAMETER
);
1175 ScrollInfo
.cbSize
= sizeof(SCROLLINFO
);
1176 ScrollInfo
.fMask
= SIF_RANGE
;
1177 Result
= NtUserSBGetParms(Wnd
, Bar
, NULL
, &ScrollInfo
);
1180 *MinPos
= ScrollInfo
.nMin
;
1181 *MaxPos
= ScrollInfo
.nMax
;
1187 /* USER32 INTERNAL FUNCTIONS **************************************************/
1189 /***********************************************************************
1190 * ScrollTrackScrollBar
1192 * Track a mouse button press on a scroll-bar.
1193 * pt is in screen-coordinates for non-client scroll bars.
1196 ScrollTrackScrollBar(HWND Wnd
, INT SBType
, POINT Pt
)
1200 UINT XOffset
, YOffset
;
1203 if (SB_CTL
!= SBType
)
1205 GetWindowRect(Wnd
, &WindowRect
);
1207 Pt
.x
-= WindowRect
.left
;
1208 Pt
.y
-= WindowRect
.top
;
1210 TopLeft
.x
= WindowRect
.left
;
1211 TopLeft
.y
= WindowRect
.top
;
1212 ScreenToClient(Wnd
, &TopLeft
);
1213 XOffset
= - TopLeft
.x
;
1214 YOffset
= - TopLeft
.y
;
1222 IntScrollHandleScrollEvent(Wnd
, SBType
, WM_LBUTTONDOWN
, Pt
);
1226 if (! GetMessageW(&Msg
, 0, 0, 0))
1230 if (CallMsgFilterW(&Msg
, MSGF_SCROLLBAR
))
1240 Pt
.x
= LOWORD(Msg
.lParam
) + XOffset
;
1241 Pt
.y
= HIWORD(Msg
.lParam
) + YOffset
;
1242 IntScrollHandleScrollEvent(Wnd
, SBType
, Msg
.message
, Pt
);
1245 TranslateMessage(&Msg
);
1246 DispatchMessageW(&Msg
);
1250 if (! IsWindow(Wnd
))
1256 while (WM_LBUTTONUP
!= Msg
.message
);
1260 /***********************************************************************
1264 ScrollBarWndProc(WNDPROC DefWindowProc
, HWND Wnd
, UINT Msg
, WPARAM wParam
, LPARAM lParam
)
1266 if (! IsWindow(Wnd
))
1274 IntScrollCreateScrollBar(Wnd
, (LPCREATESTRUCTW
) lParam
);
1280 // SCROLLBAR_INFO *infoPtr;
1281 // if ((infoPtr = SCROLL_GetScrollBarInfo( hwnd, SB_CTL )))
1283 // infoPtr->flags = wParam ? ESB_ENABLE_BOTH : ESB_DISABLE_BOTH;
1284 // SCROLL_RefreshScrollBar(hwnd, SB_CTL, TRUE, TRUE);
1287 DbgPrint("ScrollBarWndProc WM_ENABLE\n");
1288 NtUserEnableScrollBar(Wnd
,SB_CTL
,(wParam
? ESB_ENABLE_BOTH
: ESB_DISABLE_BOTH
));
1289 /* Refresh Scrollbars. */
1290 hdc
= GetDCEx( Wnd
, 0, DCX_CACHE
);
1292 IntDrawScrollBar( Wnd
, hdc
, SB_CTL
);
1293 ReleaseDC( Wnd
, hdc
);
1298 case WM_LBUTTONDBLCLK
:
1299 case WM_LBUTTONDOWN
:
1303 Pt
.x
= (short)LOWORD(lParam
);
1304 Pt
.y
= (short)HIWORD(lParam
);
1305 ScrollTrackScrollBar(Wnd
, SB_CTL
, Pt
);
1315 Pt
.x
= (short)LOWORD(lParam
);
1316 Pt
.y
= (short)HIWORD(lParam
);
1317 IntScrollHandleScrollEvent(Wnd
, SB_CTL
, Msg
, Pt
);
1322 IntScrollHandleKbdEvent(Wnd
, wParam
, lParam
);
1331 /* Create a caret when a ScrollBar get focus */
1333 int ArrowSize
, ThumbSize
, ThumbPos
, Vertical
;
1335 Vertical
= IntScrollGetScrollBarRect(Wnd
, SB_CTL
, &Rect
,
1336 &ArrowSize
, &ThumbSize
, &ThumbPos
);
1339 CreateCaret(Wnd
, (HBITMAP
) 1, ThumbSize
- 2, Rect
.bottom
- Rect
.top
- 2);
1340 SetCaretPos(ThumbPos
+ 1, Rect
.top
+ 1);
1344 CreateCaret(Wnd
, (HBITMAP
) 1, Rect
.right
- Rect
.left
- 2, ThumbSize
- 2);
1345 SetCaretPos(Rect
.top
+ 1, ThumbPos
+ 1);
1354 int ArrowSize
, ThumbSize
, ThumbPos
, Vertical
;
1356 Vertical
= IntScrollGetScrollBarRect(Wnd
, SB_CTL
, &Rect
,
1357 &ArrowSize
, &ThumbSize
, &ThumbPos
);
1360 Rect
.left
= ThumbPos
+ 1;
1361 Rect
.right
= Rect
.left
+ ThumbSize
;
1365 Rect
.top
= ThumbPos
+ 1;
1366 Rect
.bottom
= Rect
.top
+ ThumbSize
;
1369 InvalidateRect(Wnd
, &Rect
, FALSE
);
1378 return DLGC_WANTARROWS
; /* Windows returns this value */
1385 Dc
= (0 != wParam
? (HDC
) wParam
: BeginPaint(Wnd
, &Ps
));
1387 if (GetWindowLongPtrW(Wnd
, GWL_STYLE
) & SBS_SIZEGRIP
)
1389 IntScrollDrawSizeGrip(Wnd
, Dc
);
1391 else if (0 != (GetWindowLongPtrW(Wnd
, GWL_STYLE
) & SBS_SIZEBOX
))
1394 GetClientRect(Wnd
, &Rect
);
1395 FillRect(Dc
, &Rect
, GetSysColorBrush(COLOR_SCROLLBAR
));
1399 IntDrawScrollBar(Wnd
, Dc
, SB_CTL
/*, TRUE, TRUE*/);
1410 return SetScrollPos(Wnd
, SB_CTL
, wParam
, (BOOL
) lParam
);
1413 return IntScrollGetScrollPos(Wnd
, SB_CTL
);
1415 case SBM_SETRANGEREDRAW
:
1418 INT OldPos
= IntScrollGetScrollPos(Wnd
, SB_CTL
);
1419 SetScrollRange(Wnd
, SB_CTL
, wParam
, lParam
, FALSE
);
1420 if (Msg
== SBM_SETRANGEREDRAW
)
1421 SCROLL_RefreshScrollBar( Wnd
, SB_CTL
, TRUE
, TRUE
);
1422 if (OldPos
!= IntScrollGetScrollPos(Wnd
, SB_CTL
)) return OldPos
;
1427 return IntScrollGetScrollRange(Wnd
, SB_CTL
, (LPINT
) wParam
, (LPINT
) lParam
);
1429 case SBM_ENABLE_ARROWS
:
1430 return EnableScrollBar(Wnd
, SB_CTL
, wParam
);
1432 case SBM_SETSCROLLINFO
:
1433 return NtUserSetScrollInfo(Wnd
, SB_CTL
, (SCROLLINFO
*) lParam
, wParam
);
1435 case SBM_GETSCROLLINFO
:
1436 return NtUserSBGetParms(Wnd
, SB_CTL
, NULL
, (SCROLLINFO
*) lParam
);
1438 case SBM_GETSCROLLBARINFO
:
1439 ((PSCROLLBARINFO
)lParam
)->cbSize
= sizeof(SCROLLBARINFO
);
1440 return NtUserGetScrollBarInfo(Wnd
, OBJID_CLIENT
, (PSCROLLBARINFO
)lParam
);
1449 WARN("unknown Win32 msg %04x wp=%08lx lp=%08lx\n",
1450 Msg
, wParam
, lParam
);
1456 WARN("unknown msg %04x wp=%04lx lp=%08lx\n", Msg
, wParam
, lParam
);
1458 return DefWindowProc(Wnd
, Msg
, wParam
, lParam
);
1465 ScrollBarWndProcW(HWND Wnd
, UINT Msg
, WPARAM wParam
, LPARAM lParam
)
1467 return ScrollBarWndProc(DefWindowProcW
, Wnd
, Msg
, wParam
, lParam
);
1471 ScrollBarWndProcA(HWND Wnd
, UINT Msg
, WPARAM wParam
, LPARAM lParam
)
1473 return ScrollBarWndProc(DefWindowProcA
, Wnd
, Msg
, wParam
, lParam
);
1477 /* PUBLIC FUNCTIONS ***********************************************************/
1482 BOOL WINAPI
EnableScrollBar( HWND hwnd
, UINT nBar
, UINT flags
)
1484 BOOL Hook
, Ret
= FALSE
;
1488 Hook
= BeginIfHookedUserApiHook();
1490 /* Bypass SEH and go direct. */
1491 if (!Hook
) return NtUserEnableScrollBar(hwnd
, nBar
, flags
);
1495 Ret
= guah
.EnableScrollBar(hwnd
, nBar
, flags
);
1497 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1508 RealGetScrollInfo(HWND Wnd
, INT SBType
, LPSCROLLINFO Info
)
1511 PSBDATA pSBData
= NULL
;
1513 if (SB_CTL
== SBType
)
1515 return SendMessageW(Wnd
, SBM_GETSCROLLINFO
, 0, (LPARAM
) Info
);
1518 pWnd
= ValidateHwnd(Wnd
);
1519 if (!pWnd
) return FALSE
;
1521 if (SBType
< SB_HORZ
|| SBType
> SB_VERT
)
1523 SetLastError(ERROR_INVALID_PARAMETER
);
1526 // FIXME add support to set pSBData from pWnd->pSBInfo
1527 return NtUserSBGetParms(Wnd
, SBType
, pSBData
, Info
);
1534 GetScrollInfo(HWND Wnd
, INT SBType
, LPSCROLLINFO Info
)
1536 BOOL Hook
, Ret
= FALSE
;
1540 Hook
= BeginIfHookedUserApiHook();
1542 /* Bypass SEH and go direct. */
1543 if (!Hook
) return RealGetScrollInfo(Wnd
, SBType
, Info
);
1547 Ret
= guah
.GetScrollInfo(Wnd
, SBType
, Info
);
1549 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1563 GetScrollPos(HWND Wnd
, INT Bar
)
1565 TRACE("Wnd=%p Bar=%d\n", Wnd
, Bar
);
1567 /* Refer SB_CTL requests to the window */
1570 return SendMessageW(Wnd
, SBM_GETPOS
, (WPARAM
) 0, (LPARAM
) 0);
1574 return IntScrollGetScrollPos(Wnd
, Bar
);
1582 GetScrollRange(HWND Wnd
, int Bar
, LPINT MinPos
, LPINT MaxPos
)
1584 TRACE("Wnd=%x Bar=%d Min=%p Max=%p\n", Wnd
, Bar
, MinPos
, MaxPos
);
1586 /* Refer SB_CTL requests to the window */
1589 return SendMessageW(Wnd
, SBM_GETRANGE
, (WPARAM
) MinPos
, (LPARAM
) MaxPos
);
1593 return IntScrollGetScrollRange(Wnd
, Bar
, MinPos
, MaxPos
);
1598 RealSetScrollInfo(HWND Wnd
, int SBType
, LPCSCROLLINFO Info
, BOOL bRedraw
)
1600 if (SB_CTL
== SBType
)
1602 return SendMessageW(Wnd
, SBM_SETSCROLLINFO
, (WPARAM
) bRedraw
, (LPARAM
) Info
);
1606 return NtUserSetScrollInfo(Wnd
, SBType
, Info
, bRedraw
);
1614 SetScrollInfo(HWND Wnd
, int SBType
, LPCSCROLLINFO Info
, BOOL bRedraw
)
1621 Hook
= BeginIfHookedUserApiHook();
1623 /* Bypass SEH and go direct. */
1624 if (!Hook
) return RealSetScrollInfo(Wnd
, SBType
, Info
, bRedraw
);
1628 Ret
= guah
.SetScrollInfo(Wnd
, SBType
, Info
, bRedraw
);
1630 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1645 SetScrollPos(HWND hWnd
, INT nBar
, INT nPos
, BOOL bRedraw
)
1648 SCROLLINFO ScrollInfo
;
1650 ScrollInfo
.cbSize
= sizeof(SCROLLINFO
);
1651 ScrollInfo
.fMask
= SIF_POS
;
1654 * Call NtUserSBGetParms() to get the previous position that
1655 * we will later return.
1657 if (NtUserSBGetParms(hWnd
, nBar
, NULL
, &ScrollInfo
))
1659 Result
= ScrollInfo
.nPos
;
1662 ScrollInfo
.nPos
= nPos
;
1663 /* Finally set the new position */
1664 NtUserSetScrollInfo(hWnd
, nBar
, &ScrollInfo
, bRedraw
);
1675 SetScrollRange(HWND hWnd
, INT nBar
, INT nMinPos
, INT nMaxPos
, BOOL bRedraw
)
1677 SCROLLINFO ScrollInfo
;
1679 ScrollInfo
.cbSize
= sizeof(SCROLLINFO
);
1680 ScrollInfo
.fMask
= SIF_RANGE
;
1681 ScrollInfo
.nMin
= nMinPos
;
1682 ScrollInfo
.nMax
= nMaxPos
;
1683 NtUserSetScrollInfo(hWnd
, nBar
, &ScrollInfo
, bRedraw
);