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
)
292 /* The scrollbar rect is in screen coordinates */
293 // OffsetRect(&sbi.rcScrollBar, -pcontext->wi.rcWindow.left, -pcontext->wi.rcWindow.top);
298 ScreenToWindow(pcontext
->hWnd
, pt
);
299 htHot
= SCROLL_HitTest(pcontext
->hWnd
, &sbi
, vertical
, *pt
, FALSE
);
302 if (((nBar
== SB_VERT
) && !(pcontext
->wi
.dwStyle
& WS_VSCROLL
)) ||
303 ((nBar
== SB_HORZ
) && !(pcontext
->wi
.dwStyle
& WS_HSCROLL
))) return;
305 /* do not draw if the scrollbar rectangle is empty */
306 if(IsRectEmpty(&sbi
.rcScrollBar
)) return;
308 /* Draw the scrollbar */
309 SCROLL_DrawArrows( pcontext
, &sbi
, vertical
, 0, htHot
);
310 SCROLL_DrawInterior( pcontext
, &sbi
, sbi
.xyThumbTop
, vertical
, 0, htHot
);
315 /***********************************************************************
318 static POINT
SCROLL_ClipPos( LPRECT lpRect
, POINT pt
)
320 if( pt
.x
< lpRect
->left
)
323 if( pt
.x
> lpRect
->right
)
324 pt
.x
= lpRect
->right
;
326 if( pt
.y
< lpRect
->top
)
329 if( pt
.y
> lpRect
->bottom
)
330 pt
.y
= lpRect
->bottom
;
337 /***********************************************************************
340 * Compute the current scroll position based on the thumb position in pixels
341 * from the top of the scroll-bar.
343 static UINT
SCROLL_GetThumbVal( SCROLLINFO
*psi
, RECT
*rect
,
344 BOOL vertical
, INT pos
)
347 INT pixels
= vertical
? rect
->bottom
-rect
->top
: rect
->right
-rect
->left
;
350 if ((pixels
-= 2*(GetSystemMetrics(SM_CXVSCROLL
) - SCROLL_ARROW_THUMB_OVERLAP
)) <= 0)
355 thumbSize
= MulDiv(pixels
,psi
->nPage
,(psi
->nMax
-psi
->nMin
+1));
356 if (thumbSize
< SCROLL_MIN_THUMB
) thumbSize
= SCROLL_MIN_THUMB
;
358 else thumbSize
= GetSystemMetrics(SM_CXVSCROLL
);
360 if ((pixels
-= thumbSize
) <= 0) return psi
->nMin
;
362 pos
= max( 0, pos
- (GetSystemMetrics(SM_CXVSCROLL
) - SCROLL_ARROW_THUMB_OVERLAP
) );
363 if (pos
> pixels
) pos
= pixels
;
366 range
= psi
->nMax
- psi
->nMin
;
368 range
= psi
->nMax
- psi
->nMin
- psi
->nPage
+ 1;
370 return psi
->nMin
+ MulDiv(pos
, range
, pixels
);
374 SCROLL_HandleScrollEvent( HWND hwnd
, INT nBar
, UINT msg
, POINT pt
)
376 /* Previous mouse position for timer events */
378 /* Thumb position when tracking started. */
379 static UINT trackThumbPos
;
380 /* Position in the scroll-bar of the last button-down event. */
381 static INT lastClickPos
;
382 /* Position in the scroll-bar of the last mouse event. */
383 static INT lastMousePos
;
385 enum SCROLL_HITTEST hittest
;
386 HWND hwndOwner
, hwndCtl
;
390 DRAW_CONTEXT context
;
392 si
.cbSize
= sizeof(si
);
393 sbi
.cbSize
= sizeof(sbi
);
395 GetScrollInfo(hwnd
, nBar
, &si
);
396 GetScrollBarInfo(hwnd
, SCROLL_getObjectId(nBar
), &sbi
);
397 vertical
= SCROLL_IsVertical(hwnd
, nBar
);
398 if(sbi
.rgstate
[SCROLL_TOP_ARROW
] & STATE_SYSTEM_UNAVAILABLE
&&
399 sbi
.rgstate
[SCROLL_BOTTOM_ARROW
] & STATE_SYSTEM_UNAVAILABLE
)
405 /* The scrollbar rect is in screen coordinates */
406 // OffsetRect(&sbi.rcScrollBar, -context.wi.rcWindow.left, -context.wi.rcWindow.top);
409 if ((SCROLL_trackHitTest
== SCROLL_NOWHERE
) && (msg
!= WM_LBUTTONDOWN
))
412 ThemeInitDrawContext(&context
, hwnd
, 0);
414 hwndOwner
= (nBar
== SB_CTL
) ? GetParent(hwnd
) : hwnd
;
415 hwndCtl
= (nBar
== SB_CTL
) ? hwnd
: 0;
419 case WM_LBUTTONDOWN
: /* Initialise mouse tracking */
420 HideCaret(hwnd
); /* hide caret while holding down LBUTTON */
421 SCROLL_trackVertical
= vertical
;
422 SCROLL_trackHitTest
= hittest
= SCROLL_HitTest( hwnd
, &sbi
, vertical
, pt
, FALSE
);
423 lastClickPos
= vertical
? (pt
.y
- sbi
.rcScrollBar
.top
) : (pt
.x
- sbi
.rcScrollBar
.left
);
424 lastMousePos
= lastClickPos
;
425 trackThumbPos
= sbi
.xyThumbTop
;
431 hittest
= SCROLL_HitTest( hwnd
, &sbi
, vertical
, pt
, TRUE
);
436 hittest
= SCROLL_NOWHERE
;
438 /* if scrollbar has focus, show back caret */
439 if (hwnd
==GetFocus())
445 hittest
= SCROLL_HitTest( hwnd
, &sbi
, vertical
, pt
, FALSE
);
449 return; /* Should never happen */
452 //TRACE("Event: hwnd=%p bar=%d msg=%s pt=%d,%d hit=%d\n",
453 // hwnd, nBar, SPY_GetMsgName(msg,hwnd), pt.x, pt.y, hittest );
455 switch(SCROLL_trackHitTest
)
457 case SCROLL_NOWHERE
: /* No tracking in progress */
460 case SCROLL_TOP_ARROW
:
461 if (hittest
== SCROLL_trackHitTest
)
463 SCROLL_DrawArrows( &context
, &sbi
, vertical
, SCROLL_trackHitTest
, 0 );
464 if ((msg
== WM_LBUTTONDOWN
) || (msg
== WM_SYSTIMER
))
466 SendMessageW( hwndOwner
, vertical
? WM_VSCROLL
: WM_HSCROLL
,
467 SB_LINEUP
, (LPARAM
)hwndCtl
);
470 SetSystemTimer( hwnd
, SCROLL_TIMER
, (msg
== WM_LBUTTONDOWN
) ?
471 SCROLL_FIRST_DELAY
: SCROLL_REPEAT_DELAY
, NULL
);
475 SCROLL_DrawArrows( &context
, &sbi
, vertical
, 0, 0 );
476 KillSystemTimer( hwnd
, SCROLL_TIMER
);
481 case SCROLL_TOP_RECT
:
482 SCROLL_DrawInterior( &context
, &sbi
, sbi
.xyThumbTop
, vertical
, SCROLL_trackHitTest
, 0);
483 if (hittest
== SCROLL_trackHitTest
)
485 if ((msg
== WM_LBUTTONDOWN
) || (msg
== WM_SYSTIMER
))
487 SendMessageW( hwndOwner
, vertical
? WM_VSCROLL
: WM_HSCROLL
,
488 SB_PAGEUP
, (LPARAM
)hwndCtl
);
490 SetSystemTimer( hwnd
, SCROLL_TIMER
, (msg
== WM_LBUTTONDOWN
) ?
491 SCROLL_FIRST_DELAY
: SCROLL_REPEAT_DELAY
, NULL
);
493 else KillSystemTimer( hwnd
, SCROLL_TIMER
);
497 if (msg
== WM_LBUTTONDOWN
)
499 SCROLL_TrackingWin
= hwnd
;
500 SCROLL_TrackingBar
= nBar
;
501 SCROLL_TrackingPos
= trackThumbPos
+ lastMousePos
- lastClickPos
;
502 SCROLL_TrackingVal
= SCROLL_GetThumbVal( &si
, &sbi
.rcScrollBar
,
503 vertical
, SCROLL_TrackingPos
);
504 if (!SCROLL_MovingThumb
)
505 SCROLL_DrawMovingThumb(&context
, &sbi
, vertical
);
507 else if (msg
== WM_LBUTTONUP
)
509 if (SCROLL_MovingThumb
)
510 SCROLL_DrawMovingThumb(&context
, &sbi
, vertical
);
512 SCROLL_DrawInterior( &context
, &sbi
, sbi
.xyThumbTop
, vertical
, 0, SCROLL_trackHitTest
);
514 else /* WM_MOUSEMOVE */
518 if (!SCROLL_PtInRectEx( &sbi
.rcScrollBar
, pt
, vertical
))
522 pt
= SCROLL_ClipPos( &sbi
.rcScrollBar
, pt
);
523 pos
= vertical
? (pt
.y
- sbi
.rcScrollBar
.top
) : (pt
.x
- sbi
.rcScrollBar
.left
);
525 if ( (pos
!= lastMousePos
) || (!SCROLL_MovingThumb
) )
527 if (SCROLL_MovingThumb
)
528 SCROLL_DrawMovingThumb( &context
, &sbi
, vertical
);
530 SCROLL_TrackingPos
= trackThumbPos
+ pos
- lastClickPos
;
531 SCROLL_TrackingVal
= SCROLL_GetThumbVal( &si
, &sbi
.rcScrollBar
,
533 SCROLL_TrackingPos
);
534 SendMessageW( hwndOwner
, vertical
? WM_VSCROLL
: WM_HSCROLL
,
535 MAKEWPARAM( SB_THUMBTRACK
, SCROLL_TrackingVal
),
537 if (!SCROLL_MovingThumb
)
538 SCROLL_DrawMovingThumb( &context
, &sbi
, vertical
);
543 case SCROLL_BOTTOM_RECT
:
544 if (hittest
== SCROLL_trackHitTest
)
546 SCROLL_DrawInterior( &context
, &sbi
, sbi
.xyThumbTop
, vertical
, SCROLL_trackHitTest
, 0 );
547 if ((msg
== WM_LBUTTONDOWN
) || (msg
== WM_SYSTIMER
))
549 SendMessageW( hwndOwner
, vertical
? WM_VSCROLL
: WM_HSCROLL
,
550 SB_PAGEDOWN
, (LPARAM
)hwndCtl
);
552 SetSystemTimer( hwnd
, SCROLL_TIMER
, (msg
== WM_LBUTTONDOWN
) ?
553 SCROLL_FIRST_DELAY
: SCROLL_REPEAT_DELAY
, NULL
);
557 SCROLL_DrawInterior( &context
, &sbi
, sbi
.xyThumbTop
, vertical
, 0, 0 );
558 KillSystemTimer( hwnd
, SCROLL_TIMER
);
562 case SCROLL_BOTTOM_ARROW
:
563 if (hittest
== SCROLL_trackHitTest
)
565 SCROLL_DrawArrows( &context
, &sbi
, vertical
, SCROLL_trackHitTest
, 0 );
566 if ((msg
== WM_LBUTTONDOWN
) || (msg
== WM_SYSTIMER
))
568 SendMessageW( hwndOwner
, vertical
? WM_VSCROLL
: WM_HSCROLL
,
569 SB_LINEDOWN
, (LPARAM
)hwndCtl
);
572 SetSystemTimer( hwnd
, SCROLL_TIMER
, (msg
== WM_LBUTTONDOWN
) ?
573 SCROLL_FIRST_DELAY
: SCROLL_REPEAT_DELAY
, NULL
);
577 SCROLL_DrawArrows( &context
, &sbi
, vertical
, 0, 0 );
578 KillSystemTimer( hwnd
, SCROLL_TIMER
);
583 if (msg
== WM_LBUTTONDOWN
)
586 if (hittest
== SCROLL_THUMB
)
588 UINT val
= SCROLL_GetThumbVal( &si
, &sbi
.rcScrollBar
, vertical
,
589 trackThumbPos
+ lastMousePos
- lastClickPos
);
590 SendMessageW( hwndOwner
, vertical
? WM_VSCROLL
: WM_HSCROLL
,
591 MAKEWPARAM( SB_THUMBTRACK
, val
), (LPARAM
)hwndCtl
);
595 if (msg
== WM_LBUTTONUP
)
597 hittest
= SCROLL_trackHitTest
;
598 SCROLL_trackHitTest
= SCROLL_NOWHERE
; /* Terminate tracking */
600 if (hittest
== SCROLL_THUMB
)
602 UINT val
= SCROLL_GetThumbVal( &si
, &sbi
.rcScrollBar
, vertical
,
603 trackThumbPos
+ lastMousePos
- lastClickPos
);
604 SendMessageW( hwndOwner
, vertical
? WM_VSCROLL
: WM_HSCROLL
,
605 MAKEWPARAM( SB_THUMBPOSITION
, val
), (LPARAM
)hwndCtl
);
607 /* SB_ENDSCROLL doesn't report thumb position */
608 SendMessageW( hwndOwner
, vertical
? WM_VSCROLL
: WM_HSCROLL
,
609 SB_ENDSCROLL
, (LPARAM
)hwndCtl
);
611 /* Terminate tracking */
612 SCROLL_TrackingWin
= 0;
615 ThemeCleanupDrawContext(&context
);
619 SCROLL_TrackScrollBar( HWND hwnd
, INT scrollbar
, POINT pt
)
623 ScreenToWindow(hwnd
, &pt
);
625 SCROLL_HandleScrollEvent( hwnd
, scrollbar
, WM_LBUTTONDOWN
, pt
);
629 if (!GetMessageW( &msg
, 0, 0, 0 )) break;
630 if (CallMsgFilterW( &msg
, MSGF_SCROLLBAR
)) continue;
631 if (msg
.message
== WM_LBUTTONUP
||
632 msg
.message
== WM_MOUSEMOVE
||
633 (msg
.message
== WM_SYSTIMER
&& msg
.wParam
== SCROLL_TIMER
))
635 pt
.x
= GET_X_LPARAM(msg
.lParam
);
636 pt
.y
= GET_Y_LPARAM(msg
.lParam
);
637 ClientToScreen(hwnd
, &pt
);
638 ScreenToWindow(hwnd
, &pt
);
639 SCROLL_HandleScrollEvent( hwnd
, scrollbar
, msg
.message
, pt
);
643 TranslateMessage( &msg
);
644 DispatchMessageW( &msg
);
646 if (!IsWindow( hwnd
))
651 } while (msg
.message
!= WM_LBUTTONUP
&& GetCapture() == hwnd
);
654 void NC_TrackScrollBar( HWND hwnd
, WPARAM wParam
, POINT pt
)
658 if ((wParam
& 0xfff0) == SC_HSCROLL
)
660 if ((wParam
& 0x0f) != HTHSCROLL
) return;
663 else /* SC_VSCROLL */
665 if ((wParam
& 0x0f) != HTVSCROLL
) return;
668 SCROLL_TrackScrollBar( hwnd
, scrollbar
, pt
);