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 Library General Public
17 * License as published by the Free Software Foundation; either
18 * version 2 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 * Library General Public License for more details.
25 * You should have received a copy of the GNU Library General Public
26 * License along with this library; see the file COPYING.LIB.
27 * If not, write to the Free Software Foundation,
28 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31 /* INCLUDES *******************************************************************/
35 #include <wine/debug.h>
36 WINE_DEFAULT_DEBUG_CHANNEL(scrollbar
);
38 /* GLOBAL VARIABLES ***********************************************************/
40 /* Definitions for scrollbar hit testing [See SCROLLBARINFO in MSDN] */
41 #define SCROLL_NOWHERE 0x00 /* Outside the scroll bar */
42 #define SCROLL_TOP_ARROW 0x01 /* Top or left arrow */
43 #define SCROLL_TOP_RECT 0x02 /* Rectangle between the top arrow and the thumb */
44 #define SCROLL_THUMB 0x03 /* Thumb rectangle */
45 #define SCROLL_BOTTOM_RECT 0x04 /* Rectangle between the thumb and the bottom arrow */
46 #define SCROLL_BOTTOM_ARROW 0x05 /* Bottom or right arrow */
48 #define SCROLL_FIRST_DELAY 200 /* Delay (in ms) before first repetition when
49 holding the button down */
50 #define SCROLL_REPEAT_DELAY 50 /* Delay (in ms) between scroll repetitions */
52 #define SCROLL_TIMER 0 /* Scroll timer id */
54 /* Minimum size of the rectangle between the arrows */
55 #define SCROLL_MIN_RECT 4
57 /* Minimum size of the thumb in pixels */
58 #define SCROLL_MIN_THUMB 6
60 /* Thumb-tracking info */
61 static HWND ScrollTrackingWin
= 0;
62 static INT ScrollTrackingBar
= 0;
63 static INT ScrollTrackingPos
= 0;
64 static INT ScrollTrackingVal
= 0;
65 static BOOL ScrollMovingThumb
= FALSE
;
67 static DWORD ScrollTrackHitTest
= SCROLL_NOWHERE
;
68 static BOOL ScrollTrackVertical
;
70 HBRUSH
DefWndControlColor(HDC hDC
, UINT ctlType
);
72 static LRESULT WINAPI
ScrollBarWndProc( HWND hwnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
);
74 UINT STDCALL
SetSystemTimer(HWND
,UINT_PTR
,UINT
,TIMERPROC
);
75 BOOL STDCALL
KillSystemTimer(HWND
,UINT_PTR
);
77 /*********************************************************************
78 * scrollbar class descriptor
80 const struct builtin_class_descr SCROLL_builtin_class
=
82 L
"ScrollBar", /* name */
83 CS_DBLCLKS
| CS_VREDRAW
| CS_HREDRAW
| CS_PARENTDC
, /* style */
84 ScrollBarWndProc
, /* procW */
85 NULL
, /* procA (winproc is Unicode only) */
87 IDC_ARROW
, /* cursor */
91 /* PRIVATE FUNCTIONS **********************************************************/
95 IntDrawScrollInterior(HWND hWnd
, HDC hDC
, INT nBar
, BOOL Vertical
,
96 PSCROLLBARINFO ScrollBarInfo
)
98 INT ThumbSize
= ScrollBarInfo
->xyThumbBottom
- ScrollBarInfo
->xyThumbTop
;
99 INT ThumbTop
= ScrollBarInfo
->xyThumbTop
;
102 HBRUSH hSaveBrush
, hBrush
;
103 BOOL TopSelected
= FALSE
, BottomSelected
= FALSE
;
105 if (ScrollBarInfo
->rgstate
[SCROLL_TOP_RECT
] & STATE_SYSTEM_PRESSED
)
107 if (ScrollBarInfo
->rgstate
[SCROLL_BOTTOM_RECT
] & STATE_SYSTEM_PRESSED
)
108 BottomSelected
= TRUE
;
111 * Only scrollbar controls send WM_CTLCOLORSCROLLBAR.
112 * The window-owned scrollbars need to call DefWndControlColor
113 * to correctly setup default scrollbar colors
117 hBrush
= (HBRUSH
)SendMessageW(GetParent(hWnd
), WM_CTLCOLORSCROLLBAR
, (WPARAM
)hDC
, (LPARAM
)hWnd
);
119 hBrush
= GetSysColorBrush(COLOR_SCROLLBAR
);
123 hBrush
= DefWndControlColor(hDC
, CTLCOLOR_SCROLLBAR
);
126 hSavePen
= SelectObject(hDC
, GetSysColorPen(COLOR_WINDOWFRAME
));
127 hSaveBrush
= SelectObject(hDC
, hBrush
);
129 /* Calculate the scroll rectangle */
132 Rect
.top
= ScrollBarInfo
->rcScrollBar
.top
+ ScrollBarInfo
->dxyLineButton
;
133 Rect
.bottom
= ScrollBarInfo
->rcScrollBar
.bottom
- ScrollBarInfo
->dxyLineButton
;
134 Rect
.left
= ScrollBarInfo
->rcScrollBar
.left
;
135 Rect
.right
= ScrollBarInfo
->rcScrollBar
.right
;
139 Rect
.top
= ScrollBarInfo
->rcScrollBar
.top
;
140 Rect
.bottom
= ScrollBarInfo
->rcScrollBar
.bottom
;
141 Rect
.left
= ScrollBarInfo
->rcScrollBar
.left
+ ScrollBarInfo
->dxyLineButton
;
142 Rect
.right
= ScrollBarInfo
->rcScrollBar
.right
- ScrollBarInfo
->dxyLineButton
;
145 /* Draw the scroll rectangles and thumb */
146 if (!ScrollBarInfo
->xyThumbBottom
)
148 PatBlt(hDC
, Rect
.left
, Rect
.top
, Rect
.right
- Rect
.left
,
149 Rect
.bottom
- Rect
.top
, PATCOPY
);
151 /* Cleanup and return */
152 SelectObject(hDC
, hSavePen
);
153 SelectObject(hDC
, hSaveBrush
);
157 ThumbTop
-= ScrollBarInfo
->dxyLineButton
;
159 if (ScrollBarInfo
->dxyLineButton
)
165 PatBlt(hDC
, Rect
.left
, Rect
.top
, Rect
.right
- Rect
.left
,
166 ThumbTop
, TopSelected
? BLACKNESS
: PATCOPY
);
167 Rect
.top
+= ThumbTop
;
168 PatBlt(hDC
, Rect
.left
, Rect
.top
+ ThumbSize
, Rect
.right
- Rect
.left
,
169 Rect
.bottom
- Rect
.top
- ThumbSize
, BottomSelected
? BLACKNESS
: PATCOPY
);
170 Rect
.bottom
= Rect
.top
+ ThumbSize
;
176 PatBlt(hDC
, Rect
.left
, ScrollBarInfo
->dxyLineButton
,
177 Rect
.right
- Rect
.left
, Rect
.bottom
- Rect
.top
, PATCOPY
);
185 PatBlt(hDC
, Rect
.left
, Rect
.top
, ThumbTop
,
186 Rect
.bottom
- Rect
.top
, TopSelected
? BLACKNESS
: PATCOPY
);
187 Rect
.left
+= ThumbTop
;
188 PatBlt(hDC
, Rect
.left
+ ThumbSize
, Rect
.top
,
189 Rect
.right
- Rect
.left
- ThumbSize
, Rect
.bottom
- Rect
.top
,
190 BottomSelected
? BLACKNESS
: PATCOPY
);
191 Rect
.right
= Rect
.left
+ ThumbSize
;
197 PatBlt(hDC
, ScrollBarInfo
->dxyLineButton
, Rect
.top
,
198 Rect
.right
- Rect
.left
, Rect
.bottom
- Rect
.top
, PATCOPY
);
206 DrawEdge(hDC
, &Rect
, EDGE_RAISED
, BF_RECT
| BF_MIDDLE
);
209 SelectObject(hDC
, hSavePen
);
210 SelectObject(hDC
, hSaveBrush
);
214 IntDrawScrollArrows(HDC hDC
, PSCROLLBARINFO ScrollBarInfo
, BOOL Vertical
)
217 INT ScrollDirFlagLT
, ScrollDirFlagRB
;
219 RectLT
= RectRB
= ScrollBarInfo
->rcScrollBar
;
222 ScrollDirFlagLT
= DFCS_SCROLLUP
;
223 ScrollDirFlagRB
= DFCS_SCROLLDOWN
;
224 RectLT
.bottom
= RectLT
.top
+ ScrollBarInfo
->dxyLineButton
;
225 RectRB
.top
= RectRB
.bottom
- ScrollBarInfo
->dxyLineButton
;
229 ScrollDirFlagLT
= DFCS_SCROLLLEFT
;
230 ScrollDirFlagRB
= DFCS_SCROLLRIGHT
;
231 RectLT
.right
= RectLT
.left
+ ScrollBarInfo
->dxyLineButton
;
232 RectRB
.left
= RectRB
.right
- ScrollBarInfo
->dxyLineButton
;
235 if (ScrollBarInfo
->rgstate
[SCROLL_TOP_ARROW
] & STATE_SYSTEM_PRESSED
)
237 ScrollDirFlagLT
|= DFCS_PUSHED
| DFCS_FLAT
;
239 if (ScrollBarInfo
->rgstate
[SCROLL_TOP_ARROW
] & STATE_SYSTEM_UNAVAILABLE
)
241 ScrollDirFlagLT
|= DFCS_INACTIVE
;
243 if (ScrollBarInfo
->rgstate
[SCROLL_BOTTOM_ARROW
] & STATE_SYSTEM_PRESSED
)
245 ScrollDirFlagRB
|= DFCS_PUSHED
| DFCS_FLAT
;
247 if (ScrollBarInfo
->rgstate
[SCROLL_BOTTOM_ARROW
] & STATE_SYSTEM_UNAVAILABLE
)
249 ScrollDirFlagRB
|= DFCS_INACTIVE
;
252 DrawFrameControl(hDC
, &RectLT
, DFC_SCROLL
, ScrollDirFlagLT
);
253 DrawFrameControl(hDC
, &RectRB
, DFC_SCROLL
, ScrollDirFlagRB
);
257 IntScrollDrawMovingThumb(HDC Dc
, PSCROLLBARINFO ScrollBarInfo
, BOOL Vertical
)
259 INT Pos
= ScrollTrackingPos
;
265 MaxSize
= ScrollBarInfo
->rcScrollBar
.bottom
- ScrollBarInfo
->rcScrollBar
.top
;
269 MaxSize
= ScrollBarInfo
->rcScrollBar
.right
- ScrollBarInfo
->rcScrollBar
.left
;
272 MaxSize
-= ScrollBarInfo
->dxyLineButton
+ ScrollBarInfo
->xyThumbBottom
273 - ScrollBarInfo
->xyThumbTop
;
275 if (Pos
< ScrollBarInfo
->dxyLineButton
)
277 Pos
= ScrollBarInfo
->dxyLineButton
;
279 else if (MaxSize
< Pos
)
284 OldTop
= ScrollBarInfo
->xyThumbTop
;
285 ScrollBarInfo
->xyThumbBottom
= Pos
+ ScrollBarInfo
->xyThumbBottom
- ScrollBarInfo
->xyThumbTop
;
286 ScrollBarInfo
->xyThumbTop
= Pos
;
287 IntDrawScrollInterior(ScrollTrackingWin
, Dc
, ScrollTrackingBar
, Vertical
, ScrollBarInfo
);
288 ScrollBarInfo
->xyThumbBottom
= OldTop
+ ScrollBarInfo
->xyThumbBottom
- ScrollBarInfo
->xyThumbTop
;
289 ScrollBarInfo
->xyThumbTop
= OldTop
;
291 ScrollMovingThumb
= ! ScrollMovingThumb
;
295 IntScrollGetObjectId(INT SBType
)
297 if (SB_VERT
== SBType
)
299 return OBJID_VSCROLL
;
301 if (SB_HORZ
== SBType
)
303 return OBJID_HSCROLL
;
310 IntGetScrollBarInfo(HWND Wnd
, INT Bar
, PSCROLLBARINFO ScrollBarInfo
)
312 ScrollBarInfo
->cbSize
= sizeof(SCROLLBARINFO
);
314 return NtUserGetScrollBarInfo(Wnd
, IntScrollGetObjectId(Bar
), ScrollBarInfo
);
318 IntDrawScrollBar(HWND Wnd
, HDC DC
, INT Bar
)
325 * Get scroll bar info.
338 Vertical
= (GetWindowLongW(Wnd
, GWL_STYLE
) & SBS_VERT
) != 0;
344 if (! IntGetScrollBarInfo(Wnd
, Bar
, &Info
))
349 if (IsRectEmpty(&Info
.rcScrollBar
))
354 ThumbSize
= Info
.xyThumbBottom
- Info
.xyThumbTop
;
359 if (Info
.dxyLineButton
)
361 IntDrawScrollArrows(DC
, &Info
, Vertical
);
367 IntDrawScrollInterior(Wnd
, DC
, Bar
, Vertical
, &Info
);
370 * If scroll bar has focus, reposition the caret.
372 if (Wnd
== GetFocus() && SB_CTL
== Bar
)
376 SetCaretPos(Info
.rcScrollBar
.top
+ 1, Info
.dxyLineButton
+ 1);
380 SetCaretPos(Info
.dxyLineButton
+ 1, Info
.rcScrollBar
.top
+ 1);
386 IntScrollPtInRectEx(LPRECT Rect
, POINT Pt
, BOOL Vertical
)
388 RECT TempRect
= *Rect
;
391 TempRect
.left
-= Rect
->right
- Rect
->left
;
392 TempRect
.right
+= Rect
->right
- Rect
->left
;
396 TempRect
.top
-= Rect
->bottom
- Rect
->top
;
397 TempRect
.bottom
+= Rect
->bottom
- Rect
->top
;
400 return PtInRect(&TempRect
, Pt
);
403 static DWORD FASTCALL
404 IntScrollHitTest(PSCROLLBARINFO ScrollBarInfo
, BOOL Vertical
, POINT Pt
, BOOL Dragging
)
406 INT ArrowSize
, ThumbSize
, ThumbPos
;
408 if ((Dragging
&& ! IntScrollPtInRectEx(&ScrollBarInfo
->rcScrollBar
, Pt
, Vertical
)) ||
409 ! PtInRect(&ScrollBarInfo
->rcScrollBar
, Pt
))
411 return SCROLL_NOWHERE
;
414 ThumbPos
= ScrollBarInfo
->xyThumbTop
;
415 ThumbSize
= ScrollBarInfo
->xyThumbBottom
- ThumbPos
;
416 ArrowSize
= ScrollBarInfo
->dxyLineButton
;
420 if (Pt
.y
< ScrollBarInfo
->rcScrollBar
.top
+ ArrowSize
)
422 return SCROLL_TOP_ARROW
;
424 if (ScrollBarInfo
->rcScrollBar
.bottom
- ArrowSize
<= Pt
.y
)
426 return SCROLL_BOTTOM_ARROW
;
430 return SCROLL_TOP_RECT
;
432 Pt
.y
-= ScrollBarInfo
->rcScrollBar
.top
;
435 return SCROLL_TOP_RECT
;
437 if (ThumbPos
+ ThumbSize
<= Pt
.y
)
439 return SCROLL_BOTTOM_RECT
;
444 if (Pt
.x
< ScrollBarInfo
->rcScrollBar
.left
+ ArrowSize
)
446 return SCROLL_TOP_ARROW
;
448 if (ScrollBarInfo
->rcScrollBar
.right
- ArrowSize
<= Pt
.x
)
450 return SCROLL_BOTTOM_ARROW
;
454 return SCROLL_TOP_RECT
;
456 Pt
.x
-= ScrollBarInfo
->rcScrollBar
.left
;
459 return SCROLL_TOP_RECT
;
461 if (ThumbPos
+ ThumbSize
<= Pt
.x
)
463 return SCROLL_BOTTOM_RECT
;
471 /***********************************************************************
472 * IntScrollGetScrollBarRect
474 * Compute the scroll bar rectangle, in drawing coordinates (i.e. client
475 * coords for SB_CTL, window coords for SB_VERT and SB_HORZ).
476 * 'arrowSize' returns the width or height of an arrow (depending on
477 * the orientation of the scrollbar), 'thumbSize' returns the size of
478 * the thumb, and 'thumbPos' returns the position of the thumb
479 * relative to the left or to the top.
480 * Return TRUE if the scrollbar is vertical, FALSE if horizontal.
483 IntScrollGetScrollBarRect(HWND Wnd
, INT Bar
, RECT
*Rect
,
484 INT
*ArrowSize
, INT
*ThumbSize
,
491 DWORD Style
, ExStyle
;
493 GetClientRect(Wnd
, &ClientRect
);
494 if (SB_HORZ
== Bar
|| SB_VERT
== Bar
)
496 ClientToScreen(Wnd
, (LPPOINT
) &ClientRect
.left
);
497 ClientToScreen(Wnd
, (LPPOINT
) &ClientRect
.right
);
498 GetWindowRect(Wnd
, &WindowRect
);
500 Style
= GetWindowLongW(Wnd
, GWL_STYLE
);
505 Rect
->left
= ClientRect
.left
- WindowRect
.left
;
506 Rect
->top
= ClientRect
.bottom
- WindowRect
.top
;
507 Rect
->right
= ClientRect
.right
- WindowRect
.left
;
508 Rect
->bottom
= Rect
->top
+ GetSystemMetrics(SM_CYHSCROLL
);
509 if (0 != (Style
& WS_BORDER
))
514 else if (0 != (Style
& WS_VSCROLL
))
522 ExStyle
= GetWindowLongW(Wnd
, GWL_EXSTYLE
);
523 if (0 != (ExStyle
& WS_EX_LEFTSCROLLBAR
))
525 Rect
->left
= ClientRect
.left
- WindowRect
.left
- GetSystemMetrics(SM_CXVSCROLL
);
529 Rect
->left
= ClientRect
.right
- WindowRect
.left
;
531 Rect
->top
= ClientRect
.top
- WindowRect
.top
;
532 Rect
->right
= Rect
->left
+ GetSystemMetrics(SM_CXVSCROLL
);
533 Rect
->bottom
= ClientRect
.bottom
- WindowRect
.top
;
534 if (0 != (Style
& WS_BORDER
))
539 else if (0 != (Style
& WS_HSCROLL
))
548 Vertical
= (0 != (Style
& SBS_VERT
));
557 Pixels
= Rect
->bottom
- Rect
->top
;
561 Pixels
= Rect
->right
- Rect
->left
;
564 if (Pixels
<= 2 * GetSystemMetrics(SM_CXVSCROLL
) + SCROLL_MIN_RECT
)
566 if (SCROLL_MIN_RECT
< Pixels
)
568 *ArrowSize
= (Pixels
- SCROLL_MIN_RECT
) / 2;
574 *ThumbPos
= *ThumbSize
= 0;
580 NtUserGetScrollInfo(Wnd
, Bar
, &Info
);
581 *ArrowSize
= GetSystemMetrics(SM_CXVSCROLL
);
582 Pixels
-= (2 * GetSystemMetrics(SM_CXVSCROLL
));
586 *ThumbSize
= MulDiv(Pixels
, Info
.nPage
, (Info
.nMax
- Info
.nMin
+ 1));
587 if (*ThumbSize
< SCROLL_MIN_THUMB
)
589 *ThumbSize
= SCROLL_MIN_THUMB
;
594 *ThumbSize
= GetSystemMetrics(SM_CXVSCROLL
);
598 if (((pixels
-= *ThumbSize
) < 0) ||
599 ((info
->flags
& ESB_DISABLE_BOTH
) == ESB_DISABLE_BOTH
))
601 if ((Pixels
-= *ThumbSize
) < 0)
604 /* Rectangle too small or scrollbar disabled -> no thumb */
605 *ThumbPos
= *ThumbSize
= 0;
609 INT Max
= Info
.nMax
- max(Info
.nPage
- 1, 0);
610 if (Max
<= Info
.nMin
)
612 *ThumbPos
= *ArrowSize
;
616 *ThumbPos
= *ArrowSize
617 + MulDiv(Pixels
, (Info
.nPos
- Info
.nMin
),
626 /***********************************************************************
627 * IntScrollGetThumbVal
629 * Compute the current scroll position based on the thumb position in pixels
630 * from the top of the scroll-bar.
633 IntScrollGetThumbVal(HWND Wnd
, INT SBType
, PSCROLLBARINFO ScrollBarInfo
,
634 BOOL Vertical
, INT Pos
)
637 INT Pixels
= Vertical
? ScrollBarInfo
->rcScrollBar
.bottom
638 - ScrollBarInfo
->rcScrollBar
.top
639 : ScrollBarInfo
->rcScrollBar
.right
640 - ScrollBarInfo
->rcScrollBar
.left
;
642 si
.cbSize
= sizeof(SCROLLINFO
);
643 si
.fMask
= SIF_RANGE
| SIF_PAGE
;
644 NtUserGetScrollInfo(Wnd
, SBType
, &si
);
645 if ((Pixels
-= 2 * ScrollBarInfo
->dxyLineButton
) <= 0)
650 if ((Pixels
-= (ScrollBarInfo
->xyThumbBottom
- ScrollBarInfo
->xyThumbTop
)) <= 0)
655 Pos
= Pos
- ScrollBarInfo
->dxyLineButton
;
667 Pos
*= si
.nMax
- si
.nMin
;
671 Pos
*= si
.nMax
- si
.nMin
- si
.nPage
+ 1;
673 return si
.nMin
+ ((Pos
+ Pixels
/ 2) / Pixels
);
676 /***********************************************************************
679 static POINT
IntScrollClipPos(PRECT Rect
, POINT Pt
)
681 if (Pt
.x
< Rect
->left
)
685 else if (Rect
->right
< Pt
.x
)
690 if (Pt
.y
< Rect
->top
)
694 else if (Rect
->bottom
< Pt
.y
)
702 /***********************************************************************
703 * IntScrollDrawSizeGrip
705 * Draw the size grip.
708 IntScrollDrawSizeGrip(HWND Wnd
, HDC Dc
)
712 GetClientRect(Wnd
, &Rect
);
713 FillRect(Dc
, &Rect
, GetSysColorBrush(COLOR_SCROLLBAR
));
714 Rect
.left
= max(Rect
.left
, Rect
.right
- GetSystemMetrics(SM_CXVSCROLL
) - 1);
715 Rect
.top
= max(Rect
.top
, Rect
.bottom
- GetSystemMetrics(SM_CYHSCROLL
) - 1);
716 DrawFrameControl(Dc
, &Rect
, DFC_SCROLL
, DFCS_SCROLLSIZEGRIP
);
721 /***********************************************************************
722 * IntScrollHandleKbdEvent
724 * Handle a keyboard event (only for SB_CTL scrollbars with focus).
727 IntScrollHandleKbdEvent(
728 HWND Wnd
/* [in] Handle of window with scrollbar(s) */,
729 WPARAM wParam
/* [in] Variable input including enable state */,
730 LPARAM lParam
/* [in] Variable input including input point */)
732 TRACE("Wnd=%p wParam=%ld lParam=%ld\n", Wnd
, wParam
, lParam
);
734 /* hide caret on first KEYDOWN to prevent flicker */
735 if (0 == (lParam
& PFD_DOUBLEBUFFER_DONTCARE
))
747 wParam
= SB_PAGEDOWN
;
763 wParam
= SB_LINEDOWN
;
770 SendMessageW(GetParent(Wnd
),
771 (0 != (GetWindowLongW(Wnd
, GWL_STYLE
) & SBS_VERT
) ?
772 WM_VSCROLL
: WM_HSCROLL
), wParam
, (LPARAM
) Wnd
);
775 /***********************************************************************
776 * IntScrollHandleScrollEvent
778 * Handle a mouse or timer event for the scrollbar.
779 * 'Pt' is the location of the mouse event in drawing coordinates
782 IntScrollHandleScrollEvent(HWND Wnd
, INT SBType
, UINT Msg
, POINT Pt
)
784 static POINT PrevPt
; /* Previous mouse position for timer events */
785 static UINT TrackThumbPos
; /* Thumb position when tracking started. */
786 static INT LastClickPos
; /* Position in the scroll-bar of the last
787 button-down event. */
788 static INT LastMousePos
; /* Position in the scroll-bar of the last
792 HWND WndOwner
, WndCtl
;
795 SCROLLBARINFO ScrollBarInfo
;
796 SETSCROLLBARINFO NewInfo
;
798 if (! IntGetScrollBarInfo(Wnd
, SBType
, &ScrollBarInfo
))
802 if (SCROLL_NOWHERE
== ScrollTrackHitTest
&& WM_LBUTTONDOWN
!= Msg
)
807 NewInfo
.nTrackPos
= ScrollTrackingVal
;
808 NewInfo
.reserved
= ScrollBarInfo
.reserved
;
809 memcpy(NewInfo
.rgstate
, ScrollBarInfo
.rgstate
, (CCHILDREN_SCROLLBAR
+ 1) * sizeof(DWORD
));
812 && 0 != (GetWindowLongW(Wnd
, GWL_STYLE
) & (SBS_SIZEGRIP
| SBS_SIZEBOX
)))
816 case WM_LBUTTONDOWN
: /* Initialise mouse tracking */
817 HideCaret(Wnd
); /* hide caret while holding down LBUTTON */
820 ScrollTrackHitTest
= HitTest
= SCROLL_THUMB
;
823 GetClientRect(GetParent(GetParent(Wnd
)), &ScrollBarInfo
.rcScrollBar
);
828 ScrollTrackHitTest
= HitTest
= SCROLL_NOWHERE
;
829 if (Wnd
== GetFocus())
841 Dc
= GetDCEx(Wnd
, 0, DCX_CACHE
| ((SB_CTL
== SBType
) ? 0 : DCX_WINDOW
));
842 if (SB_VERT
== SBType
)
846 else if (SB_HORZ
== SBType
)
852 Vertical
= (0 != (GetWindowLongW(Wnd
, GWL_STYLE
) & SBS_VERT
));
854 WndOwner
= (SB_CTL
== SBType
) ? GetParent(Wnd
) : Wnd
;
855 WndCtl
= (SB_CTL
== SBType
) ? Wnd
: NULL
;
859 case WM_LBUTTONDOWN
: /* Initialise mouse tracking */
860 HideCaret(Wnd
); /* hide caret while holding down LBUTTON */
861 ScrollTrackVertical
= Vertical
;
862 ScrollTrackHitTest
= HitTest
= IntScrollHitTest(&ScrollBarInfo
, Vertical
, Pt
, FALSE
);
863 LastClickPos
= Vertical
? (Pt
.y
- ScrollBarInfo
.rcScrollBar
.top
)
864 : (Pt
.x
- ScrollBarInfo
.rcScrollBar
.left
);
865 LastMousePos
= LastClickPos
;
866 TrackThumbPos
= ScrollBarInfo
.xyThumbTop
;
868 if (SB_CTL
== SBType
&& 0 != (GetWindowLongW(Wnd
, GWL_STYLE
) & WS_TABSTOP
))
873 ScrollBarInfo
.rgstate
[ScrollTrackHitTest
] |= STATE_SYSTEM_PRESSED
;
874 NewInfo
.rgstate
[ScrollTrackHitTest
] = ScrollBarInfo
.rgstate
[ScrollTrackHitTest
];
875 NtUserSetScrollBarInfo(Wnd
, IntScrollGetObjectId(SBType
), &NewInfo
);
879 HitTest
= IntScrollHitTest(&ScrollBarInfo
, Vertical
, Pt
, TRUE
);
884 HitTest
= SCROLL_NOWHERE
;
886 /* if scrollbar has focus, show back caret */
887 if (Wnd
== GetFocus())
891 ScrollBarInfo
.rgstate
[ScrollTrackHitTest
] &= ~STATE_SYSTEM_PRESSED
;
892 NewInfo
.rgstate
[ScrollTrackHitTest
] = ScrollBarInfo
.rgstate
[ScrollTrackHitTest
];
893 NtUserSetScrollBarInfo(Wnd
, IntScrollGetObjectId(SBType
), &NewInfo
);
898 HitTest
= IntScrollHitTest(&ScrollBarInfo
, Vertical
, Pt
, FALSE
);
902 return; /* Should never happen */
905 switch (ScrollTrackHitTest
)
907 case SCROLL_NOWHERE
: /* No tracking in progress */
910 case SCROLL_TOP_ARROW
:
911 if (HitTest
== ScrollTrackHitTest
)
913 if ((WM_LBUTTONDOWN
== Msg
) || (WM_SYSTIMER
== Msg
))
915 SendMessageW(WndOwner
, Vertical
? WM_VSCROLL
: WM_HSCROLL
,
916 SB_LINEUP
, (LPARAM
) WndCtl
);
918 SetSystemTimer(Wnd
, SCROLL_TIMER
, (WM_LBUTTONDOWN
== Msg
) ?
919 SCROLL_FIRST_DELAY
: SCROLL_REPEAT_DELAY
,
924 KillSystemTimer(Wnd
, SCROLL_TIMER
);
928 case SCROLL_TOP_RECT
:
929 if (HitTest
== ScrollTrackHitTest
)
931 if ((WM_LBUTTONDOWN
== Msg
) || (WM_SYSTIMER
== Msg
))
933 SendMessageW(WndOwner
, Vertical
? WM_VSCROLL
: WM_HSCROLL
,
934 SB_PAGEUP
, (LPARAM
) WndCtl
);
936 SetSystemTimer(Wnd
, SCROLL_TIMER
, (WM_LBUTTONDOWN
== Msg
) ?
937 SCROLL_FIRST_DELAY
: SCROLL_REPEAT_DELAY
,
942 KillSystemTimer(Wnd
, SCROLL_TIMER
);
947 if (WM_LBUTTONDOWN
== Msg
)
949 ScrollTrackingWin
= Wnd
;
950 ScrollTrackingBar
= SBType
;
951 ScrollTrackingPos
= TrackThumbPos
+ LastMousePos
- LastClickPos
;
952 ScrollTrackingVal
= IntScrollGetThumbVal(Wnd
, SBType
, &ScrollBarInfo
,
953 Vertical
, ScrollTrackingPos
);
954 NewInfo
.nTrackPos
= ScrollTrackingVal
;
955 NtUserSetScrollBarInfo(Wnd
, IntScrollGetObjectId(SBType
), &NewInfo
);
956 IntScrollDrawMovingThumb(Dc
, &ScrollBarInfo
, Vertical
);
958 else if (WM_LBUTTONUP
== Msg
)
960 ScrollTrackingWin
= 0;
961 ScrollTrackingVal
= 0;
962 IntDrawScrollInterior(Wnd
, Dc
, SBType
, Vertical
, &ScrollBarInfo
);
964 else /* WM_MOUSEMOVE */
968 if (! IntScrollPtInRectEx(&ScrollBarInfo
.rcScrollBar
, Pt
, Vertical
))
974 Pt
= IntScrollClipPos(&ScrollBarInfo
.rcScrollBar
, Pt
);
975 Pos
= Vertical
? (Pt
.y
- ScrollBarInfo
.rcScrollBar
.top
)
976 : (Pt
.x
- ScrollBarInfo
.rcScrollBar
.left
);
978 if (Pos
!= LastMousePos
|| ! ScrollMovingThumb
)
981 ScrollTrackingPos
= TrackThumbPos
+ Pos
- LastClickPos
;
982 ScrollTrackingVal
= IntScrollGetThumbVal(Wnd
, SBType
, &ScrollBarInfo
,
983 Vertical
, ScrollTrackingPos
);
984 NewInfo
.nTrackPos
= ScrollTrackingVal
;
985 NtUserSetScrollBarInfo(Wnd
, IntScrollGetObjectId(SBType
), &NewInfo
);
986 IntScrollDrawMovingThumb(Dc
, &ScrollBarInfo
, Vertical
);
987 SendMessageW(WndOwner
, Vertical
? WM_VSCROLL
: WM_HSCROLL
,
988 MAKEWPARAM(SB_THUMBTRACK
, ScrollTrackingVal
),
994 case SCROLL_BOTTOM_RECT
:
995 if (HitTest
== ScrollTrackHitTest
)
997 if ((WM_LBUTTONDOWN
== Msg
) || (WM_SYSTIMER
== Msg
))
999 SendMessageW(WndOwner
, Vertical
? WM_VSCROLL
: WM_HSCROLL
,
1000 SB_PAGEDOWN
, (LPARAM
) WndCtl
);
1002 SetSystemTimer(Wnd
, SCROLL_TIMER
, (WM_LBUTTONDOWN
== Msg
) ?
1003 SCROLL_FIRST_DELAY
: SCROLL_REPEAT_DELAY
,
1008 KillSystemTimer(Wnd
, SCROLL_TIMER
);
1012 case SCROLL_BOTTOM_ARROW
:
1013 if (HitTest
== ScrollTrackHitTest
)
1015 if ((WM_LBUTTONDOWN
== Msg
) || (WM_SYSTIMER
== Msg
))
1017 SendMessageW(WndOwner
, Vertical
? WM_VSCROLL
: WM_HSCROLL
,
1018 SB_LINEDOWN
, (LPARAM
) WndCtl
);
1020 SetSystemTimer(Wnd
, SCROLL_TIMER
, (WM_LBUTTONDOWN
== Msg
) ?
1021 SCROLL_FIRST_DELAY
: SCROLL_REPEAT_DELAY
,
1026 KillSystemTimer(Wnd
, SCROLL_TIMER
);
1031 if (WM_LBUTTONDOWN
== Msg
)
1033 if (SCROLL_THUMB
== HitTest
)
1035 UINT Val
= IntScrollGetThumbVal(Wnd
, SBType
, &ScrollBarInfo
, Vertical
,
1036 TrackThumbPos
+ LastMousePos
- LastClickPos
);
1037 SendMessageW(WndOwner
, Vertical
? WM_VSCROLL
: WM_HSCROLL
,
1038 MAKEWPARAM(SB_THUMBTRACK
, Val
), (LPARAM
) WndCtl
);
1042 if (WM_LBUTTONUP
== Msg
)
1044 HitTest
= ScrollTrackHitTest
;
1045 ScrollTrackHitTest
= SCROLL_NOWHERE
; /* Terminate tracking */
1047 if (SCROLL_THUMB
== HitTest
)
1049 UINT Val
= IntScrollGetThumbVal(Wnd
, SBType
, &ScrollBarInfo
, Vertical
,
1050 TrackThumbPos
+ LastMousePos
- LastClickPos
);
1051 SendMessageW(WndOwner
, Vertical
? WM_VSCROLL
: WM_HSCROLL
,
1052 MAKEWPARAM(SB_THUMBPOSITION
, Val
), (LPARAM
) WndCtl
);
1054 SendMessageW(WndOwner
, Vertical
? WM_VSCROLL
: WM_HSCROLL
,
1055 SB_ENDSCROLL
, (LPARAM
) WndCtl
);
1062 /***********************************************************************
1063 * IntScrollCreateScrollBar
1065 * Create a scroll bar
1067 static void IntScrollCreateScrollBar(
1068 HWND Wnd
/* [in] Handle of window with scrollbar(s) */,
1069 LPCREATESTRUCTW lpCreate
/* [in] The style and place of the scroll bar */)
1073 Info
.cbSize
= sizeof(SCROLLINFO
);
1074 Info
.fMask
= SIF_RANGE
| SIF_PAGE
| SIF_POS
;
1080 NtUserSetScrollInfo(Wnd
, SB_CTL
, &Info
, FALSE
);
1082 TRACE("hwnd=%p lpCreate=%p\n", Wnd
, lpCreate
);
1085 if (lpCreate
->style
& WS_DISABLED
)
1087 info
->flags
= ESB_DISABLE_BOTH
;
1088 TRACE("Created WS_DISABLED scrollbar\n");
1092 if (0 != (lpCreate
->style
& (SBS_SIZEGRIP
| SBS_SIZEBOX
)))
1094 if (0 != (lpCreate
->style
& SBS_SIZEBOXTOPLEFTALIGN
))
1096 MoveWindow(Wnd
, lpCreate
->x
, lpCreate
->y
, GetSystemMetrics(SM_CXVSCROLL
) + 1,
1097 GetSystemMetrics(SM_CYHSCROLL
) + 1, FALSE
);
1099 else if (0 != (lpCreate
->style
& SBS_SIZEBOXBOTTOMRIGHTALIGN
))
1101 MoveWindow(Wnd
, lpCreate
->x
+ lpCreate
->cx
- GetSystemMetrics(SM_CXVSCROLL
) - 1,
1102 lpCreate
->y
+ lpCreate
->cy
- GetSystemMetrics(SM_CYHSCROLL
) - 1,
1103 GetSystemMetrics(SM_CXVSCROLL
) + 1,
1104 GetSystemMetrics(SM_CYHSCROLL
) + 1, FALSE
);
1107 else if (0 != (lpCreate
->style
& SBS_VERT
))
1109 if (0 != (lpCreate
->style
& SBS_LEFTALIGN
))
1111 MoveWindow(Wnd
, lpCreate
->x
, lpCreate
->y
,
1112 GetSystemMetrics(SM_CXVSCROLL
) + 1, lpCreate
->cy
, FALSE
);
1114 else if (0 != (lpCreate
->style
& SBS_RIGHTALIGN
))
1117 lpCreate
->x
+ lpCreate
->cx
- GetSystemMetrics(SM_CXVSCROLL
) - 1,
1119 GetSystemMetrics(SM_CXVSCROLL
) + 1, lpCreate
->cy
, FALSE
);
1124 if (0 != (lpCreate
->style
& SBS_TOPALIGN
))
1126 MoveWindow(Wnd
, lpCreate
->x
, lpCreate
->y
,
1127 lpCreate
->cx
, GetSystemMetrics(SM_CYHSCROLL
) + 1, FALSE
);
1129 else if (0 != (lpCreate
->style
& SBS_BOTTOMALIGN
))
1133 lpCreate
->y
+ lpCreate
->cy
- GetSystemMetrics(SM_CYHSCROLL
) - 1,
1134 lpCreate
->cx
, GetSystemMetrics(SM_CYHSCROLL
) + 1, FALSE
);
1140 IntScrollGetScrollPos(HWND Wnd
, INT Bar
)
1142 SCROLLINFO ScrollInfo
;
1144 ScrollInfo
.cbSize
= sizeof(SCROLLINFO
);
1145 ScrollInfo
.fMask
= SIF_POS
;
1146 if (! NtUserGetScrollInfo(Wnd
, Bar
, &ScrollInfo
))
1151 return ScrollInfo
.nPos
;
1154 static BOOL FASTCALL
1155 IntScrollGetScrollRange(HWND Wnd
, int Bar
, LPINT MinPos
, LPINT MaxPos
)
1158 SCROLLINFO ScrollInfo
;
1160 if (NULL
== MinPos
|| NULL
== MaxPos
)
1162 SetLastError(ERROR_INVALID_PARAMETER
);
1166 ScrollInfo
.cbSize
= sizeof(SCROLLINFO
);
1167 ScrollInfo
.fMask
= SIF_RANGE
;
1168 Result
= NtUserGetScrollInfo(Wnd
, Bar
, &ScrollInfo
);
1171 *MinPos
= ScrollInfo
.nMin
;
1172 *MaxPos
= ScrollInfo
.nMax
;
1178 /* USER32 INTERNAL FUNCTIONS **************************************************/
1180 /***********************************************************************
1181 * ScrollTrackScrollBar
1183 * Track a mouse button press on a scroll-bar.
1184 * pt is in screen-coordinates for non-client scroll bars.
1187 ScrollTrackScrollBar(HWND Wnd
, INT SBType
, POINT Pt
)
1191 UINT XOffset
, YOffset
;
1194 if (SB_CTL
!= SBType
)
1196 GetWindowRect(Wnd
, &WindowRect
);
1198 Pt
.x
-= WindowRect
.left
;
1199 Pt
.y
-= WindowRect
.top
;
1201 TopLeft
.x
= WindowRect
.left
;
1202 TopLeft
.y
= WindowRect
.top
;
1203 ScreenToClient(Wnd
, &TopLeft
);
1204 XOffset
= - TopLeft
.x
;
1205 YOffset
= - TopLeft
.y
;
1213 IntScrollHandleScrollEvent(Wnd
, SBType
, WM_LBUTTONDOWN
, Pt
);
1217 if (! GetMessageW(&Msg
, 0, 0, 0))
1221 if (CallMsgFilterW(&Msg
, MSGF_SCROLLBAR
))
1231 Pt
.x
= LOWORD(Msg
.lParam
) + XOffset
;
1232 Pt
.y
= HIWORD(Msg
.lParam
) + YOffset
;
1233 IntScrollHandleScrollEvent(Wnd
, SBType
, Msg
.message
, Pt
);
1236 TranslateMessage(&Msg
);
1237 DispatchMessageW(&Msg
);
1241 if (! IsWindow(Wnd
))
1247 while (WM_LBUTTONUP
!= Msg
.message
);
1251 /***********************************************************************
1254 static LRESULT WINAPI
1255 ScrollBarWndProc(HWND Wnd
, UINT Msg
, WPARAM wParam
, LPARAM lParam
)
1257 if (! IsWindow(Wnd
))
1265 IntScrollCreateScrollBar(Wnd
, (LPCREATESTRUCTW
) lParam
);
1271 // SCROLLBAR_INFO *infoPtr;
1272 // if ((infoPtr = SCROLL_GetScrollBarInfo( hwnd, SB_CTL )))
1274 // infoPtr->flags = wParam ? ESB_ENABLE_BOTH : ESB_DISABLE_BOTH;
1275 // SCROLL_RefreshScrollBar(hwnd, SB_CTL, TRUE, TRUE);
1278 DbgPrint("ScrollBarWndProc WM_ENABLE\n");
1279 NtUserEnableScrollBar(Wnd
,SB_CTL
,(wParam
? ESB_ENABLE_BOTH
: ESB_DISABLE_BOTH
));
1280 /* Refresh Scrollbars. */
1281 hdc
= GetDCEx( Wnd
, 0, DCX_CACHE
);
1283 IntDrawScrollBar( Wnd
, hdc
, SB_CTL
);
1284 ReleaseDC( Wnd
, hdc
);
1289 case WM_LBUTTONDBLCLK
:
1290 case WM_LBUTTONDOWN
:
1294 Pt
.x
= (short)LOWORD(lParam
);
1295 Pt
.y
= (short)HIWORD(lParam
);
1296 ScrollTrackScrollBar(Wnd
, SB_CTL
, Pt
);
1306 Pt
.x
= (short)LOWORD(lParam
);
1307 Pt
.y
= (short)HIWORD(lParam
);
1308 IntScrollHandleScrollEvent(Wnd
, SB_CTL
, Msg
, Pt
);
1313 IntScrollHandleKbdEvent(Wnd
, wParam
, lParam
);
1322 /* Create a caret when a ScrollBar get focus */
1324 int ArrowSize
, ThumbSize
, ThumbPos
, Vertical
;
1326 Vertical
= IntScrollGetScrollBarRect(Wnd
, SB_CTL
, &Rect
,
1327 &ArrowSize
, &ThumbSize
, &ThumbPos
);
1330 CreateCaret(Wnd
, (HBITMAP
) 1, ThumbSize
- 2, Rect
.bottom
- Rect
.top
- 2);
1331 SetCaretPos(ThumbPos
+ 1, Rect
.top
+ 1);
1335 CreateCaret(Wnd
, (HBITMAP
) 1, Rect
.right
- Rect
.left
- 2, ThumbSize
- 2);
1336 SetCaretPos(Rect
.top
+ 1, ThumbPos
+ 1);
1345 int ArrowSize
, ThumbSize
, ThumbPos
, Vertical
;
1347 Vertical
= IntScrollGetScrollBarRect(Wnd
, SB_CTL
, &Rect
,
1348 &ArrowSize
, &ThumbSize
, &ThumbPos
);
1351 Rect
.left
= ThumbPos
+ 1;
1352 Rect
.right
= Rect
.left
+ ThumbSize
;
1356 Rect
.top
= ThumbPos
+ 1;
1357 Rect
.bottom
= Rect
.top
+ ThumbSize
;
1360 NtUserInvalidateRect(Wnd
, &Rect
, FALSE
);
1369 return DLGC_WANTARROWS
; /* Windows returns this value */
1376 Dc
= (0 != wParam
? (HDC
) wParam
: BeginPaint(Wnd
, &Ps
));
1378 if (GetWindowLongW(Wnd
, GWL_STYLE
) & SBS_SIZEGRIP
)
1380 IntScrollDrawSizeGrip(Wnd
, Dc
);
1382 else if (0 != (GetWindowLongW(Wnd
, GWL_STYLE
) & SBS_SIZEBOX
))
1385 GetClientRect(Wnd
, &Rect
);
1386 FillRect(Dc
, &Rect
, GetSysColorBrush(COLOR_SCROLLBAR
));
1390 IntDrawScrollBar(Wnd
, Dc
, SB_CTL
/*, TRUE, TRUE*/);
1401 return SetScrollPos(Wnd
, SB_CTL
, wParam
, (BOOL
) lParam
);
1404 return IntScrollGetScrollPos(Wnd
, SB_CTL
);
1408 INT OldPos
= IntScrollGetScrollPos(Wnd
, SB_CTL
);
1409 SetScrollRange(Wnd
, SB_CTL
, wParam
, lParam
, FALSE
);
1410 if (OldPos
!= IntScrollGetScrollPos(Wnd
, SB_CTL
))
1418 return IntScrollGetScrollRange(Wnd
, SB_CTL
, (LPINT
) wParam
, (LPINT
) lParam
);
1420 case SBM_ENABLE_ARROWS
:
1421 return EnableScrollBar(Wnd
, SB_CTL
, wParam
);
1423 case SBM_SETRANGEREDRAW
:
1425 INT OldPos
= IntScrollGetScrollPos(Wnd
, SB_CTL
);
1426 SetScrollRange(Wnd
, SB_CTL
, wParam
, lParam
, TRUE
);
1427 if (OldPos
!= IntScrollGetScrollPos(Wnd
, SB_CTL
))
1434 case SBM_SETSCROLLINFO
:
1435 return NtUserSetScrollInfo(Wnd
, SB_CTL
, (SCROLLINFO
*) lParam
, wParam
);
1437 case SBM_GETSCROLLINFO
:
1438 return NtUserGetScrollInfo(Wnd
, SB_CTL
, (SCROLLINFO
*) lParam
);
1448 WARN("unknown Win32 msg %04x wp=%08lx lp=%08lx\n",
1449 Msg
, wParam
, lParam
);
1455 WARN("unknown msg %04x wp=%04lx lp=%08lx\n", Msg
, wParam
, lParam
);
1457 return DefWindowProcW(Wnd
, Msg
, wParam
, lParam
);
1464 /* PUBLIC FUNCTIONS ***********************************************************/
1470 EnableScrollBar(HWND hWnd
, UINT wSBflags
, UINT wArrows
)
1472 return NtUserEnableScrollBar(hWnd
, wSBflags
, wArrows
);
1479 GetScrollBarInfo(HWND hWnd
, LONG idObject
, PSCROLLBARINFO psbi
)
1481 return NtUserGetScrollBarInfo(hWnd
, idObject
, psbi
);
1488 GetScrollInfo(HWND Wnd
, INT SBType
, LPSCROLLINFO Info
)
1490 if (SB_CTL
== SBType
)
1492 return SendMessageW(Wnd
, SBM_GETSCROLLINFO
, 0, (LPARAM
) Info
);
1496 return NtUserGetScrollInfo(Wnd
, SBType
, Info
);
1504 GetScrollPos(HWND Wnd
, INT Bar
)
1506 TRACE("Wnd=%p Bar=%d\n", Wnd
, Bar
);
1508 /* Refer SB_CTL requests to the window */
1511 return SendMessageW(Wnd
, SBM_GETPOS
, (WPARAM
) 0, (LPARAM
) 0);
1515 return IntScrollGetScrollPos(Wnd
, Bar
);
1523 GetScrollRange(HWND Wnd
, int Bar
, LPINT MinPos
, LPINT MaxPos
)
1525 TRACE("Wnd=%x Bar=%d Min=%p Max=%p\n", Wnd
, Bar
, MinPos
, MaxPos
);
1527 /* Refer SB_CTL requests to the window */
1530 return SendMessageW(Wnd
, SBM_GETRANGE
, (WPARAM
) MinPos
, (LPARAM
) MaxPos
);
1534 return IntScrollGetScrollRange(Wnd
, Bar
, MinPos
, MaxPos
);
1542 SetScrollInfo(HWND Wnd
, int SBType
, LPCSCROLLINFO Info
, BOOL bRedraw
)
1544 if (SB_CTL
== SBType
)
1546 return SendMessageW(Wnd
, SBM_SETSCROLLINFO
, (WPARAM
) bRedraw
, (LPARAM
) Info
);
1550 return NtUserSetScrollInfo(Wnd
, SBType
, Info
, bRedraw
);
1558 SetScrollPos(HWND hWnd
, INT nBar
, INT nPos
, BOOL bRedraw
)
1561 SCROLLINFO ScrollInfo
;
1563 ScrollInfo
.cbSize
= sizeof(SCROLLINFO
);
1564 ScrollInfo
.fMask
= SIF_POS
;
1567 * Call NtUserGetScrollInfo() to get the previous position that
1568 * we will later return.
1570 if (NtUserGetScrollInfo(hWnd
, nBar
, &ScrollInfo
))
1572 Result
= ScrollInfo
.nPos
;
1575 ScrollInfo
.nPos
= nPos
;
1576 /* Finally set the new position */
1577 NtUserSetScrollInfo(hWnd
, nBar
, &ScrollInfo
, bRedraw
);
1588 SetScrollRange(HWND hWnd
, INT nBar
, INT nMinPos
, INT nMaxPos
, BOOL bRedraw
)
1590 SCROLLINFO ScrollInfo
;
1592 ScrollInfo
.cbSize
= sizeof(SCROLLINFO
);
1593 ScrollInfo
.fMask
= SIF_RANGE
;
1594 ScrollInfo
.nMin
= nMinPos
;
1595 ScrollInfo
.nMax
= nMaxPos
;
1596 NtUserSetScrollInfo(hWnd
, nBar
, &ScrollInfo
, bRedraw
);
1605 ShowScrollBar(HWND hWnd
, INT wBar
, BOOL bShow
)
1607 return NtUserShowScrollBar(hWnd
, wBar
, bShow
);