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
->xyThumbBottom
)
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
->xyThumbBottom
)
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
= thumbPos
;
219 SCROLL_ThemeDrawPart(pcontext
, SBP_UPPERTRACKVERT
, BUTTON_NORMAL
, psbi
, SCROLL_TOP_RECT
, htDown
, htHot
, &rcPart
);
220 r
.top
= rcPart
.bottom
;
223 rcPart
.top
+= psbi
->xyThumbBottom
- psbi
->xyThumbTop
;
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
= thumbPos
;
234 SCROLL_ThemeDrawPart(pcontext
, SBP_UPPERTRACKHORZ
, BUTTON_NORMAL
, psbi
, SCROLL_TOP_RECT
, htDown
, htHot
, &rcPart
);
235 r
.left
= rcPart
.right
;
238 rcPart
.left
+= psbi
->xyThumbBottom
- psbi
->xyThumbTop
;
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
->xyThumbBottom
- psbi
->xyThumbTop
+ psbi
->dxyLineButton
;
259 if( pos
< (psbi
->dxyLineButton
) )
260 pos
= (psbi
->dxyLineButton
);
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 if (SCROLL_TrackingWin
)
281 if (((nBar
== SB_VERT
) && !(pcontext
->wi
.dwStyle
& WS_VSCROLL
)) ||
282 ((nBar
== SB_HORZ
) && !(pcontext
->wi
.dwStyle
& WS_HSCROLL
))) return;
284 /* Retrieve scrollbar info */
285 sbi
.cbSize
= sizeof(sbi
);
286 si
.cbSize
= sizeof(si
);
288 GetScrollInfo(pcontext
->hWnd
, nBar
, &si
);
289 GetScrollBarInfo(pcontext
->hWnd
, SCROLL_getObjectId(nBar
), &sbi
);
290 vertical
= SCROLL_IsVertical(pcontext
->hWnd
, nBar
);
291 if(sbi
.rgstate
[SCROLL_TOP_ARROW
] & STATE_SYSTEM_UNAVAILABLE
&&
292 sbi
.rgstate
[SCROLL_BOTTOM_ARROW
] & STATE_SYSTEM_UNAVAILABLE
)
297 /* The scrollbar rect is in screen coordinates */
298 OffsetRect(&sbi
.rcScrollBar
, -pcontext
->wi
.rcWindow
.left
, -pcontext
->wi
.rcWindow
.top
);
302 ScreenToWindow(pcontext
->hWnd
, pt
);
303 htHot
= SCROLL_HitTest(pcontext
->hWnd
, &sbi
, vertical
, *pt
, FALSE
);
306 /* do not draw if the scrollbar rectangle is empty */
307 if(IsRectEmpty(&sbi
.rcScrollBar
)) return;
309 /* Draw the scrollbar */
310 SCROLL_DrawArrows( pcontext
, &sbi
, vertical
, 0, htHot
);
311 SCROLL_DrawInterior( pcontext
, &sbi
, sbi
.xyThumbTop
, vertical
, 0, htHot
);
316 /***********************************************************************
319 static POINT
SCROLL_ClipPos( LPRECT lpRect
, POINT pt
)
321 if( pt
.x
< lpRect
->left
)
324 if( pt
.x
> lpRect
->right
)
325 pt
.x
= lpRect
->right
;
327 if( pt
.y
< lpRect
->top
)
330 if( pt
.y
> lpRect
->bottom
)
331 pt
.y
= lpRect
->bottom
;
338 /***********************************************************************
341 * Compute the current scroll position based on the thumb position in pixels
342 * from the top of the scroll-bar.
344 static UINT
SCROLL_GetThumbVal( SCROLLINFO
*psi
, RECT
*rect
,
345 BOOL vertical
, INT pos
)
348 INT pixels
= vertical
? rect
->bottom
-rect
->top
: rect
->right
-rect
->left
;
351 if ((pixels
-= 2*(GetSystemMetrics(SM_CXVSCROLL
) - SCROLL_ARROW_THUMB_OVERLAP
)) <= 0)
356 thumbSize
= MulDiv(pixels
,psi
->nPage
,(psi
->nMax
-psi
->nMin
+1));
357 if (thumbSize
< SCROLL_MIN_THUMB
) thumbSize
= SCROLL_MIN_THUMB
;
359 else thumbSize
= GetSystemMetrics(SM_CXVSCROLL
);
361 if ((pixels
-= thumbSize
) <= 0) return psi
->nMin
;
363 pos
= max( 0, pos
- (GetSystemMetrics(SM_CXVSCROLL
) - SCROLL_ARROW_THUMB_OVERLAP
) );
364 if (pos
> pixels
) pos
= pixels
;
367 range
= psi
->nMax
- psi
->nMin
;
369 range
= psi
->nMax
- psi
->nMin
- psi
->nPage
+ 1;
371 return psi
->nMin
+ MulDiv(pos
, range
, pixels
);
375 SCROLL_HandleScrollEvent( HWND hwnd
, INT nBar
, UINT msg
, POINT pt
)
377 /* Previous mouse position for timer events */
379 /* Thumb position when tracking started. */
380 static UINT trackThumbPos
;
381 /* Position in the scroll-bar of the last button-down event. */
382 static INT lastClickPos
;
383 /* Position in the scroll-bar of the last mouse event. */
384 static INT lastMousePos
;
386 enum SCROLL_HITTEST hittest
;
387 HWND hwndOwner
, hwndCtl
;
391 DRAW_CONTEXT context
;
393 si
.cbSize
= sizeof(si
);
394 sbi
.cbSize
= sizeof(sbi
);
396 GetScrollInfo(hwnd
, nBar
, &si
);
397 GetScrollBarInfo(hwnd
, SCROLL_getObjectId(nBar
), &sbi
);
398 vertical
= SCROLL_IsVertical(hwnd
, nBar
);
399 if(sbi
.rgstate
[SCROLL_TOP_ARROW
] & STATE_SYSTEM_UNAVAILABLE
&&
400 sbi
.rgstate
[SCROLL_BOTTOM_ARROW
] & STATE_SYSTEM_UNAVAILABLE
)
405 if ((SCROLL_trackHitTest
== SCROLL_NOWHERE
) && (msg
!= WM_LBUTTONDOWN
))
408 ThemeInitDrawContext(&context
, hwnd
, 0);
410 /* The scrollbar rect is in screen coordinates */
411 OffsetRect(&sbi
.rcScrollBar
, -context
.wi
.rcWindow
.left
, -context
.wi
.rcWindow
.top
);
413 hwndOwner
= (nBar
== SB_CTL
) ? GetParent(hwnd
) : hwnd
;
414 hwndCtl
= (nBar
== SB_CTL
) ? hwnd
: 0;
418 case WM_LBUTTONDOWN
: /* Initialise mouse tracking */
419 HideCaret(hwnd
); /* hide caret while holding down LBUTTON */
420 SCROLL_trackVertical
= vertical
;
421 SCROLL_trackHitTest
= hittest
= SCROLL_HitTest( hwnd
, &sbi
, vertical
, pt
, FALSE
);
422 lastClickPos
= vertical
? (pt
.y
- sbi
.rcScrollBar
.top
) : (pt
.x
- sbi
.rcScrollBar
.left
);
423 lastMousePos
= lastClickPos
;
424 trackThumbPos
= sbi
.xyThumbTop
;
430 hittest
= SCROLL_HitTest( hwnd
, &sbi
, vertical
, pt
, TRUE
);
435 hittest
= SCROLL_NOWHERE
;
437 /* if scrollbar has focus, show back caret */
438 if (hwnd
==GetFocus())
444 hittest
= SCROLL_HitTest( hwnd
, &sbi
, vertical
, pt
, FALSE
);
448 return; /* Should never happen */
451 //TRACE("Event: hwnd=%p bar=%d msg=%s pt=%d,%d hit=%d\n",
452 // hwnd, nBar, SPY_GetMsgName(msg,hwnd), pt.x, pt.y, hittest );
454 switch(SCROLL_trackHitTest
)
456 case SCROLL_NOWHERE
: /* No tracking in progress */
459 case SCROLL_TOP_ARROW
:
460 if (hittest
== SCROLL_trackHitTest
)
462 SCROLL_DrawArrows( &context
, &sbi
, vertical
, SCROLL_trackHitTest
, 0 );
463 if ((msg
== WM_LBUTTONDOWN
) || (msg
== WM_SYSTIMER
))
465 SendMessageW( hwndOwner
, vertical
? WM_VSCROLL
: WM_HSCROLL
,
466 SB_LINEUP
, (LPARAM
)hwndCtl
);
469 SetSystemTimer( hwnd
, SCROLL_TIMER
, (msg
== WM_LBUTTONDOWN
) ?
470 SCROLL_FIRST_DELAY
: SCROLL_REPEAT_DELAY
, NULL
);
474 SCROLL_DrawArrows( &context
, &sbi
, vertical
, 0, 0 );
475 KillSystemTimer( hwnd
, SCROLL_TIMER
);
480 case SCROLL_TOP_RECT
:
481 SCROLL_DrawInterior( &context
, &sbi
, sbi
.xyThumbTop
, vertical
, SCROLL_trackHitTest
, 0);
482 if (hittest
== SCROLL_trackHitTest
)
484 if ((msg
== WM_LBUTTONDOWN
) || (msg
== WM_SYSTIMER
))
486 SendMessageW( hwndOwner
, vertical
? WM_VSCROLL
: WM_HSCROLL
,
487 SB_PAGEUP
, (LPARAM
)hwndCtl
);
489 SetSystemTimer( hwnd
, SCROLL_TIMER
, (msg
== WM_LBUTTONDOWN
) ?
490 SCROLL_FIRST_DELAY
: SCROLL_REPEAT_DELAY
, NULL
);
492 else KillSystemTimer( hwnd
, SCROLL_TIMER
);
496 if (msg
== WM_LBUTTONDOWN
)
498 SCROLL_TrackingWin
= hwnd
;
499 SCROLL_TrackingBar
= nBar
;
500 SCROLL_TrackingPos
= trackThumbPos
+ lastMousePos
- lastClickPos
;
501 SCROLL_TrackingVal
= SCROLL_GetThumbVal( &si
, &sbi
.rcScrollBar
,
502 vertical
, SCROLL_TrackingPos
);
503 if (!SCROLL_MovingThumb
)
504 SCROLL_DrawMovingThumb(&context
, &sbi
, vertical
);
506 else if (msg
== WM_LBUTTONUP
)
508 if (SCROLL_MovingThumb
)
509 SCROLL_DrawMovingThumb(&context
, &sbi
, vertical
);
511 SCROLL_DrawInterior( &context
, &sbi
, sbi
.xyThumbTop
, vertical
, 0, SCROLL_trackHitTest
);
513 else /* WM_MOUSEMOVE */
517 if (!SCROLL_PtInRectEx( &sbi
.rcScrollBar
, pt
, vertical
))
521 pt
= SCROLL_ClipPos( &sbi
.rcScrollBar
, pt
);
522 pos
= vertical
? (pt
.y
- sbi
.rcScrollBar
.top
) : (pt
.x
- sbi
.rcScrollBar
.left
);
524 if ( (pos
!= lastMousePos
) || (!SCROLL_MovingThumb
) )
526 if (SCROLL_MovingThumb
)
527 SCROLL_DrawMovingThumb( &context
, &sbi
, vertical
);
529 SCROLL_TrackingPos
= trackThumbPos
+ pos
- lastClickPos
;
530 SCROLL_TrackingVal
= SCROLL_GetThumbVal( &si
, &sbi
.rcScrollBar
,
532 SCROLL_TrackingPos
);
533 SendMessageW( hwndOwner
, vertical
? WM_VSCROLL
: WM_HSCROLL
,
534 MAKEWPARAM( SB_THUMBTRACK
, SCROLL_TrackingVal
),
536 if (!SCROLL_MovingThumb
)
537 SCROLL_DrawMovingThumb( &context
, &sbi
, vertical
);
542 case SCROLL_BOTTOM_RECT
:
543 if (hittest
== SCROLL_trackHitTest
)
545 SCROLL_DrawInterior( &context
, &sbi
, sbi
.xyThumbTop
, vertical
, SCROLL_trackHitTest
, 0 );
546 if ((msg
== WM_LBUTTONDOWN
) || (msg
== WM_SYSTIMER
))
548 SendMessageW( hwndOwner
, vertical
? WM_VSCROLL
: WM_HSCROLL
,
549 SB_PAGEDOWN
, (LPARAM
)hwndCtl
);
551 SetSystemTimer( hwnd
, SCROLL_TIMER
, (msg
== WM_LBUTTONDOWN
) ?
552 SCROLL_FIRST_DELAY
: SCROLL_REPEAT_DELAY
, NULL
);
556 SCROLL_DrawInterior( &context
, &sbi
, sbi
.xyThumbTop
, vertical
, 0, 0 );
557 KillSystemTimer( hwnd
, SCROLL_TIMER
);
561 case SCROLL_BOTTOM_ARROW
:
562 if (hittest
== SCROLL_trackHitTest
)
564 SCROLL_DrawArrows( &context
, &sbi
, vertical
, SCROLL_trackHitTest
, 0 );
565 if ((msg
== WM_LBUTTONDOWN
) || (msg
== WM_SYSTIMER
))
567 SendMessageW( hwndOwner
, vertical
? WM_VSCROLL
: WM_HSCROLL
,
568 SB_LINEDOWN
, (LPARAM
)hwndCtl
);
571 SetSystemTimer( hwnd
, SCROLL_TIMER
, (msg
== WM_LBUTTONDOWN
) ?
572 SCROLL_FIRST_DELAY
: SCROLL_REPEAT_DELAY
, NULL
);
576 SCROLL_DrawArrows( &context
, &sbi
, vertical
, 0, 0 );
577 KillSystemTimer( hwnd
, SCROLL_TIMER
);
582 if (msg
== WM_LBUTTONDOWN
)
585 if (hittest
== SCROLL_THUMB
)
587 UINT val
= SCROLL_GetThumbVal( &si
, &sbi
.rcScrollBar
, vertical
,
588 trackThumbPos
+ lastMousePos
- lastClickPos
);
589 SendMessageW( hwndOwner
, vertical
? WM_VSCROLL
: WM_HSCROLL
,
590 MAKEWPARAM( SB_THUMBTRACK
, val
), (LPARAM
)hwndCtl
);
594 if (msg
== WM_LBUTTONUP
)
596 hittest
= SCROLL_trackHitTest
;
597 SCROLL_trackHitTest
= SCROLL_NOWHERE
; /* Terminate tracking */
599 if (hittest
== SCROLL_THUMB
)
601 UINT val
= SCROLL_GetThumbVal( &si
, &sbi
.rcScrollBar
, vertical
,
602 trackThumbPos
+ lastMousePos
- lastClickPos
);
603 SendMessageW( hwndOwner
, vertical
? WM_VSCROLL
: WM_HSCROLL
,
604 MAKEWPARAM( SB_THUMBPOSITION
, val
), (LPARAM
)hwndCtl
);
606 /* SB_ENDSCROLL doesn't report thumb position */
607 SendMessageW( hwndOwner
, vertical
? WM_VSCROLL
: WM_HSCROLL
,
608 SB_ENDSCROLL
, (LPARAM
)hwndCtl
);
610 /* Terminate tracking */
611 SCROLL_TrackingWin
= 0;
614 ThemeCleanupDrawContext(&context
);
618 SCROLL_TrackScrollBar( HWND hwnd
, INT scrollbar
, POINT pt
)
622 ScreenToWindow(hwnd
, &pt
);
624 SCROLL_HandleScrollEvent( hwnd
, scrollbar
, WM_LBUTTONDOWN
, pt
);
628 if (!GetMessageW( &msg
, 0, 0, 0 )) break;
629 if (CallMsgFilterW( &msg
, MSGF_SCROLLBAR
)) continue;
630 if (msg
.message
== WM_LBUTTONUP
||
631 msg
.message
== WM_MOUSEMOVE
||
632 (msg
.message
== WM_SYSTIMER
&& msg
.wParam
== SCROLL_TIMER
))
634 pt
.x
= GET_X_LPARAM(msg
.lParam
);
635 pt
.y
= GET_Y_LPARAM(msg
.lParam
);
636 ClientToScreen(hwnd
, &pt
);
637 ScreenToWindow(hwnd
, &pt
);
638 SCROLL_HandleScrollEvent( hwnd
, scrollbar
, msg
.message
, pt
);
642 TranslateMessage( &msg
);
643 DispatchMessageW( &msg
);
645 if (!IsWindow( hwnd
))
650 } while (msg
.message
!= WM_LBUTTONUP
&& GetCapture() == hwnd
);
653 void NC_TrackScrollBar( HWND hwnd
, WPARAM wParam
, POINT pt
)
657 if ((wParam
& 0xfff0) == SC_HSCROLL
)
659 if ((wParam
& 0x0f) != HTHSCROLL
) return;
662 else /* SC_VSCROLL */
664 if ((wParam
& 0x0f) != HTVSCROLL
) return;
667 SCROLL_TrackScrollBar( hwnd
, scrollbar
, pt
);