2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS uxtheme.dll
4 * FILE: dll/win32/uxtheme/ncscrollbar.c
5 * PURPOSE: uxtheme scrollbar support
6 * PROGRAMMER: Giannis Adamopoulos
7 * This file is heavily based on code from the wine project:
8 * Copyright 1993 Martin Ayotte
9 * Copyright 1994, 1996 Alexandre Julliard
16 static BOOL SCROLL_trackVertical
;
17 static enum SCROLL_HITTEST SCROLL_trackHitTest
;
18 /* Is the moving thumb being displayed? */
19 static BOOL SCROLL_MovingThumb
= FALSE
;
20 static HWND SCROLL_TrackingWin
= 0;
21 static INT SCROLL_TrackingBar
= 0;
22 static INT SCROLL_TrackingPos
= 0;
23 static INT SCROLL_TrackingVal
= 0;
25 static void ScreenToWindow( HWND hWnd
, POINT
* pt
)
28 GetWindowRect(hWnd
, &rcWnd
);
33 static BOOL
SCROLL_IsVertical(HWND hwnd
, INT nBar
)
47 static LONG
SCROLL_getObjectId(INT nBar
)
61 /***********************************************************************
64 static BOOL
SCROLL_PtInRectEx( LPRECT lpRect
, POINT pt
, BOOL vertical
)
69 /* Pad hit rect to allow mouse to be dragged outside of scrollbar and
70 * still be considered in the scrollbar. */
73 scrollbarWidth
= lpRect
->right
- lpRect
->left
;
74 rect
.left
-= scrollbarWidth
*8;
75 rect
.right
+= scrollbarWidth
*8;
76 rect
.top
-= scrollbarWidth
*2;
77 rect
.bottom
+= scrollbarWidth
*2;
81 scrollbarWidth
= lpRect
->bottom
- lpRect
->top
;
82 rect
.left
-= scrollbarWidth
*2;
83 rect
.right
+= scrollbarWidth
*2;
84 rect
.top
-= scrollbarWidth
*8;
85 rect
.bottom
+= scrollbarWidth
*8;
87 return PtInRect( &rect
, pt
);
91 /***********************************************************************
94 * Scroll-bar hit testing (don't confuse this with WM_NCHITTEST!).
96 static enum SCROLL_HITTEST
SCROLL_HitTest( HWND hwnd
, SCROLLBARINFO
* psbi
, BOOL vertical
,
97 POINT pt
, BOOL bDragging
)
99 if ( (bDragging
&& !SCROLL_PtInRectEx( &psbi
->rcScrollBar
, pt
, vertical
)) ||
100 (!PtInRect( &psbi
->rcScrollBar
, pt
)) )
102 return SCROLL_NOWHERE
;
107 if (pt
.y
< psbi
->rcScrollBar
.top
+ psbi
->dxyLineButton
)
108 return SCROLL_TOP_ARROW
;
109 if (pt
.y
>= psbi
->rcScrollBar
.bottom
- psbi
->dxyLineButton
)
110 return SCROLL_BOTTOM_ARROW
;
111 if (!psbi
->xyThumbTop
)
112 return SCROLL_TOP_RECT
;
113 pt
.y
-= psbi
->rcScrollBar
.top
;
114 if (pt
.y
< psbi
->xyThumbTop
)
115 return SCROLL_TOP_RECT
;
116 if (pt
.y
>= psbi
->xyThumbTop
+ psbi
->dxyLineButton
)
117 return SCROLL_BOTTOM_RECT
;
119 else /* horizontal */
121 if (pt
.x
< psbi
->rcScrollBar
.left
+ psbi
->dxyLineButton
)
122 return SCROLL_TOP_ARROW
;
123 if (pt
.x
>= psbi
->rcScrollBar
.right
- psbi
->dxyLineButton
)
124 return SCROLL_BOTTOM_ARROW
;
125 if (!psbi
->xyThumbTop
)
126 return SCROLL_TOP_RECT
;
127 pt
.x
-= psbi
->rcScrollBar
.left
;
128 if (pt
.x
< psbi
->xyThumbTop
)
129 return SCROLL_TOP_RECT
;
130 if (pt
.x
>= psbi
->xyThumbTop
+ psbi
->dxyLineButton
)
131 return SCROLL_BOTTOM_RECT
;
136 static void SCROLL_ThemeDrawPart(PDRAW_CONTEXT pcontext
, int iPartId
,int iStateId
, SCROLLBARINFO
* psbi
, int htCurrent
, int htDown
, int htHot
, RECT
* r
)
138 if(psbi
->rgstate
[htCurrent
] & STATE_SYSTEM_UNAVAILABLE
)
139 iStateId
+= BUTTON_DISABLED
- BUTTON_NORMAL
;
140 else if (htHot
== htCurrent
)
141 iStateId
+= BUTTON_HOT
- BUTTON_NORMAL
;
142 else if (htDown
== htCurrent
)
143 iStateId
+= BUTTON_PRESSED
- BUTTON_NORMAL
;
145 DrawThemeBackground(pcontext
->scrolltheme
, pcontext
->hDC
, iPartId
, iStateId
, r
, NULL
);
148 /***********************************************************************
151 * Draw the scroll bar arrows.
153 static void SCROLL_DrawArrows( PDRAW_CONTEXT pcontext
, SCROLLBARINFO
* psbi
,
154 BOOL vertical
, int htDown
, int htHot
)
159 r
= psbi
->rcScrollBar
;
162 r
.bottom
= r
.top
+ psbi
->dxyLineButton
;
163 iStateId
= ABS_UPNORMAL
;
167 r
.right
= r
.left
+ psbi
->dxyLineButton
;
168 iStateId
= ABS_LEFTNORMAL
;
171 SCROLL_ThemeDrawPart(pcontext
, SBP_ARROWBTN
, iStateId
, psbi
, SCROLL_TOP_ARROW
, htDown
, htHot
, &r
);
173 r
= psbi
->rcScrollBar
;
176 r
.top
= r
.bottom
- psbi
->dxyLineButton
;
177 iStateId
= ABS_DOWNNORMAL
;
181 iStateId
= ABS_RIGHTNORMAL
;
182 r
.left
= r
.right
- psbi
->dxyLineButton
;
185 SCROLL_ThemeDrawPart(pcontext
, SBP_ARROWBTN
, iStateId
, psbi
, SCROLL_BOTTOM_ARROW
, htDown
, htHot
, &r
);
188 static void SCROLL_DrawInterior( PDRAW_CONTEXT pcontext
, SCROLLBARINFO
* psbi
,
189 INT thumbPos
, BOOL vertical
,
190 int htDown
, int htHot
)
194 r
= psbi
->rcScrollBar
;
197 r
.top
+= psbi
->dxyLineButton
;
198 r
.bottom
-= (psbi
->dxyLineButton
);
202 r
.left
+= psbi
->dxyLineButton
;
203 r
.right
-= psbi
->dxyLineButton
;
206 /* Draw the scroll rectangles and thumb */
208 if (!thumbPos
) /* No thumb to draw */
211 SCROLL_ThemeDrawPart(pcontext
, vertical
? SBP_UPPERTRACKVERT
: SBP_UPPERTRACKHORZ
, BUTTON_NORMAL
, psbi
, SCROLL_THUMB
, 0, 0, &rcPart
);
218 rcPart
.bottom
= rcPart
.top
+ thumbPos
- psbi
->dxyLineButton
;
219 SCROLL_ThemeDrawPart(pcontext
, SBP_UPPERTRACKVERT
, BUTTON_NORMAL
, psbi
, SCROLL_TOP_RECT
, htDown
, htHot
, &rcPart
);
220 r
.top
= rcPart
.bottom
;
223 rcPart
.top
+= psbi
->dxyLineButton
;
224 SCROLL_ThemeDrawPart(pcontext
, SBP_LOWERTRACKVERT
, BUTTON_NORMAL
, psbi
, SCROLL_BOTTOM_RECT
, htDown
, htHot
, &rcPart
);
225 r
.bottom
= rcPart
.top
;
227 SCROLL_ThemeDrawPart(pcontext
, SBP_THUMBBTNVERT
, BUTTON_NORMAL
, psbi
, SCROLL_THUMB
, htDown
, htHot
, &r
);
228 SCROLL_ThemeDrawPart(pcontext
, SBP_GRIPPERVERT
, BUTTON_NORMAL
, psbi
, SCROLL_THUMB
, htDown
, htHot
, &r
);
230 else /* horizontal */
233 rcPart
.right
= rcPart
.left
+ thumbPos
- psbi
->dxyLineButton
;
234 SCROLL_ThemeDrawPart(pcontext
, SBP_UPPERTRACKHORZ
, BUTTON_NORMAL
, psbi
, SCROLL_TOP_RECT
, htDown
, htHot
, &rcPart
);
235 r
.left
= rcPart
.right
;
238 rcPart
.left
+= psbi
->dxyLineButton
;
239 SCROLL_ThemeDrawPart(pcontext
, SBP_LOWERTRACKHORZ
, BUTTON_NORMAL
, psbi
, SCROLL_BOTTOM_RECT
, htDown
, htHot
, &rcPart
);
240 r
.right
= rcPart
.left
;
242 SCROLL_ThemeDrawPart(pcontext
, SBP_THUMBBTNHORZ
, BUTTON_NORMAL
, psbi
, SCROLL_THUMB
, htDown
, htHot
, &r
);
243 SCROLL_ThemeDrawPart(pcontext
, SBP_GRIPPERHORZ
, BUTTON_NORMAL
, psbi
, SCROLL_THUMB
, htDown
, htHot
, &r
);
247 static void SCROLL_DrawMovingThumb( PDRAW_CONTEXT pcontext
, SCROLLBARINFO
* psbi
, BOOL vertical
)
249 INT pos
= SCROLL_TrackingPos
;
253 max_size
= psbi
->rcScrollBar
.bottom
- psbi
->rcScrollBar
.top
;
255 max_size
= psbi
->rcScrollBar
.right
- psbi
->rcScrollBar
.left
;
257 max_size
-= (psbi
->dxyLineButton
-SCROLL_ARROW_THUMB_OVERLAP
) + psbi
->dxyLineButton
;
259 if( pos
< (psbi
->dxyLineButton
-SCROLL_ARROW_THUMB_OVERLAP
) )
260 pos
= (psbi
->dxyLineButton
-SCROLL_ARROW_THUMB_OVERLAP
);
261 else if( pos
> max_size
)
264 SCROLL_DrawInterior(pcontext
, psbi
, pos
, vertical
, SCROLL_THUMB
, 0);
266 SCROLL_MovingThumb
= !SCROLL_MovingThumb
;
271 ThemeDrawScrollBar(PDRAW_CONTEXT pcontext
, INT nBar
, POINT
* pt
)
276 enum SCROLL_HITTEST htHot
= SCROLL_NOWHERE
;
278 /* Retrieve scrollbar info */
279 sbi
.cbSize
= sizeof(sbi
);
280 si
.cbSize
= sizeof(si
);
282 GetScrollInfo(pcontext
->hWnd
, nBar
, &si
);
283 GetScrollBarInfo(pcontext
->hWnd
, SCROLL_getObjectId(nBar
), &sbi
);
284 vertical
= SCROLL_IsVertical(pcontext
->hWnd
, nBar
);
285 if(sbi
.rgstate
[SCROLL_TOP_ARROW
] & STATE_SYSTEM_UNAVAILABLE
&&
286 sbi
.rgstate
[SCROLL_BOTTOM_ARROW
] & STATE_SYSTEM_UNAVAILABLE
)
291 /* The scrollbar rect is in screen coordinates */
292 OffsetRect(&sbi
.rcScrollBar
, -pcontext
->wi
.rcWindow
.left
, -pcontext
->wi
.rcWindow
.top
);
296 ScreenToWindow(pcontext
->hWnd
, pt
);
297 htHot
= SCROLL_HitTest(pcontext
->hWnd
, &sbi
, vertical
, *pt
, FALSE
);
300 if (((nBar
== SB_VERT
) && !(pcontext
->wi
.dwStyle
& WS_VSCROLL
)) ||
301 ((nBar
== SB_HORZ
) && !(pcontext
->wi
.dwStyle
& WS_HSCROLL
))) return;
303 /* do not draw if the scrollbar rectangle is empty */
304 if(IsRectEmpty(&sbi
.rcScrollBar
)) return;
306 /* Draw the scrollbar */
307 SCROLL_DrawArrows( pcontext
, &sbi
, vertical
, 0, htHot
);
308 SCROLL_DrawInterior( pcontext
, &sbi
, sbi
.xyThumbTop
, vertical
, 0, htHot
);
313 /***********************************************************************
316 static POINT
SCROLL_ClipPos( LPRECT lpRect
, POINT pt
)
318 if( pt
.x
< lpRect
->left
)
321 if( pt
.x
> lpRect
->right
)
322 pt
.x
= lpRect
->right
;
324 if( pt
.y
< lpRect
->top
)
327 if( pt
.y
> lpRect
->bottom
)
328 pt
.y
= lpRect
->bottom
;
335 /***********************************************************************
338 * Compute the current scroll position based on the thumb position in pixels
339 * from the top of the scroll-bar.
341 static UINT
SCROLL_GetThumbVal( SCROLLINFO
*psi
, RECT
*rect
,
342 BOOL vertical
, INT pos
)
345 INT pixels
= vertical
? rect
->bottom
-rect
->top
: rect
->right
-rect
->left
;
348 if ((pixels
-= 2*(GetSystemMetrics(SM_CXVSCROLL
) - SCROLL_ARROW_THUMB_OVERLAP
)) <= 0)
353 thumbSize
= MulDiv(pixels
,psi
->nPage
,(psi
->nMax
-psi
->nMin
+1));
354 if (thumbSize
< SCROLL_MIN_THUMB
) thumbSize
= SCROLL_MIN_THUMB
;
356 else thumbSize
= GetSystemMetrics(SM_CXVSCROLL
);
358 if ((pixels
-= thumbSize
) <= 0) return psi
->nMin
;
360 pos
= max( 0, pos
- (GetSystemMetrics(SM_CXVSCROLL
) - SCROLL_ARROW_THUMB_OVERLAP
) );
361 if (pos
> pixels
) pos
= pixels
;
364 range
= psi
->nMax
- psi
->nMin
;
366 range
= psi
->nMax
- psi
->nMin
- psi
->nPage
+ 1;
368 return psi
->nMin
+ MulDiv(pos
, range
, pixels
);
372 SCROLL_HandleScrollEvent( HWND hwnd
, INT nBar
, UINT msg
, POINT pt
)
374 /* Previous mouse position for timer events */
376 /* Thumb position when tracking started. */
377 static UINT trackThumbPos
;
378 /* Position in the scroll-bar of the last button-down event. */
379 static INT lastClickPos
;
380 /* Position in the scroll-bar of the last mouse event. */
381 static INT lastMousePos
;
383 enum SCROLL_HITTEST hittest
;
384 HWND hwndOwner
, hwndCtl
;
388 DRAW_CONTEXT context
;
390 si
.cbSize
= sizeof(si
);
391 sbi
.cbSize
= sizeof(sbi
);
393 GetScrollInfo(hwnd
, nBar
, &si
);
394 GetScrollBarInfo(hwnd
, SCROLL_getObjectId(nBar
), &sbi
);
395 vertical
= SCROLL_IsVertical(hwnd
, nBar
);
396 if(sbi
.rgstate
[SCROLL_TOP_ARROW
] & STATE_SYSTEM_UNAVAILABLE
&&
397 sbi
.rgstate
[SCROLL_BOTTOM_ARROW
] & STATE_SYSTEM_UNAVAILABLE
)
402 /* The scrollbar rect is in screen coordinates */
403 OffsetRect(&sbi
.rcScrollBar
, -context
.wi
.rcWindow
.left
, -context
.wi
.rcWindow
.top
);
405 if ((SCROLL_trackHitTest
== SCROLL_NOWHERE
) && (msg
!= WM_LBUTTONDOWN
))
408 ThemeInitDrawContext(&context
, hwnd
, 0);
410 hwndOwner
= (nBar
== SB_CTL
) ? GetParent(hwnd
) : hwnd
;
411 hwndCtl
= (nBar
== SB_CTL
) ? hwnd
: 0;
415 case WM_LBUTTONDOWN
: /* Initialise mouse tracking */
416 HideCaret(hwnd
); /* hide caret while holding down LBUTTON */
417 SCROLL_trackVertical
= vertical
;
418 SCROLL_trackHitTest
= hittest
= SCROLL_HitTest( hwnd
, &sbi
, vertical
, pt
, FALSE
);
419 lastClickPos
= vertical
? (pt
.y
- sbi
.rcScrollBar
.top
) : (pt
.x
- sbi
.rcScrollBar
.left
);
420 lastMousePos
= lastClickPos
;
421 trackThumbPos
= sbi
.xyThumbTop
;
427 hittest
= SCROLL_HitTest( hwnd
, &sbi
, vertical
, pt
, TRUE
);
432 hittest
= SCROLL_NOWHERE
;
434 /* if scrollbar has focus, show back caret */
435 if (hwnd
==GetFocus())
441 hittest
= SCROLL_HitTest( hwnd
, &sbi
, vertical
, pt
, FALSE
);
445 return; /* Should never happen */
448 //TRACE("Event: hwnd=%p bar=%d msg=%s pt=%d,%d hit=%d\n",
449 // hwnd, nBar, SPY_GetMsgName(msg,hwnd), pt.x, pt.y, hittest );
451 switch(SCROLL_trackHitTest
)
453 case SCROLL_NOWHERE
: /* No tracking in progress */
456 case SCROLL_TOP_ARROW
:
457 if (hittest
== SCROLL_trackHitTest
)
459 SCROLL_DrawArrows( &context
, &sbi
, vertical
, SCROLL_trackHitTest
, 0 );
460 if ((msg
== WM_LBUTTONDOWN
) || (msg
== WM_SYSTIMER
))
462 SendMessageW( hwndOwner
, vertical
? WM_VSCROLL
: WM_HSCROLL
,
463 SB_LINEUP
, (LPARAM
)hwndCtl
);
466 SetSystemTimer( hwnd
, SCROLL_TIMER
, (msg
== WM_LBUTTONDOWN
) ?
467 SCROLL_FIRST_DELAY
: SCROLL_REPEAT_DELAY
, NULL
);
471 SCROLL_DrawArrows( &context
, &sbi
, vertical
, 0, 0 );
472 KillSystemTimer( hwnd
, SCROLL_TIMER
);
477 case SCROLL_TOP_RECT
:
478 SCROLL_DrawInterior( &context
, &sbi
, sbi
.xyThumbTop
, vertical
, SCROLL_trackHitTest
, 0);
479 if (hittest
== SCROLL_trackHitTest
)
481 if ((msg
== WM_LBUTTONDOWN
) || (msg
== WM_SYSTIMER
))
483 SendMessageW( hwndOwner
, vertical
? WM_VSCROLL
: WM_HSCROLL
,
484 SB_PAGEUP
, (LPARAM
)hwndCtl
);
486 SetSystemTimer( hwnd
, SCROLL_TIMER
, (msg
== WM_LBUTTONDOWN
) ?
487 SCROLL_FIRST_DELAY
: SCROLL_REPEAT_DELAY
, NULL
);
489 else KillSystemTimer( hwnd
, SCROLL_TIMER
);
493 if (msg
== WM_LBUTTONDOWN
)
495 SCROLL_TrackingWin
= hwnd
;
496 SCROLL_TrackingBar
= nBar
;
497 SCROLL_TrackingPos
= trackThumbPos
+ lastMousePos
- lastClickPos
;
498 SCROLL_TrackingVal
= SCROLL_GetThumbVal( &si
, &sbi
.rcScrollBar
,
499 vertical
, SCROLL_TrackingPos
);
500 if (!SCROLL_MovingThumb
)
501 SCROLL_DrawMovingThumb(&context
, &sbi
, vertical
);
503 else if (msg
== WM_LBUTTONUP
)
505 if (SCROLL_MovingThumb
)
506 SCROLL_DrawMovingThumb(&context
, &sbi
, vertical
);
508 SCROLL_DrawInterior( &context
, &sbi
, sbi
.xyThumbTop
, vertical
, 0, SCROLL_trackHitTest
);
510 else /* WM_MOUSEMOVE */
514 if (!SCROLL_PtInRectEx( &sbi
.rcScrollBar
, pt
, vertical
))
518 pt
= SCROLL_ClipPos( &sbi
.rcScrollBar
, pt
);
519 pos
= vertical
? (pt
.y
- sbi
.rcScrollBar
.top
) : (pt
.x
- sbi
.rcScrollBar
.left
);
521 if ( (pos
!= lastMousePos
) || (!SCROLL_MovingThumb
) )
523 if (SCROLL_MovingThumb
)
524 SCROLL_DrawMovingThumb( &context
, &sbi
, vertical
);
526 SCROLL_TrackingPos
= trackThumbPos
+ pos
- lastClickPos
;
527 SCROLL_TrackingVal
= SCROLL_GetThumbVal( &si
, &sbi
.rcScrollBar
,
529 SCROLL_TrackingPos
);
530 SendMessageW( hwndOwner
, vertical
? WM_VSCROLL
: WM_HSCROLL
,
531 MAKEWPARAM( SB_THUMBTRACK
, SCROLL_TrackingVal
),
533 if (!SCROLL_MovingThumb
)
534 SCROLL_DrawMovingThumb( &context
, &sbi
, vertical
);
539 case SCROLL_BOTTOM_RECT
:
540 if (hittest
== SCROLL_trackHitTest
)
542 SCROLL_DrawInterior( &context
, &sbi
, sbi
.xyThumbTop
, vertical
, SCROLL_trackHitTest
, 0 );
543 if ((msg
== WM_LBUTTONDOWN
) || (msg
== WM_SYSTIMER
))
545 SendMessageW( hwndOwner
, vertical
? WM_VSCROLL
: WM_HSCROLL
,
546 SB_PAGEDOWN
, (LPARAM
)hwndCtl
);
548 SetSystemTimer( hwnd
, SCROLL_TIMER
, (msg
== WM_LBUTTONDOWN
) ?
549 SCROLL_FIRST_DELAY
: SCROLL_REPEAT_DELAY
, NULL
);
553 SCROLL_DrawInterior( &context
, &sbi
, sbi
.xyThumbTop
, vertical
, 0, 0 );
554 KillSystemTimer( hwnd
, SCROLL_TIMER
);
558 case SCROLL_BOTTOM_ARROW
:
559 if (hittest
== SCROLL_trackHitTest
)
561 SCROLL_DrawArrows( &context
, &sbi
, vertical
, SCROLL_trackHitTest
, 0 );
562 if ((msg
== WM_LBUTTONDOWN
) || (msg
== WM_SYSTIMER
))
564 SendMessageW( hwndOwner
, vertical
? WM_VSCROLL
: WM_HSCROLL
,
565 SB_LINEDOWN
, (LPARAM
)hwndCtl
);
568 SetSystemTimer( hwnd
, SCROLL_TIMER
, (msg
== WM_LBUTTONDOWN
) ?
569 SCROLL_FIRST_DELAY
: SCROLL_REPEAT_DELAY
, NULL
);
573 SCROLL_DrawArrows( &context
, &sbi
, vertical
, 0, 0 );
574 KillSystemTimer( hwnd
, SCROLL_TIMER
);
579 if (msg
== WM_LBUTTONDOWN
)
582 if (hittest
== SCROLL_THUMB
)
584 UINT val
= SCROLL_GetThumbVal( &si
, &sbi
.rcScrollBar
, vertical
,
585 trackThumbPos
+ lastMousePos
- lastClickPos
);
586 SendMessageW( hwndOwner
, vertical
? WM_VSCROLL
: WM_HSCROLL
,
587 MAKEWPARAM( SB_THUMBTRACK
, val
), (LPARAM
)hwndCtl
);
591 if (msg
== WM_LBUTTONUP
)
593 hittest
= SCROLL_trackHitTest
;
594 SCROLL_trackHitTest
= SCROLL_NOWHERE
; /* Terminate tracking */
596 if (hittest
== SCROLL_THUMB
)
598 UINT val
= SCROLL_GetThumbVal( &si
, &sbi
.rcScrollBar
, vertical
,
599 trackThumbPos
+ lastMousePos
- lastClickPos
);
600 SendMessageW( hwndOwner
, vertical
? WM_VSCROLL
: WM_HSCROLL
,
601 MAKEWPARAM( SB_THUMBPOSITION
, val
), (LPARAM
)hwndCtl
);
603 /* SB_ENDSCROLL doesn't report thumb position */
604 SendMessageW( hwndOwner
, vertical
? WM_VSCROLL
: WM_HSCROLL
,
605 SB_ENDSCROLL
, (LPARAM
)hwndCtl
);
607 /* Terminate tracking */
608 SCROLL_TrackingWin
= 0;
611 ThemeCleanupDrawContext(&context
);
615 SCROLL_TrackScrollBar( HWND hwnd
, INT scrollbar
, POINT pt
)
619 ScreenToWindow(hwnd
, &pt
);
621 SCROLL_HandleScrollEvent( hwnd
, scrollbar
, WM_LBUTTONDOWN
, pt
);
625 if (!GetMessageW( &msg
, 0, 0, 0 )) break;
626 if (CallMsgFilterW( &msg
, MSGF_SCROLLBAR
)) continue;
627 if (msg
.message
== WM_LBUTTONUP
||
628 msg
.message
== WM_MOUSEMOVE
||
629 (msg
.message
== WM_SYSTIMER
&& msg
.wParam
== SCROLL_TIMER
))
631 pt
.x
= GET_X_LPARAM(msg
.lParam
);
632 pt
.y
= GET_Y_LPARAM(msg
.lParam
);
633 ClientToScreen(hwnd
, &pt
);
634 ScreenToWindow(hwnd
, &pt
);
635 SCROLL_HandleScrollEvent( hwnd
, scrollbar
, msg
.message
, pt
);
639 TranslateMessage( &msg
);
640 DispatchMessageW( &msg
);
642 if (!IsWindow( hwnd
))
647 } while (msg
.message
!= WM_LBUTTONUP
&& GetCapture() == hwnd
);
650 void NC_TrackScrollBar( HWND hwnd
, WPARAM wParam
, POINT pt
)
654 if ((wParam
& 0xfff0) == SC_HSCROLL
)
656 if ((wParam
& 0x0f) != HTHSCROLL
) return;
659 else /* SC_VSCROLL */
661 if ((wParam
& 0x0f) != HTVSCROLL
) return;
664 SCROLL_TrackScrollBar( hwnd
, scrollbar
, pt
);