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
ScrollBarWndProcW( HWND hwnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
);
73 static LRESULT WINAPI
ScrollBarWndProcA( HWND hwnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
);
75 UINT STDCALL
SetSystemTimer(HWND
,UINT_PTR
,UINT
,TIMERPROC
);
76 BOOL STDCALL
KillSystemTimer(HWND
,UINT_PTR
);
78 /*********************************************************************
79 * scrollbar class descriptor
81 const struct builtin_class_descr SCROLL_builtin_class
=
83 L
"ScrollBar", /* name */
84 CS_DBLCLKS
| CS_VREDRAW
| CS_HREDRAW
| CS_PARENTDC
, /* style */
85 ScrollBarWndProcW
, /* procW */
86 ScrollBarWndProcA
, /* procA */
88 IDC_ARROW
, /* cursor */
92 /* PRIVATE FUNCTIONS **********************************************************/
96 IntDrawScrollInterior(HWND hWnd
, HDC hDC
, INT nBar
, BOOL Vertical
,
97 PSCROLLBARINFO ScrollBarInfo
)
99 INT ThumbSize
= ScrollBarInfo
->xyThumbBottom
- ScrollBarInfo
->xyThumbTop
;
100 INT ThumbTop
= ScrollBarInfo
->xyThumbTop
;
103 HBRUSH hSaveBrush
, hBrush
;
104 BOOL TopSelected
= FALSE
, BottomSelected
= FALSE
;
106 if (ScrollBarInfo
->rgstate
[SCROLL_TOP_RECT
] & STATE_SYSTEM_PRESSED
)
108 if (ScrollBarInfo
->rgstate
[SCROLL_BOTTOM_RECT
] & STATE_SYSTEM_PRESSED
)
109 BottomSelected
= TRUE
;
112 * Only scrollbar controls send WM_CTLCOLORSCROLLBAR.
113 * The window-owned scrollbars need to call DefWndControlColor
114 * to correctly setup default scrollbar colors
118 hBrush
= (HBRUSH
)SendMessageW(GetParent(hWnd
), WM_CTLCOLORSCROLLBAR
, (WPARAM
)hDC
, (LPARAM
)hWnd
);
120 hBrush
= GetSysColorBrush(COLOR_SCROLLBAR
);
124 hBrush
= DefWndControlColor(hDC
, CTLCOLOR_SCROLLBAR
);
127 hSavePen
= SelectObject(hDC
, GetSysColorPen(COLOR_WINDOWFRAME
));
128 hSaveBrush
= SelectObject(hDC
, hBrush
);
130 /* Calculate the scroll rectangle */
133 Rect
.top
= ScrollBarInfo
->rcScrollBar
.top
+ ScrollBarInfo
->dxyLineButton
;
134 Rect
.bottom
= ScrollBarInfo
->rcScrollBar
.bottom
- ScrollBarInfo
->dxyLineButton
;
135 Rect
.left
= ScrollBarInfo
->rcScrollBar
.left
;
136 Rect
.right
= ScrollBarInfo
->rcScrollBar
.right
;
140 Rect
.top
= ScrollBarInfo
->rcScrollBar
.top
;
141 Rect
.bottom
= ScrollBarInfo
->rcScrollBar
.bottom
;
142 Rect
.left
= ScrollBarInfo
->rcScrollBar
.left
+ ScrollBarInfo
->dxyLineButton
;
143 Rect
.right
= ScrollBarInfo
->rcScrollBar
.right
- ScrollBarInfo
->dxyLineButton
;
146 /* Draw the scroll rectangles and thumb */
147 if (!ScrollBarInfo
->xyThumbBottom
)
149 PatBlt(hDC
, Rect
.left
, Rect
.top
, Rect
.right
- Rect
.left
,
150 Rect
.bottom
- Rect
.top
, PATCOPY
);
152 /* Cleanup and return */
153 SelectObject(hDC
, hSavePen
);
154 SelectObject(hDC
, hSaveBrush
);
158 ThumbTop
-= ScrollBarInfo
->dxyLineButton
;
160 if (ScrollBarInfo
->dxyLineButton
)
166 PatBlt(hDC
, Rect
.left
, Rect
.top
, Rect
.right
- Rect
.left
,
167 ThumbTop
, TopSelected
? BLACKNESS
: PATCOPY
);
168 Rect
.top
+= ThumbTop
;
169 PatBlt(hDC
, Rect
.left
, Rect
.top
+ ThumbSize
, Rect
.right
- Rect
.left
,
170 Rect
.bottom
- Rect
.top
- ThumbSize
, BottomSelected
? BLACKNESS
: PATCOPY
);
171 Rect
.bottom
= Rect
.top
+ ThumbSize
;
177 PatBlt(hDC
, Rect
.left
, ScrollBarInfo
->dxyLineButton
,
178 Rect
.right
- Rect
.left
, Rect
.bottom
- Rect
.top
, PATCOPY
);
186 PatBlt(hDC
, Rect
.left
, Rect
.top
, ThumbTop
,
187 Rect
.bottom
- Rect
.top
, TopSelected
? BLACKNESS
: PATCOPY
);
188 Rect
.left
+= ThumbTop
;
189 PatBlt(hDC
, Rect
.left
+ ThumbSize
, Rect
.top
,
190 Rect
.right
- Rect
.left
- ThumbSize
, Rect
.bottom
- Rect
.top
,
191 BottomSelected
? BLACKNESS
: PATCOPY
);
192 Rect
.right
= Rect
.left
+ ThumbSize
;
198 PatBlt(hDC
, ScrollBarInfo
->dxyLineButton
, Rect
.top
,
199 Rect
.right
- Rect
.left
, Rect
.bottom
- Rect
.top
, PATCOPY
);
207 DrawEdge(hDC
, &Rect
, EDGE_RAISED
, BF_RECT
| BF_MIDDLE
);
210 SelectObject(hDC
, hSavePen
);
211 SelectObject(hDC
, hSaveBrush
);
215 IntDrawScrollArrows(HDC hDC
, PSCROLLBARINFO ScrollBarInfo
, BOOL Vertical
)
218 INT ScrollDirFlagLT
, ScrollDirFlagRB
;
220 RectLT
= RectRB
= ScrollBarInfo
->rcScrollBar
;
223 ScrollDirFlagLT
= DFCS_SCROLLUP
;
224 ScrollDirFlagRB
= DFCS_SCROLLDOWN
;
225 RectLT
.bottom
= RectLT
.top
+ ScrollBarInfo
->dxyLineButton
;
226 RectRB
.top
= RectRB
.bottom
- ScrollBarInfo
->dxyLineButton
;
230 ScrollDirFlagLT
= DFCS_SCROLLLEFT
;
231 ScrollDirFlagRB
= DFCS_SCROLLRIGHT
;
232 RectLT
.right
= RectLT
.left
+ ScrollBarInfo
->dxyLineButton
;
233 RectRB
.left
= RectRB
.right
- ScrollBarInfo
->dxyLineButton
;
236 if (ScrollBarInfo
->rgstate
[SCROLL_TOP_ARROW
] & STATE_SYSTEM_PRESSED
)
238 ScrollDirFlagLT
|= DFCS_PUSHED
| DFCS_FLAT
;
240 if (ScrollBarInfo
->rgstate
[SCROLL_TOP_ARROW
] & STATE_SYSTEM_UNAVAILABLE
)
242 ScrollDirFlagLT
|= DFCS_INACTIVE
;
244 if (ScrollBarInfo
->rgstate
[SCROLL_BOTTOM_ARROW
] & STATE_SYSTEM_PRESSED
)
246 ScrollDirFlagRB
|= DFCS_PUSHED
| DFCS_FLAT
;
248 if (ScrollBarInfo
->rgstate
[SCROLL_BOTTOM_ARROW
] & STATE_SYSTEM_UNAVAILABLE
)
250 ScrollDirFlagRB
|= DFCS_INACTIVE
;
253 DrawFrameControl(hDC
, &RectLT
, DFC_SCROLL
, ScrollDirFlagLT
);
254 DrawFrameControl(hDC
, &RectRB
, DFC_SCROLL
, ScrollDirFlagRB
);
258 IntScrollDrawMovingThumb(HDC Dc
, PSCROLLBARINFO ScrollBarInfo
, BOOL Vertical
)
260 INT Pos
= ScrollTrackingPos
;
266 MaxSize
= ScrollBarInfo
->rcScrollBar
.bottom
- ScrollBarInfo
->rcScrollBar
.top
;
270 MaxSize
= ScrollBarInfo
->rcScrollBar
.right
- ScrollBarInfo
->rcScrollBar
.left
;
273 MaxSize
-= ScrollBarInfo
->dxyLineButton
+ ScrollBarInfo
->xyThumbBottom
274 - ScrollBarInfo
->xyThumbTop
;
276 if (Pos
< ScrollBarInfo
->dxyLineButton
)
278 Pos
= ScrollBarInfo
->dxyLineButton
;
280 else if (MaxSize
< Pos
)
285 OldTop
= ScrollBarInfo
->xyThumbTop
;
286 ScrollBarInfo
->xyThumbBottom
= Pos
+ ScrollBarInfo
->xyThumbBottom
- ScrollBarInfo
->xyThumbTop
;
287 ScrollBarInfo
->xyThumbTop
= Pos
;
288 IntDrawScrollInterior(ScrollTrackingWin
, Dc
, ScrollTrackingBar
, Vertical
, ScrollBarInfo
);
289 ScrollBarInfo
->xyThumbBottom
= OldTop
+ ScrollBarInfo
->xyThumbBottom
- ScrollBarInfo
->xyThumbTop
;
290 ScrollBarInfo
->xyThumbTop
= OldTop
;
292 ScrollMovingThumb
= ! ScrollMovingThumb
;
296 IntScrollGetObjectId(INT SBType
)
298 if (SB_VERT
== SBType
)
300 return OBJID_VSCROLL
;
302 if (SB_HORZ
== SBType
)
304 return OBJID_HSCROLL
;
311 IntGetScrollBarInfo(HWND Wnd
, INT Bar
, PSCROLLBARINFO ScrollBarInfo
)
313 ScrollBarInfo
->cbSize
= sizeof(SCROLLBARINFO
);
315 return NtUserGetScrollBarInfo(Wnd
, IntScrollGetObjectId(Bar
), ScrollBarInfo
);
319 IntDrawScrollBar(HWND Wnd
, HDC DC
, INT Bar
)
326 * Get scroll bar info.
339 Vertical
= (GetWindowLongW(Wnd
, GWL_STYLE
) & SBS_VERT
) != 0;
345 if (! IntGetScrollBarInfo(Wnd
, Bar
, &Info
))
350 if (IsRectEmpty(&Info
.rcScrollBar
))
355 ThumbSize
= Info
.xyThumbBottom
- Info
.xyThumbTop
;
360 if (Info
.dxyLineButton
)
362 IntDrawScrollArrows(DC
, &Info
, Vertical
);
368 IntDrawScrollInterior(Wnd
, DC
, Bar
, Vertical
, &Info
);
371 * If scroll bar has focus, reposition the caret.
373 if (Wnd
== GetFocus() && SB_CTL
== Bar
)
377 SetCaretPos(Info
.rcScrollBar
.top
+ 1, Info
.dxyLineButton
+ 1);
381 SetCaretPos(Info
.dxyLineButton
+ 1, Info
.rcScrollBar
.top
+ 1);
387 IntScrollPtInRectEx(LPRECT Rect
, POINT Pt
, BOOL Vertical
)
389 RECT TempRect
= *Rect
;
392 TempRect
.left
-= Rect
->right
- Rect
->left
;
393 TempRect
.right
+= Rect
->right
- Rect
->left
;
397 TempRect
.top
-= Rect
->bottom
- Rect
->top
;
398 TempRect
.bottom
+= Rect
->bottom
- Rect
->top
;
401 return PtInRect(&TempRect
, Pt
);
404 static DWORD FASTCALL
405 IntScrollHitTest(PSCROLLBARINFO ScrollBarInfo
, BOOL Vertical
, POINT Pt
, BOOL Dragging
)
407 INT ArrowSize
, ThumbSize
, ThumbPos
;
409 if ((Dragging
&& ! IntScrollPtInRectEx(&ScrollBarInfo
->rcScrollBar
, Pt
, Vertical
)) ||
410 ! PtInRect(&ScrollBarInfo
->rcScrollBar
, Pt
))
412 return SCROLL_NOWHERE
;
415 ThumbPos
= ScrollBarInfo
->xyThumbTop
;
416 ThumbSize
= ScrollBarInfo
->xyThumbBottom
- ThumbPos
;
417 ArrowSize
= ScrollBarInfo
->dxyLineButton
;
421 if (Pt
.y
< ScrollBarInfo
->rcScrollBar
.top
+ ArrowSize
)
423 return SCROLL_TOP_ARROW
;
425 if (ScrollBarInfo
->rcScrollBar
.bottom
- ArrowSize
<= Pt
.y
)
427 return SCROLL_BOTTOM_ARROW
;
431 return SCROLL_TOP_RECT
;
433 Pt
.y
-= ScrollBarInfo
->rcScrollBar
.top
;
436 return SCROLL_TOP_RECT
;
438 if (ThumbPos
+ ThumbSize
<= Pt
.y
)
440 return SCROLL_BOTTOM_RECT
;
445 if (Pt
.x
< ScrollBarInfo
->rcScrollBar
.left
+ ArrowSize
)
447 return SCROLL_TOP_ARROW
;
449 if (ScrollBarInfo
->rcScrollBar
.right
- ArrowSize
<= Pt
.x
)
451 return SCROLL_BOTTOM_ARROW
;
455 return SCROLL_TOP_RECT
;
457 Pt
.x
-= ScrollBarInfo
->rcScrollBar
.left
;
460 return SCROLL_TOP_RECT
;
462 if (ThumbPos
+ ThumbSize
<= Pt
.x
)
464 return SCROLL_BOTTOM_RECT
;
472 /***********************************************************************
473 * IntScrollGetScrollBarRect
475 * Compute the scroll bar rectangle, in drawing coordinates (i.e. client
476 * coords for SB_CTL, window coords for SB_VERT and SB_HORZ).
477 * 'arrowSize' returns the width or height of an arrow (depending on
478 * the orientation of the scrollbar), 'thumbSize' returns the size of
479 * the thumb, and 'thumbPos' returns the position of the thumb
480 * relative to the left or to the top.
481 * Return TRUE if the scrollbar is vertical, FALSE if horizontal.
484 IntScrollGetScrollBarRect(HWND Wnd
, INT Bar
, RECT
*Rect
,
485 INT
*ArrowSize
, INT
*ThumbSize
,
492 DWORD Style
, ExStyle
;
494 GetClientRect(Wnd
, &ClientRect
);
495 if (SB_HORZ
== Bar
|| SB_VERT
== Bar
)
497 ClientToScreen(Wnd
, (LPPOINT
) &ClientRect
.left
);
498 ClientToScreen(Wnd
, (LPPOINT
) &ClientRect
.right
);
499 GetWindowRect(Wnd
, &WindowRect
);
501 Style
= GetWindowLongW(Wnd
, GWL_STYLE
);
506 Rect
->left
= ClientRect
.left
- WindowRect
.left
;
507 Rect
->top
= ClientRect
.bottom
- WindowRect
.top
;
508 Rect
->right
= ClientRect
.right
- WindowRect
.left
;
509 Rect
->bottom
= Rect
->top
+ GetSystemMetrics(SM_CYHSCROLL
);
510 if (0 != (Style
& WS_BORDER
))
515 else if (0 != (Style
& WS_VSCROLL
))
523 ExStyle
= GetWindowLongW(Wnd
, GWL_EXSTYLE
);
524 if (0 != (ExStyle
& WS_EX_LEFTSCROLLBAR
))
526 Rect
->left
= ClientRect
.left
- WindowRect
.left
- GetSystemMetrics(SM_CXVSCROLL
);
530 Rect
->left
= ClientRect
.right
- WindowRect
.left
;
532 Rect
->top
= ClientRect
.top
- WindowRect
.top
;
533 Rect
->right
= Rect
->left
+ GetSystemMetrics(SM_CXVSCROLL
);
534 Rect
->bottom
= ClientRect
.bottom
- WindowRect
.top
;
535 if (0 != (Style
& WS_BORDER
))
540 else if (0 != (Style
& WS_HSCROLL
))
549 Vertical
= (0 != (Style
& SBS_VERT
));
558 Pixels
= Rect
->bottom
- Rect
->top
;
562 Pixels
= Rect
->right
- Rect
->left
;
565 if (Pixels
<= 2 * GetSystemMetrics(SM_CXVSCROLL
) + SCROLL_MIN_RECT
)
567 if (SCROLL_MIN_RECT
< Pixels
)
569 *ArrowSize
= (Pixels
- SCROLL_MIN_RECT
) / 2;
575 *ThumbPos
= *ThumbSize
= 0;
581 NtUserGetScrollInfo(Wnd
, Bar
, &Info
);
582 *ArrowSize
= GetSystemMetrics(SM_CXVSCROLL
);
583 Pixels
-= (2 * GetSystemMetrics(SM_CXVSCROLL
));
587 *ThumbSize
= MulDiv(Pixels
, Info
.nPage
, (Info
.nMax
- Info
.nMin
+ 1));
588 if (*ThumbSize
< SCROLL_MIN_THUMB
)
590 *ThumbSize
= SCROLL_MIN_THUMB
;
595 *ThumbSize
= GetSystemMetrics(SM_CXVSCROLL
);
599 if (((pixels
-= *ThumbSize
) < 0) ||
600 ((info
->flags
& ESB_DISABLE_BOTH
) == ESB_DISABLE_BOTH
))
602 if ((Pixels
-= *ThumbSize
) < 0)
605 /* Rectangle too small or scrollbar disabled -> no thumb */
606 *ThumbPos
= *ThumbSize
= 0;
610 INT Max
= Info
.nMax
- max(Info
.nPage
- 1, 0);
611 if (Max
<= Info
.nMin
)
613 *ThumbPos
= *ArrowSize
;
617 *ThumbPos
= *ArrowSize
618 + MulDiv(Pixels
, (Info
.nPos
- Info
.nMin
),
627 /***********************************************************************
628 * IntScrollGetThumbVal
630 * Compute the current scroll position based on the thumb position in pixels
631 * from the top of the scroll-bar.
634 IntScrollGetThumbVal(HWND Wnd
, INT SBType
, PSCROLLBARINFO ScrollBarInfo
,
635 BOOL Vertical
, INT Pos
)
638 INT Pixels
= Vertical
? ScrollBarInfo
->rcScrollBar
.bottom
639 - ScrollBarInfo
->rcScrollBar
.top
640 : ScrollBarInfo
->rcScrollBar
.right
641 - ScrollBarInfo
->rcScrollBar
.left
;
643 si
.cbSize
= sizeof(SCROLLINFO
);
644 si
.fMask
= SIF_RANGE
| SIF_PAGE
;
645 NtUserGetScrollInfo(Wnd
, SBType
, &si
);
646 if ((Pixels
-= 2 * ScrollBarInfo
->dxyLineButton
) <= 0)
651 if ((Pixels
-= (ScrollBarInfo
->xyThumbBottom
- ScrollBarInfo
->xyThumbTop
)) <= 0)
656 Pos
= Pos
- ScrollBarInfo
->dxyLineButton
;
668 Pos
*= si
.nMax
- si
.nMin
;
672 Pos
*= si
.nMax
- si
.nMin
- si
.nPage
+ 1;
674 return si
.nMin
+ ((Pos
+ Pixels
/ 2) / Pixels
);
677 /***********************************************************************
680 static POINT
IntScrollClipPos(PRECT Rect
, POINT Pt
)
682 if (Pt
.x
< Rect
->left
)
686 else if (Rect
->right
< Pt
.x
)
691 if (Pt
.y
< Rect
->top
)
695 else if (Rect
->bottom
< Pt
.y
)
703 /***********************************************************************
704 * IntScrollDrawSizeGrip
706 * Draw the size grip.
709 IntScrollDrawSizeGrip(HWND Wnd
, HDC Dc
)
713 GetClientRect(Wnd
, &Rect
);
714 FillRect(Dc
, &Rect
, GetSysColorBrush(COLOR_SCROLLBAR
));
715 Rect
.left
= max(Rect
.left
, Rect
.right
- GetSystemMetrics(SM_CXVSCROLL
) - 1);
716 Rect
.top
= max(Rect
.top
, Rect
.bottom
- GetSystemMetrics(SM_CYHSCROLL
) - 1);
717 DrawFrameControl(Dc
, &Rect
, DFC_SCROLL
, DFCS_SCROLLSIZEGRIP
);
722 /***********************************************************************
723 * IntScrollHandleKbdEvent
725 * Handle a keyboard event (only for SB_CTL scrollbars with focus).
728 IntScrollHandleKbdEvent(
729 HWND Wnd
/* [in] Handle of window with scrollbar(s) */,
730 WPARAM wParam
/* [in] Variable input including enable state */,
731 LPARAM lParam
/* [in] Variable input including input point */)
733 TRACE("Wnd=%p wParam=%ld lParam=%ld\n", Wnd
, wParam
, lParam
);
735 /* hide caret on first KEYDOWN to prevent flicker */
736 if (0 == (lParam
& PFD_DOUBLEBUFFER_DONTCARE
))
748 wParam
= SB_PAGEDOWN
;
764 wParam
= SB_LINEDOWN
;
771 SendMessageW(GetParent(Wnd
),
772 (0 != (GetWindowLongW(Wnd
, GWL_STYLE
) & SBS_VERT
) ?
773 WM_VSCROLL
: WM_HSCROLL
), wParam
, (LPARAM
) Wnd
);
776 /***********************************************************************
777 * IntScrollHandleScrollEvent
779 * Handle a mouse or timer event for the scrollbar.
780 * 'Pt' is the location of the mouse event in drawing coordinates
783 IntScrollHandleScrollEvent(HWND Wnd
, INT SBType
, UINT Msg
, POINT Pt
)
785 static POINT PrevPt
; /* Previous mouse position for timer events */
786 static UINT TrackThumbPos
; /* Thumb position when tracking started. */
787 static INT LastClickPos
; /* Position in the scroll-bar of the last
788 button-down event. */
789 static INT LastMousePos
; /* Position in the scroll-bar of the last
793 HWND WndOwner
, WndCtl
;
796 SCROLLBARINFO ScrollBarInfo
;
797 SETSCROLLBARINFO NewInfo
;
799 if (! IntGetScrollBarInfo(Wnd
, SBType
, &ScrollBarInfo
))
803 if (SCROLL_NOWHERE
== ScrollTrackHitTest
&& WM_LBUTTONDOWN
!= Msg
)
808 NewInfo
.nTrackPos
= ScrollTrackingVal
;
809 NewInfo
.reserved
= ScrollBarInfo
.reserved
;
810 memcpy(NewInfo
.rgstate
, ScrollBarInfo
.rgstate
, (CCHILDREN_SCROLLBAR
+ 1) * sizeof(DWORD
));
813 && 0 != (GetWindowLongW(Wnd
, GWL_STYLE
) & (SBS_SIZEGRIP
| SBS_SIZEBOX
)))
817 case WM_LBUTTONDOWN
: /* Initialise mouse tracking */
818 HideCaret(Wnd
); /* hide caret while holding down LBUTTON */
821 ScrollTrackHitTest
= HitTest
= SCROLL_THUMB
;
824 GetClientRect(GetParent(GetParent(Wnd
)), &ScrollBarInfo
.rcScrollBar
);
829 ScrollTrackHitTest
= HitTest
= SCROLL_NOWHERE
;
830 if (Wnd
== GetFocus())
842 Dc
= GetDCEx(Wnd
, 0, DCX_CACHE
| ((SB_CTL
== SBType
) ? 0 : DCX_WINDOW
));
843 if (SB_VERT
== SBType
)
847 else if (SB_HORZ
== SBType
)
853 Vertical
= (0 != (GetWindowLongW(Wnd
, GWL_STYLE
) & SBS_VERT
));
855 WndOwner
= (SB_CTL
== SBType
) ? GetParent(Wnd
) : Wnd
;
856 WndCtl
= (SB_CTL
== SBType
) ? Wnd
: NULL
;
860 case WM_LBUTTONDOWN
: /* Initialise mouse tracking */
861 HideCaret(Wnd
); /* hide caret while holding down LBUTTON */
862 ScrollTrackVertical
= Vertical
;
863 ScrollTrackHitTest
= HitTest
= IntScrollHitTest(&ScrollBarInfo
, Vertical
, Pt
, FALSE
);
864 LastClickPos
= Vertical
? (Pt
.y
- ScrollBarInfo
.rcScrollBar
.top
)
865 : (Pt
.x
- ScrollBarInfo
.rcScrollBar
.left
);
866 LastMousePos
= LastClickPos
;
867 TrackThumbPos
= ScrollBarInfo
.xyThumbTop
;
869 if (SB_CTL
== SBType
&& 0 != (GetWindowLongW(Wnd
, GWL_STYLE
) & WS_TABSTOP
))
874 ScrollBarInfo
.rgstate
[ScrollTrackHitTest
] |= STATE_SYSTEM_PRESSED
;
875 NewInfo
.rgstate
[ScrollTrackHitTest
] = ScrollBarInfo
.rgstate
[ScrollTrackHitTest
];
876 NtUserSetScrollBarInfo(Wnd
, IntScrollGetObjectId(SBType
), &NewInfo
);
880 HitTest
= IntScrollHitTest(&ScrollBarInfo
, Vertical
, Pt
, TRUE
);
885 HitTest
= SCROLL_NOWHERE
;
887 /* if scrollbar has focus, show back caret */
888 if (Wnd
== GetFocus())
892 ScrollBarInfo
.rgstate
[ScrollTrackHitTest
] &= ~STATE_SYSTEM_PRESSED
;
893 NewInfo
.rgstate
[ScrollTrackHitTest
] = ScrollBarInfo
.rgstate
[ScrollTrackHitTest
];
894 NtUserSetScrollBarInfo(Wnd
, IntScrollGetObjectId(SBType
), &NewInfo
);
899 HitTest
= IntScrollHitTest(&ScrollBarInfo
, Vertical
, Pt
, FALSE
);
903 return; /* Should never happen */
906 switch (ScrollTrackHitTest
)
908 case SCROLL_NOWHERE
: /* No tracking in progress */
911 case SCROLL_TOP_ARROW
:
912 if (HitTest
== ScrollTrackHitTest
)
914 if ((WM_LBUTTONDOWN
== Msg
) || (WM_SYSTIMER
== Msg
))
916 SendMessageW(WndOwner
, Vertical
? WM_VSCROLL
: WM_HSCROLL
,
917 SB_LINEUP
, (LPARAM
) WndCtl
);
919 SetSystemTimer(Wnd
, SCROLL_TIMER
, (WM_LBUTTONDOWN
== Msg
) ?
920 SCROLL_FIRST_DELAY
: SCROLL_REPEAT_DELAY
,
925 KillSystemTimer(Wnd
, SCROLL_TIMER
);
929 case SCROLL_TOP_RECT
:
930 if (HitTest
== ScrollTrackHitTest
)
932 if ((WM_LBUTTONDOWN
== Msg
) || (WM_SYSTIMER
== Msg
))
934 SendMessageW(WndOwner
, Vertical
? WM_VSCROLL
: WM_HSCROLL
,
935 SB_PAGEUP
, (LPARAM
) WndCtl
);
937 SetSystemTimer(Wnd
, SCROLL_TIMER
, (WM_LBUTTONDOWN
== Msg
) ?
938 SCROLL_FIRST_DELAY
: SCROLL_REPEAT_DELAY
,
943 KillSystemTimer(Wnd
, SCROLL_TIMER
);
948 if (WM_LBUTTONDOWN
== Msg
)
950 ScrollTrackingWin
= Wnd
;
951 ScrollTrackingBar
= SBType
;
952 ScrollTrackingPos
= TrackThumbPos
+ LastMousePos
- LastClickPos
;
953 ScrollTrackingVal
= IntScrollGetThumbVal(Wnd
, SBType
, &ScrollBarInfo
,
954 Vertical
, ScrollTrackingPos
);
955 NewInfo
.nTrackPos
= ScrollTrackingVal
;
956 NtUserSetScrollBarInfo(Wnd
, IntScrollGetObjectId(SBType
), &NewInfo
);
957 IntScrollDrawMovingThumb(Dc
, &ScrollBarInfo
, Vertical
);
959 else if (WM_LBUTTONUP
== Msg
)
961 ScrollTrackingWin
= 0;
962 ScrollTrackingVal
= 0;
963 IntDrawScrollInterior(Wnd
, Dc
, SBType
, Vertical
, &ScrollBarInfo
);
965 else /* WM_MOUSEMOVE */
969 if (! IntScrollPtInRectEx(&ScrollBarInfo
.rcScrollBar
, Pt
, Vertical
))
975 Pt
= IntScrollClipPos(&ScrollBarInfo
.rcScrollBar
, Pt
);
976 Pos
= Vertical
? (Pt
.y
- ScrollBarInfo
.rcScrollBar
.top
)
977 : (Pt
.x
- ScrollBarInfo
.rcScrollBar
.left
);
979 if (Pos
!= LastMousePos
|| ! ScrollMovingThumb
)
982 ScrollTrackingPos
= TrackThumbPos
+ Pos
- LastClickPos
;
983 ScrollTrackingVal
= IntScrollGetThumbVal(Wnd
, SBType
, &ScrollBarInfo
,
984 Vertical
, ScrollTrackingPos
);
985 NewInfo
.nTrackPos
= ScrollTrackingVal
;
986 NtUserSetScrollBarInfo(Wnd
, IntScrollGetObjectId(SBType
), &NewInfo
);
987 IntScrollDrawMovingThumb(Dc
, &ScrollBarInfo
, Vertical
);
988 SendMessageW(WndOwner
, Vertical
? WM_VSCROLL
: WM_HSCROLL
,
989 MAKEWPARAM(SB_THUMBTRACK
, ScrollTrackingVal
),
995 case SCROLL_BOTTOM_RECT
:
996 if (HitTest
== ScrollTrackHitTest
)
998 if ((WM_LBUTTONDOWN
== Msg
) || (WM_SYSTIMER
== Msg
))
1000 SendMessageW(WndOwner
, Vertical
? WM_VSCROLL
: WM_HSCROLL
,
1001 SB_PAGEDOWN
, (LPARAM
) WndCtl
);
1003 SetSystemTimer(Wnd
, SCROLL_TIMER
, (WM_LBUTTONDOWN
== Msg
) ?
1004 SCROLL_FIRST_DELAY
: SCROLL_REPEAT_DELAY
,
1009 KillSystemTimer(Wnd
, SCROLL_TIMER
);
1013 case SCROLL_BOTTOM_ARROW
:
1014 if (HitTest
== ScrollTrackHitTest
)
1016 if ((WM_LBUTTONDOWN
== Msg
) || (WM_SYSTIMER
== Msg
))
1018 SendMessageW(WndOwner
, Vertical
? WM_VSCROLL
: WM_HSCROLL
,
1019 SB_LINEDOWN
, (LPARAM
) WndCtl
);
1021 SetSystemTimer(Wnd
, SCROLL_TIMER
, (WM_LBUTTONDOWN
== Msg
) ?
1022 SCROLL_FIRST_DELAY
: SCROLL_REPEAT_DELAY
,
1027 KillSystemTimer(Wnd
, SCROLL_TIMER
);
1032 if (WM_LBUTTONDOWN
== Msg
)
1034 if (SCROLL_THUMB
== HitTest
)
1036 UINT Val
= IntScrollGetThumbVal(Wnd
, SBType
, &ScrollBarInfo
, Vertical
,
1037 TrackThumbPos
+ LastMousePos
- LastClickPos
);
1038 SendMessageW(WndOwner
, Vertical
? WM_VSCROLL
: WM_HSCROLL
,
1039 MAKEWPARAM(SB_THUMBTRACK
, Val
), (LPARAM
) WndCtl
);
1043 if (WM_LBUTTONUP
== Msg
)
1045 HitTest
= ScrollTrackHitTest
;
1046 ScrollTrackHitTest
= SCROLL_NOWHERE
; /* Terminate tracking */
1048 if (SCROLL_THUMB
== HitTest
)
1050 UINT Val
= IntScrollGetThumbVal(Wnd
, SBType
, &ScrollBarInfo
, Vertical
,
1051 TrackThumbPos
+ LastMousePos
- LastClickPos
);
1052 SendMessageW(WndOwner
, Vertical
? WM_VSCROLL
: WM_HSCROLL
,
1053 MAKEWPARAM(SB_THUMBPOSITION
, Val
), (LPARAM
) WndCtl
);
1055 SendMessageW(WndOwner
, Vertical
? WM_VSCROLL
: WM_HSCROLL
,
1056 SB_ENDSCROLL
, (LPARAM
) WndCtl
);
1063 /***********************************************************************
1064 * IntScrollCreateScrollBar
1066 * Create a scroll bar
1068 static void IntScrollCreateScrollBar(
1069 HWND Wnd
/* [in] Handle of window with scrollbar(s) */,
1070 LPCREATESTRUCTW lpCreate
/* [in] The style and place of the scroll bar */)
1074 Info
.cbSize
= sizeof(SCROLLINFO
);
1075 Info
.fMask
= SIF_RANGE
| SIF_PAGE
| SIF_POS
;
1081 NtUserSetScrollInfo(Wnd
, SB_CTL
, &Info
, FALSE
);
1083 TRACE("hwnd=%p lpCreate=%p\n", Wnd
, lpCreate
);
1086 if (lpCreate
->style
& WS_DISABLED
)
1088 info
->flags
= ESB_DISABLE_BOTH
;
1089 TRACE("Created WS_DISABLED scrollbar\n");
1093 if (0 != (lpCreate
->style
& (SBS_SIZEGRIP
| SBS_SIZEBOX
)))
1095 if (0 != (lpCreate
->style
& SBS_SIZEBOXTOPLEFTALIGN
))
1097 MoveWindow(Wnd
, lpCreate
->x
, lpCreate
->y
, GetSystemMetrics(SM_CXVSCROLL
) + 1,
1098 GetSystemMetrics(SM_CYHSCROLL
) + 1, FALSE
);
1100 else if (0 != (lpCreate
->style
& SBS_SIZEBOXBOTTOMRIGHTALIGN
))
1102 MoveWindow(Wnd
, lpCreate
->x
+ lpCreate
->cx
- GetSystemMetrics(SM_CXVSCROLL
) - 1,
1103 lpCreate
->y
+ lpCreate
->cy
- GetSystemMetrics(SM_CYHSCROLL
) - 1,
1104 GetSystemMetrics(SM_CXVSCROLL
) + 1,
1105 GetSystemMetrics(SM_CYHSCROLL
) + 1, FALSE
);
1108 else if (0 != (lpCreate
->style
& SBS_VERT
))
1110 if (0 != (lpCreate
->style
& SBS_LEFTALIGN
))
1112 MoveWindow(Wnd
, lpCreate
->x
, lpCreate
->y
,
1113 GetSystemMetrics(SM_CXVSCROLL
) + 1, lpCreate
->cy
, FALSE
);
1115 else if (0 != (lpCreate
->style
& SBS_RIGHTALIGN
))
1118 lpCreate
->x
+ lpCreate
->cx
- GetSystemMetrics(SM_CXVSCROLL
) - 1,
1120 GetSystemMetrics(SM_CXVSCROLL
) + 1, lpCreate
->cy
, FALSE
);
1125 if (0 != (lpCreate
->style
& SBS_TOPALIGN
))
1127 MoveWindow(Wnd
, lpCreate
->x
, lpCreate
->y
,
1128 lpCreate
->cx
, GetSystemMetrics(SM_CYHSCROLL
) + 1, FALSE
);
1130 else if (0 != (lpCreate
->style
& SBS_BOTTOMALIGN
))
1134 lpCreate
->y
+ lpCreate
->cy
- GetSystemMetrics(SM_CYHSCROLL
) - 1,
1135 lpCreate
->cx
, GetSystemMetrics(SM_CYHSCROLL
) + 1, FALSE
);
1141 IntScrollGetScrollPos(HWND Wnd
, INT Bar
)
1143 SCROLLINFO ScrollInfo
;
1145 ScrollInfo
.cbSize
= sizeof(SCROLLINFO
);
1146 ScrollInfo
.fMask
= SIF_POS
;
1147 if (! NtUserGetScrollInfo(Wnd
, Bar
, &ScrollInfo
))
1152 return ScrollInfo
.nPos
;
1155 static BOOL FASTCALL
1156 IntScrollGetScrollRange(HWND Wnd
, int Bar
, LPINT MinPos
, LPINT MaxPos
)
1159 SCROLLINFO ScrollInfo
;
1161 if (NULL
== MinPos
|| NULL
== MaxPos
)
1163 SetLastError(ERROR_INVALID_PARAMETER
);
1167 ScrollInfo
.cbSize
= sizeof(SCROLLINFO
);
1168 ScrollInfo
.fMask
= SIF_RANGE
;
1169 Result
= NtUserGetScrollInfo(Wnd
, Bar
, &ScrollInfo
);
1172 *MinPos
= ScrollInfo
.nMin
;
1173 *MaxPos
= ScrollInfo
.nMax
;
1179 /* USER32 INTERNAL FUNCTIONS **************************************************/
1181 /***********************************************************************
1182 * ScrollTrackScrollBar
1184 * Track a mouse button press on a scroll-bar.
1185 * pt is in screen-coordinates for non-client scroll bars.
1188 ScrollTrackScrollBar(HWND Wnd
, INT SBType
, POINT Pt
)
1192 UINT XOffset
, YOffset
;
1195 if (SB_CTL
!= SBType
)
1197 GetWindowRect(Wnd
, &WindowRect
);
1199 Pt
.x
-= WindowRect
.left
;
1200 Pt
.y
-= WindowRect
.top
;
1202 TopLeft
.x
= WindowRect
.left
;
1203 TopLeft
.y
= WindowRect
.top
;
1204 ScreenToClient(Wnd
, &TopLeft
);
1205 XOffset
= - TopLeft
.x
;
1206 YOffset
= - TopLeft
.y
;
1214 IntScrollHandleScrollEvent(Wnd
, SBType
, WM_LBUTTONDOWN
, Pt
);
1218 if (! GetMessageW(&Msg
, 0, 0, 0))
1222 if (CallMsgFilterW(&Msg
, MSGF_SCROLLBAR
))
1232 Pt
.x
= LOWORD(Msg
.lParam
) + XOffset
;
1233 Pt
.y
= HIWORD(Msg
.lParam
) + YOffset
;
1234 IntScrollHandleScrollEvent(Wnd
, SBType
, Msg
.message
, Pt
);
1237 TranslateMessage(&Msg
);
1238 DispatchMessageW(&Msg
);
1242 if (! IsWindow(Wnd
))
1248 while (WM_LBUTTONUP
!= Msg
.message
);
1252 /***********************************************************************
1255 static LRESULT WINAPI
1256 ScrollBarWndProc(WNDPROC DefWindowProc
, HWND Wnd
, UINT Msg
, WPARAM wParam
, LPARAM lParam
)
1258 if (! IsWindow(Wnd
))
1266 IntScrollCreateScrollBar(Wnd
, (LPCREATESTRUCTW
) lParam
);
1272 // SCROLLBAR_INFO *infoPtr;
1273 // if ((infoPtr = SCROLL_GetScrollBarInfo( hwnd, SB_CTL )))
1275 // infoPtr->flags = wParam ? ESB_ENABLE_BOTH : ESB_DISABLE_BOTH;
1276 // SCROLL_RefreshScrollBar(hwnd, SB_CTL, TRUE, TRUE);
1279 DbgPrint("ScrollBarWndProc WM_ENABLE\n");
1280 NtUserEnableScrollBar(Wnd
,SB_CTL
,(wParam
? ESB_ENABLE_BOTH
: ESB_DISABLE_BOTH
));
1281 /* Refresh Scrollbars. */
1282 hdc
= GetDCEx( Wnd
, 0, DCX_CACHE
);
1284 IntDrawScrollBar( Wnd
, hdc
, SB_CTL
);
1285 ReleaseDC( Wnd
, hdc
);
1290 case WM_LBUTTONDBLCLK
:
1291 case WM_LBUTTONDOWN
:
1295 Pt
.x
= (short)LOWORD(lParam
);
1296 Pt
.y
= (short)HIWORD(lParam
);
1297 ScrollTrackScrollBar(Wnd
, SB_CTL
, Pt
);
1307 Pt
.x
= (short)LOWORD(lParam
);
1308 Pt
.y
= (short)HIWORD(lParam
);
1309 IntScrollHandleScrollEvent(Wnd
, SB_CTL
, Msg
, Pt
);
1314 IntScrollHandleKbdEvent(Wnd
, wParam
, lParam
);
1323 /* Create a caret when a ScrollBar get focus */
1325 int ArrowSize
, ThumbSize
, ThumbPos
, Vertical
;
1327 Vertical
= IntScrollGetScrollBarRect(Wnd
, SB_CTL
, &Rect
,
1328 &ArrowSize
, &ThumbSize
, &ThumbPos
);
1331 CreateCaret(Wnd
, (HBITMAP
) 1, ThumbSize
- 2, Rect
.bottom
- Rect
.top
- 2);
1332 SetCaretPos(ThumbPos
+ 1, Rect
.top
+ 1);
1336 CreateCaret(Wnd
, (HBITMAP
) 1, Rect
.right
- Rect
.left
- 2, ThumbSize
- 2);
1337 SetCaretPos(Rect
.top
+ 1, ThumbPos
+ 1);
1346 int ArrowSize
, ThumbSize
, ThumbPos
, Vertical
;
1348 Vertical
= IntScrollGetScrollBarRect(Wnd
, SB_CTL
, &Rect
,
1349 &ArrowSize
, &ThumbSize
, &ThumbPos
);
1352 Rect
.left
= ThumbPos
+ 1;
1353 Rect
.right
= Rect
.left
+ ThumbSize
;
1357 Rect
.top
= ThumbPos
+ 1;
1358 Rect
.bottom
= Rect
.top
+ ThumbSize
;
1361 NtUserInvalidateRect(Wnd
, &Rect
, FALSE
);
1370 return DLGC_WANTARROWS
; /* Windows returns this value */
1377 Dc
= (0 != wParam
? (HDC
) wParam
: BeginPaint(Wnd
, &Ps
));
1379 if (GetWindowLongW(Wnd
, GWL_STYLE
) & SBS_SIZEGRIP
)
1381 IntScrollDrawSizeGrip(Wnd
, Dc
);
1383 else if (0 != (GetWindowLongW(Wnd
, GWL_STYLE
) & SBS_SIZEBOX
))
1386 GetClientRect(Wnd
, &Rect
);
1387 FillRect(Dc
, &Rect
, GetSysColorBrush(COLOR_SCROLLBAR
));
1391 IntDrawScrollBar(Wnd
, Dc
, SB_CTL
/*, TRUE, TRUE*/);
1402 return SetScrollPos(Wnd
, SB_CTL
, wParam
, (BOOL
) lParam
);
1405 return IntScrollGetScrollPos(Wnd
, SB_CTL
);
1409 INT OldPos
= IntScrollGetScrollPos(Wnd
, SB_CTL
);
1410 SetScrollRange(Wnd
, SB_CTL
, wParam
, lParam
, FALSE
);
1411 if (OldPos
!= IntScrollGetScrollPos(Wnd
, SB_CTL
))
1419 return IntScrollGetScrollRange(Wnd
, SB_CTL
, (LPINT
) wParam
, (LPINT
) lParam
);
1421 case SBM_ENABLE_ARROWS
:
1422 return EnableScrollBar(Wnd
, SB_CTL
, wParam
);
1424 case SBM_SETRANGEREDRAW
:
1426 INT OldPos
= IntScrollGetScrollPos(Wnd
, SB_CTL
);
1427 SetScrollRange(Wnd
, SB_CTL
, wParam
, lParam
, TRUE
);
1428 if (OldPos
!= IntScrollGetScrollPos(Wnd
, SB_CTL
))
1435 case SBM_SETSCROLLINFO
:
1436 return NtUserSetScrollInfo(Wnd
, SB_CTL
, (SCROLLINFO
*) lParam
, wParam
);
1438 case SBM_GETSCROLLINFO
:
1439 return NtUserGetScrollInfo(Wnd
, SB_CTL
, (SCROLLINFO
*) 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
);
1464 static LRESULT WINAPI
1465 ScrollBarWndProcW(HWND Wnd
, UINT Msg
, WPARAM wParam
, LPARAM lParam
)
1467 return ScrollBarWndProc(DefWindowProcW
, Wnd
, Msg
, wParam
, lParam
);
1470 static LRESULT WINAPI
1471 ScrollBarWndProcA(HWND Wnd
, UINT Msg
, WPARAM wParam
, LPARAM lParam
)
1473 return ScrollBarWndProc(DefWindowProcA
, Wnd
, Msg
, wParam
, lParam
);
1477 /* PUBLIC FUNCTIONS ***********************************************************/
1483 EnableScrollBar(HWND hWnd
, UINT wSBflags
, UINT wArrows
)
1485 return NtUserEnableScrollBar(hWnd
, wSBflags
, wArrows
);
1492 GetScrollBarInfo(HWND hWnd
, LONG idObject
, PSCROLLBARINFO psbi
)
1494 return NtUserGetScrollBarInfo(hWnd
, idObject
, psbi
);
1501 GetScrollInfo(HWND Wnd
, INT SBType
, LPSCROLLINFO Info
)
1503 if (SB_CTL
== SBType
)
1505 return SendMessageW(Wnd
, SBM_GETSCROLLINFO
, 0, (LPARAM
) Info
);
1509 return NtUserGetScrollInfo(Wnd
, SBType
, Info
);
1517 GetScrollPos(HWND Wnd
, INT Bar
)
1519 TRACE("Wnd=%p Bar=%d\n", Wnd
, Bar
);
1521 /* Refer SB_CTL requests to the window */
1524 return SendMessageW(Wnd
, SBM_GETPOS
, (WPARAM
) 0, (LPARAM
) 0);
1528 return IntScrollGetScrollPos(Wnd
, Bar
);
1536 GetScrollRange(HWND Wnd
, int Bar
, LPINT MinPos
, LPINT MaxPos
)
1538 TRACE("Wnd=%x Bar=%d Min=%p Max=%p\n", Wnd
, Bar
, MinPos
, MaxPos
);
1540 /* Refer SB_CTL requests to the window */
1543 return SendMessageW(Wnd
, SBM_GETRANGE
, (WPARAM
) MinPos
, (LPARAM
) MaxPos
);
1547 return IntScrollGetScrollRange(Wnd
, Bar
, MinPos
, MaxPos
);
1555 SetScrollInfo(HWND Wnd
, int SBType
, LPCSCROLLINFO Info
, BOOL bRedraw
)
1557 if (SB_CTL
== SBType
)
1559 return SendMessageW(Wnd
, SBM_SETSCROLLINFO
, (WPARAM
) bRedraw
, (LPARAM
) Info
);
1563 return NtUserSetScrollInfo(Wnd
, SBType
, Info
, bRedraw
);
1571 SetScrollPos(HWND hWnd
, INT nBar
, INT nPos
, BOOL bRedraw
)
1574 SCROLLINFO ScrollInfo
;
1576 ScrollInfo
.cbSize
= sizeof(SCROLLINFO
);
1577 ScrollInfo
.fMask
= SIF_POS
;
1580 * Call NtUserGetScrollInfo() to get the previous position that
1581 * we will later return.
1583 if (NtUserGetScrollInfo(hWnd
, nBar
, &ScrollInfo
))
1585 Result
= ScrollInfo
.nPos
;
1588 ScrollInfo
.nPos
= nPos
;
1589 /* Finally set the new position */
1590 NtUserSetScrollInfo(hWnd
, nBar
, &ScrollInfo
, bRedraw
);
1601 SetScrollRange(HWND hWnd
, INT nBar
, INT nMinPos
, INT nMaxPos
, BOOL bRedraw
)
1603 SCROLLINFO ScrollInfo
;
1605 ScrollInfo
.cbSize
= sizeof(SCROLLINFO
);
1606 ScrollInfo
.fMask
= SIF_RANGE
;
1607 ScrollInfo
.nMin
= nMinPos
;
1608 ScrollInfo
.nMax
= nMaxPos
;
1609 NtUserSetScrollInfo(hWnd
, nBar
, &ScrollInfo
, bRedraw
);
1618 ShowScrollBar(HWND hWnd
, INT wBar
, BOOL bShow
)
1620 return NtUserShowScrollBar(hWnd
, wBar
, bShow
);