ReactOS  0.4.13-dev-982-g9853eab
ncscrollbar.c
Go to the documentation of this file.
1 /*
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
10  */
11 
12 #include "uxthemep.h"
13 
14 #include <assert.h>
15 
16 static void ScreenToWindow( HWND hWnd, POINT* pt)
17 {
18  RECT rcWnd;
19  GetWindowRect(hWnd, &rcWnd);
20  pt->x -= rcWnd.left;
21  pt->y -= rcWnd.top;
22 }
23 
25 {
26  switch(nBar)
27  {
28  case SB_HORZ:
29  return FALSE;
30  case SB_VERT:
31  return TRUE;
32  default:
33  assert(FALSE);
34  return FALSE;
35  }
36 }
37 
39 {
40  switch(nBar)
41  {
42  case SB_HORZ:
43  return OBJID_HSCROLL;
44  case SB_VERT:
45  return OBJID_VSCROLL;
46  default:
47  assert(FALSE);
48  return 0;
49  }
50 }
51 
52 /***********************************************************************
53  * SCROLL_PtInRectEx
54  */
55 static BOOL SCROLL_PtInRectEx( LPRECT lpRect, POINT pt, BOOL vertical )
56 {
57  RECT rect = *lpRect;
58  int scrollbarWidth;
59 
60  /* Pad hit rect to allow mouse to be dragged outside of scrollbar and
61  * still be considered in the scrollbar. */
62  if (vertical)
63  {
64  scrollbarWidth = lpRect->right - lpRect->left;
65  rect.left -= scrollbarWidth*8;
66  rect.right += scrollbarWidth*8;
67  rect.top -= scrollbarWidth*2;
68  rect.bottom += scrollbarWidth*2;
69  }
70  else
71  {
72  scrollbarWidth = lpRect->bottom - lpRect->top;
73  rect.left -= scrollbarWidth*2;
74  rect.right += scrollbarWidth*2;
75  rect.top -= scrollbarWidth*8;
76  rect.bottom += scrollbarWidth*8;
77  }
78  return PtInRect( &rect, pt );
79 }
80 
81 
82 /***********************************************************************
83  * SCROLL_HitTest
84  *
85  * Scroll-bar hit testing (don't confuse this with WM_NCHITTEST!).
86  */
87 static enum SCROLL_HITTEST SCROLL_HitTest( HWND hwnd, SCROLLBARINFO* psbi, BOOL vertical,
88  POINT pt, BOOL bDragging )
89 {
90  if ( (bDragging && !SCROLL_PtInRectEx( &psbi->rcScrollBar, pt, vertical )) ||
91  (!PtInRect( &psbi->rcScrollBar, pt )) )
92  {
93  return SCROLL_NOWHERE;
94  }
95 
96  if (vertical)
97  {
98  if (pt.y < psbi->rcScrollBar.top + psbi->dxyLineButton)
99  return SCROLL_TOP_ARROW;
100  if (pt.y >= psbi->rcScrollBar.bottom - psbi->dxyLineButton)
101  return SCROLL_BOTTOM_ARROW;
102  if (!psbi->xyThumbTop)
103  return SCROLL_TOP_RECT;
104  pt.y -= psbi->rcScrollBar.top;
105  if (pt.y < psbi->xyThumbTop)
106  return SCROLL_TOP_RECT;
107  if (pt.y >= psbi->xyThumbBottom)
108  return SCROLL_BOTTOM_RECT;
109  }
110  else /* horizontal */
111  {
112  if (pt.x < psbi->rcScrollBar.left + psbi->dxyLineButton)
113  return SCROLL_TOP_ARROW;
114  if (pt.x >= psbi->rcScrollBar.right - psbi->dxyLineButton)
115  return SCROLL_BOTTOM_ARROW;
116  if (!psbi->xyThumbTop)
117  return SCROLL_TOP_RECT;
118  pt.x -= psbi->rcScrollBar.left;
119  if (pt.x < psbi->xyThumbTop)
120  return SCROLL_TOP_RECT;
121  if (pt.x >= psbi->xyThumbBottom)
122  return SCROLL_BOTTOM_RECT;
123  }
124  return SCROLL_THUMB;
125 }
126 
127 static void SCROLL_ThemeDrawPart(PDRAW_CONTEXT pcontext, int iPartId,int iStateId, SCROLLBARINFO* psbi, int htCurrent, int htDown, int htHot, RECT* r)
128 {
129  if (r->right <= r->left || r->bottom <= r->top)
130  return;
131 
132  if(psbi->rgstate[htCurrent] & STATE_SYSTEM_UNAVAILABLE)
133  iStateId += BUTTON_DISABLED - BUTTON_NORMAL;
134  else if (htHot == htCurrent)
135  iStateId += BUTTON_HOT - BUTTON_NORMAL;
136  else if (htDown == htCurrent)
137  iStateId += BUTTON_PRESSED - BUTTON_NORMAL;
138 
139  DrawThemeBackground(pcontext->scrolltheme, pcontext->hDC, iPartId, iStateId, r, NULL);
140 }
141 
142 /***********************************************************************
143  * SCROLL_DrawArrows
144  *
145  * Draw the scroll bar arrows.
146  */
147 static void SCROLL_DrawArrows( PDRAW_CONTEXT pcontext, SCROLLBARINFO* psbi,
148  BOOL vertical, int htDown, int htHot )
149 {
150  RECT r;
151  int iStateId;
152 
153  r = psbi->rcScrollBar;
154  if( vertical )
155  {
156  r.bottom = r.top + psbi->dxyLineButton;
157  iStateId = ABS_UPNORMAL;
158  }
159  else
160  {
161  r.right = r.left + psbi->dxyLineButton;
162  iStateId = ABS_LEFTNORMAL;
163  }
164 
165  SCROLL_ThemeDrawPart(pcontext, SBP_ARROWBTN, iStateId, psbi, SCROLL_TOP_ARROW, htDown, htHot, &r);
166 
167  r = psbi->rcScrollBar;
168  if( vertical )
169  {
170  r.top = r.bottom - psbi->dxyLineButton;
171  iStateId = ABS_DOWNNORMAL;
172  }
173  else
174  {
175  iStateId = ABS_RIGHTNORMAL;
176  r.left = r.right - psbi->dxyLineButton;
177  }
178 
179  SCROLL_ThemeDrawPart(pcontext, SBP_ARROWBTN, iStateId, psbi, SCROLL_BOTTOM_ARROW, htDown, htHot, &r);
180 }
181 
182 static void SCROLL_DrawInterior( PDRAW_CONTEXT pcontext, SCROLLBARINFO* psbi,
183  INT thumbPos, BOOL vertical,
184  int htDown, int htHot )
185 {
186  RECT r, rcPart;
187 
188  /* thumbPos is relative to the edge of the scrollbar */
189 
190  r = psbi->rcScrollBar;
191  if (vertical)
192  {
193  if (thumbPos)
194  thumbPos += pcontext->wi.rcClient.top - pcontext->wi.rcWindow.top;
195  r.top += psbi->dxyLineButton;
196  r.bottom -= (psbi->dxyLineButton);
197  }
198  else
199  {
200  if (thumbPos)
201  thumbPos += pcontext->wi.rcClient.left - pcontext->wi.rcWindow.left;
202  r.left += psbi->dxyLineButton;
203  r.right -= psbi->dxyLineButton;
204  }
205 
206  if (r.right <= r.left || r.bottom <= r.top)
207  return;
208 
209  /* Draw the scroll rectangles and thumb */
210 
211  if (!thumbPos) /* No thumb to draw */
212  {
213  rcPart = r;
214  SCROLL_ThemeDrawPart(pcontext, vertical ? SBP_UPPERTRACKVERT: SBP_UPPERTRACKHORZ , BUTTON_NORMAL, psbi, SCROLL_THUMB, 0, 0, &rcPart);
215  return;
216  }
217 
218  /* Some themes have different bitmaps for the upper and lower tracks
219  It seems that windows use the bitmap for the lower track in the upper track */
220  if (vertical)
221  {
222  rcPart = r;
223  rcPart.bottom = thumbPos;
224  SCROLL_ThemeDrawPart(pcontext, SBP_LOWERTRACKVERT, BUTTON_NORMAL, psbi, SCROLL_TOP_RECT, htDown, htHot, &rcPart);
225  r.top = rcPart.bottom;
226 
227  rcPart = r;
228  rcPart.top += psbi->xyThumbBottom - psbi->xyThumbTop;
229  SCROLL_ThemeDrawPart(pcontext, SBP_UPPERTRACKVERT, BUTTON_NORMAL, psbi, SCROLL_BOTTOM_RECT, htDown, htHot, &rcPart);
230  r.bottom = rcPart.top;
231 
232  SCROLL_ThemeDrawPart(pcontext, SBP_THUMBBTNVERT, BUTTON_NORMAL, psbi, SCROLL_THUMB, htDown, htHot, &r);
233  SCROLL_ThemeDrawPart(pcontext, SBP_GRIPPERVERT, BUTTON_NORMAL, psbi, SCROLL_THUMB, htDown, htHot, &r);
234  }
235  else /* horizontal */
236  {
237  rcPart = r;
238  rcPart.right = thumbPos;
239  SCROLL_ThemeDrawPart(pcontext, SBP_LOWERTRACKHORZ, BUTTON_NORMAL, psbi, SCROLL_TOP_RECT, htDown, htHot, &rcPart);
240  r.left = rcPart.right;
241 
242  rcPart = r;
243  rcPart.left += psbi->xyThumbBottom - psbi->xyThumbTop;
244  SCROLL_ThemeDrawPart(pcontext, SBP_UPPERTRACKHORZ, BUTTON_NORMAL, psbi, SCROLL_BOTTOM_RECT, htDown, htHot, &rcPart);
245  r.right = rcPart.left;
246 
247  SCROLL_ThemeDrawPart(pcontext, SBP_THUMBBTNHORZ, BUTTON_NORMAL, psbi, SCROLL_THUMB, htDown, htHot, &r);
248  SCROLL_ThemeDrawPart(pcontext, SBP_GRIPPERHORZ, BUTTON_NORMAL, psbi, SCROLL_THUMB, htDown, htHot, &r);
249  }
250 }
251 
252 static void SCROLL_DrawMovingThumb(PWND_DATA pwndData, PDRAW_CONTEXT pcontext, SCROLLBARINFO* psbi, BOOL vertical)
253 {
254  INT pos = pwndData->SCROLL_TrackingPos;
255  INT max_size;
256 
257  if( vertical )
258  max_size = psbi->rcScrollBar.bottom - psbi->rcScrollBar.top;
259  else
260  max_size = psbi->rcScrollBar.right - psbi->rcScrollBar.left;
261 
262  max_size -= psbi->xyThumbBottom - psbi->xyThumbTop + psbi->dxyLineButton;
263 
264  if( pos < (psbi->dxyLineButton) )
265  pos = (psbi->dxyLineButton);
266  else if( pos > max_size )
267  pos = max_size;
268 
269  SCROLL_DrawInterior(pcontext, psbi, pos, vertical, SCROLL_THUMB, 0);
270 
271  pwndData->SCROLL_MovingThumb = !pwndData->SCROLL_MovingThumb;
272 }
273 
274 
275 void
277 {
278  SCROLLINFO si;
279  SCROLLBARINFO sbi;
280  BOOL vertical;
281  enum SCROLL_HITTEST htHot = SCROLL_NOWHERE;
282  PWND_DATA pwndData;
283 
284  if (((nBar == SB_VERT) && !(pcontext->wi.dwStyle & WS_VSCROLL)) ||
285  ((nBar == SB_HORZ) && !(pcontext->wi.dwStyle & WS_HSCROLL))) return;
286 
287  if (!(pwndData = ThemeGetWndData(pcontext->hWnd)))
288  return;
289 
290  if (pwndData->SCROLL_TrackingWin)
291  return;
292 
293  /* Retrieve scrollbar info */
294  sbi.cbSize = sizeof(sbi);
295  si.cbSize = sizeof(si);
296  si.fMask = SIF_ALL ;
297  GetScrollInfo(pcontext->hWnd, nBar, &si);
298  GetScrollBarInfo(pcontext->hWnd, SCROLL_getObjectId(nBar), &sbi);
299  vertical = SCROLL_IsVertical(pcontext->hWnd, nBar);
302  {
303  sbi.xyThumbTop = 0;
304  }
305 
306  /* The scrollbar rect is in screen coordinates */
307  OffsetRect(&sbi.rcScrollBar, -pcontext->wi.rcWindow.left, -pcontext->wi.rcWindow.top);
308 
309  if(pt)
310  {
311  ScreenToWindow(pcontext->hWnd, pt);
312  htHot = SCROLL_HitTest(pcontext->hWnd, &sbi, vertical, *pt, FALSE);
313  }
314 
315  /* do not draw if the scrollbar rectangle is empty */
316  if(IsRectEmpty(&sbi.rcScrollBar)) return;
317 
318  /* Draw the scrollbar */
319  SCROLL_DrawArrows( pcontext, &sbi, vertical, 0, htHot );
320  SCROLL_DrawInterior( pcontext, &sbi, sbi.xyThumbTop, vertical, 0, htHot );
321 }
322 
323 
324 
325 /***********************************************************************
326  * SCROLL_ClipPos
327  */
328 static POINT SCROLL_ClipPos( LPRECT lpRect, POINT pt )
329 {
330  if( pt.x < lpRect->left )
331  pt.x = lpRect->left;
332  else
333  if( pt.x > lpRect->right )
334  pt.x = lpRect->right;
335 
336  if( pt.y < lpRect->top )
337  pt.y = lpRect->top;
338  else
339  if( pt.y > lpRect->bottom )
340  pt.y = lpRect->bottom;
341 
342  return pt;
343 }
344 
345 
346 
347 /***********************************************************************
348  * SCROLL_GetThumbVal
349  *
350  * Compute the current scroll position based on the thumb position in pixels
351  * from the top of the scroll-bar.
352  */
354  BOOL vertical, INT pos )
355 {
356  INT thumbSize;
357  INT pixels = vertical ? rect->bottom-rect->top : rect->right-rect->left;
358  INT range;
359 
361  return psi->nMin;
362 
363  if (psi->nPage)
364  {
365  thumbSize = MulDiv(pixels,psi->nPage,(psi->nMax-psi->nMin+1));
366  if (thumbSize < SCROLL_MIN_THUMB) thumbSize = SCROLL_MIN_THUMB;
367  }
368  else thumbSize = GetSystemMetrics(SM_CXVSCROLL);
369 
370  if ((pixels -= thumbSize) <= 0) return psi->nMin;
371 
373  if (pos > pixels) pos = pixels;
374 
375  if (!psi->nPage)
376  range = psi->nMax - psi->nMin;
377  else
378  range = psi->nMax - psi->nMin - psi->nPage + 1;
379 
380  return psi->nMin + MulDiv(pos, range, pixels);
381 }
382 
383 static void
385 {
386  /* Previous mouse position for timer events */
387  static POINT prevPt;
388  /* Thumb position when tracking started. */
389  static UINT trackThumbPos;
390  /* Position in the scroll-bar of the last button-down event. */
391  static INT lastClickPos;
392  /* Position in the scroll-bar of the last mouse event. */
393  static INT lastMousePos;
394 
395  enum SCROLL_HITTEST hittest;
396  HWND hwndOwner, hwndCtl;
397  BOOL vertical;
398  SCROLLINFO si;
399  SCROLLBARINFO sbi;
401 
402  si.cbSize = sizeof(si);
403  sbi.cbSize = sizeof(sbi);
404  si.fMask = SIF_ALL;
405  GetScrollInfo(hwnd, nBar, &si);
407  vertical = SCROLL_IsVertical(hwnd, nBar);
410  {
411  return;
412  }
413 
414  if ((pwndData->SCROLL_trackHitTest == SCROLL_NOWHERE) && (msg != WM_LBUTTONDOWN))
415  return;
416 
418 
419  /* The scrollbar rect is in screen coordinates */
420  OffsetRect(&sbi.rcScrollBar, -context.wi.rcWindow.left, -context.wi.rcWindow.top);
421 
422  hwndOwner = (nBar == SB_CTL) ? GetParent(hwnd) : hwnd;
423  hwndCtl = (nBar == SB_CTL) ? hwnd : 0;
424 
425  switch(msg)
426  {
427  case WM_LBUTTONDOWN: /* Initialise mouse tracking */
428  HideCaret(hwnd); /* hide caret while holding down LBUTTON */
429  pwndData->SCROLL_trackVertical = vertical;
430  pwndData->SCROLL_trackHitTest = hittest = SCROLL_HitTest( hwnd, &sbi, vertical, pt, FALSE );
431  lastClickPos = vertical ? (pt.y - sbi.rcScrollBar.top) : (pt.x - sbi.rcScrollBar.left);
432  lastMousePos = lastClickPos;
433  trackThumbPos = sbi.xyThumbTop;
434  prevPt = pt;
435  SetCapture( hwnd );
436  break;
437 
438  case WM_MOUSEMOVE:
439  hittest = SCROLL_HitTest( hwnd, &sbi, vertical, pt, TRUE );
440  prevPt = pt;
441  break;
442 
443  case WM_LBUTTONUP:
444  hittest = SCROLL_NOWHERE;
445  ReleaseCapture();
446  /* if scrollbar has focus, show back caret */
447  if (hwnd==GetFocus())
448  ShowCaret(hwnd);
449  break;
450 
451  case WM_SYSTIMER:
452  pt = prevPt;
453  hittest = SCROLL_HitTest( hwnd, &sbi, vertical, pt, FALSE );
454  break;
455 
456  default:
457  return; /* Should never happen */
458  }
459 
460  //TRACE("Event: hwnd=%p bar=%d msg=%s pt=%d,%d hit=%d\n",
461  // hwnd, nBar, SPY_GetMsgName(msg,hwnd), pt.x, pt.y, hittest );
462 
463  switch(pwndData->SCROLL_trackHitTest)
464  {
465  case SCROLL_NOWHERE: /* No tracking in progress */
466  break;
467 
468  case SCROLL_TOP_ARROW:
469  if (hittest == pwndData->SCROLL_trackHitTest)
470  {
471  SCROLL_DrawArrows( &context, &sbi, vertical, pwndData->SCROLL_trackHitTest, 0 );
472  if ((msg == WM_LBUTTONDOWN) || (msg == WM_SYSTIMER))
473  {
474  SendMessageW( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
475  SB_LINEUP, (LPARAM)hwndCtl );
476  }
477 
480  }
481  else
482  {
483  SCROLL_DrawArrows( &context, &sbi, vertical, 0, 0 );
485  }
486 
487  break;
488 
489  case SCROLL_TOP_RECT:
490  SCROLL_DrawInterior( &context, &sbi, sbi.xyThumbTop, vertical, pwndData->SCROLL_trackHitTest, 0);
491  if (hittest == pwndData->SCROLL_trackHitTest)
492  {
493  if ((msg == WM_LBUTTONDOWN) || (msg == WM_SYSTIMER))
494  {
495  SendMessageW( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
496  SB_PAGEUP, (LPARAM)hwndCtl );
497  }
500  }
502  break;
503 
504  case SCROLL_THUMB:
505  if (msg == WM_LBUTTONDOWN)
506  {
507  pwndData->SCROLL_TrackingWin = hwnd;
508  pwndData->SCROLL_TrackingBar = nBar;
509  pwndData->SCROLL_TrackingPos = trackThumbPos + lastMousePos - lastClickPos;
510  pwndData->SCROLL_TrackingVal = SCROLL_GetThumbVal( &si, &sbi.rcScrollBar,
511  vertical, pwndData->SCROLL_TrackingPos );
512  if (!pwndData->SCROLL_MovingThumb)
513  SCROLL_DrawMovingThumb(pwndData, &context, &sbi, vertical);
514  }
515  else if (msg == WM_LBUTTONUP)
516  {
517  if (pwndData->SCROLL_MovingThumb)
518  SCROLL_DrawMovingThumb(pwndData, &context, &sbi, vertical);
519 
520  SCROLL_DrawInterior( &context, &sbi, sbi.xyThumbTop, vertical, 0, pwndData->SCROLL_trackHitTest );
521  }
522  else /* WM_MOUSEMOVE */
523  {
524  INT pos;
525 
526  if (!SCROLL_PtInRectEx( &sbi.rcScrollBar, pt, vertical ))
527  pos = lastClickPos;
528  else
529  {
530  pt = SCROLL_ClipPos( &sbi.rcScrollBar, pt );
531  pos = vertical ? (pt.y - sbi.rcScrollBar.top) : (pt.x - sbi.rcScrollBar.left);
532  }
533  if ( (pos != lastMousePos) || (!pwndData->SCROLL_MovingThumb) )
534  {
535  if (pwndData->SCROLL_MovingThumb)
536  SCROLL_DrawMovingThumb(pwndData, &context, &sbi, vertical);
537  lastMousePos = pos;
538  pwndData->SCROLL_TrackingPos = trackThumbPos + pos - lastClickPos;
539  pwndData->SCROLL_TrackingVal = SCROLL_GetThumbVal( &si, &sbi.rcScrollBar,
540  vertical,
541  pwndData->SCROLL_TrackingPos );
542  SendMessageW( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
544  (LPARAM)hwndCtl );
545  if (!pwndData->SCROLL_MovingThumb)
546  SCROLL_DrawMovingThumb(pwndData, &context, &sbi, vertical);
547  }
548  }
549  break;
550 
551  case SCROLL_BOTTOM_RECT:
552  if (hittest == pwndData->SCROLL_trackHitTest)
553  {
554  SCROLL_DrawInterior( &context, &sbi, sbi.xyThumbTop, vertical, pwndData->SCROLL_trackHitTest, 0 );
555  if ((msg == WM_LBUTTONDOWN) || (msg == WM_SYSTIMER))
556  {
557  SendMessageW( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
558  SB_PAGEDOWN, (LPARAM)hwndCtl );
559  }
562  }
563  else
564  {
565  SCROLL_DrawInterior( &context, &sbi, sbi.xyThumbTop, vertical, 0, 0 );
567  }
568  break;
569 
570  case SCROLL_BOTTOM_ARROW:
571  if (hittest == pwndData->SCROLL_trackHitTest)
572  {
573  SCROLL_DrawArrows( &context, &sbi, vertical, pwndData->SCROLL_trackHitTest, 0 );
574  if ((msg == WM_LBUTTONDOWN) || (msg == WM_SYSTIMER))
575  {
576  SendMessageW( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
577  SB_LINEDOWN, (LPARAM)hwndCtl );
578  }
579 
582  }
583  else
584  {
585  SCROLL_DrawArrows( &context, &sbi, vertical, 0, 0 );
587  }
588  break;
589  }
590 
591  if (msg == WM_LBUTTONDOWN)
592  {
593 
594  if (hittest == SCROLL_THUMB)
595  {
596  UINT val = SCROLL_GetThumbVal( &si, &sbi.rcScrollBar, vertical,
597  trackThumbPos + lastMousePos - lastClickPos );
598  SendMessageW( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
599  MAKEWPARAM( SB_THUMBTRACK, val ), (LPARAM)hwndCtl );
600  }
601  }
602 
603  if (msg == WM_LBUTTONUP)
604  {
605  hittest = pwndData->SCROLL_trackHitTest;
606  pwndData->SCROLL_trackHitTest = SCROLL_NOWHERE; /* Terminate tracking */
607 
608  if (hittest == SCROLL_THUMB)
609  {
610  UINT val = SCROLL_GetThumbVal( &si, &sbi.rcScrollBar, vertical,
611  trackThumbPos + lastMousePos - lastClickPos );
612  SendMessageW( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
613  MAKEWPARAM( SB_THUMBPOSITION, val ), (LPARAM)hwndCtl );
614  }
615  /* SB_ENDSCROLL doesn't report thumb position */
616  SendMessageW( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
617  SB_ENDSCROLL, (LPARAM)hwndCtl );
618 
619  /* Terminate tracking */
620  pwndData->SCROLL_TrackingWin = 0;
621  }
622 
624 }
625 
626 static void
628 {
629  MSG msg;
630  PWND_DATA pwndData = ThemeGetWndData(hwnd);
631  if(!pwndData)
632  return;
633 
635 
636  SCROLL_HandleScrollEvent(pwndData, hwnd, scrollbar, WM_LBUTTONDOWN, pt );
637 
638  do
639  {
640  if (!GetMessageW( &msg, 0, 0, 0 )) break;
641  if (CallMsgFilterW( &msg, MSGF_SCROLLBAR )) continue;
642  if (msg.message == WM_LBUTTONUP ||
643  msg.message == WM_MOUSEMOVE ||
644  (msg.message == WM_SYSTIMER && msg.wParam == SCROLL_TIMER))
645  {
646  pt.x = GET_X_LPARAM(msg.lParam);
647  pt.y = GET_Y_LPARAM(msg.lParam);
650  SCROLL_HandleScrollEvent(pwndData, hwnd, scrollbar, msg.message, pt );
651  }
652  else
653  {
654  TranslateMessage( &msg );
655  DispatchMessageW( &msg );
656  }
657  if (!IsWindow( hwnd ))
658  {
659  ReleaseCapture();
660  break;
661  }
662  } while (msg.message != WM_LBUTTONUP && GetCapture() == hwnd);
663 }
664 
666 {
667  INT scrollbar;
668 
669  if ((wParam & 0xfff0) == SC_HSCROLL)
670  {
671  if ((wParam & 0x0f) != HTHSCROLL) return;
672  scrollbar = SB_HORZ;
673  }
674  else /* SC_VSCROLL */
675  {
676  if ((wParam & 0x0f) != HTVSCROLL) return;
677  scrollbar = SB_VERT;
678  }
679  SCROLL_TrackScrollBar( hwnd, scrollbar, pt );
680 }
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
#define SB_PAGEDOWN
Definition: winuser.h:569
#define SCROLL_NOWHERE
Definition: scrollbar.c:14
#define SB_PAGEUP
Definition: winuser.h:568
#define max(a, b)
Definition: svc.c:63
BOOL WINAPI TranslateMessage(_In_ const MSG *)
#define STATE_SYSTEM_UNAVAILABLE
Definition: winuser.h:2836
#define HTHSCROLL
Definition: winuser.h:2456
#define TRUE
Definition: types.h:120
#define MAKEWPARAM(l, h)
Definition: winuser.h:3948
INT SCROLL_TrackingVal
Definition: uxthemep.h:169
BOOL WINAPI ClientToScreen(_In_ HWND, _Inout_ LPPOINT)
#define WM_LBUTTONDOWN
Definition: winuser.h:1758
BOOL WINAPI OffsetRect(_Inout_ LPRECT, _In_ int, _In_ int)
BOOL WINAPI IsWindow(_In_opt_ HWND)
#define WM_SYSTIMER
Definition: comctl32.h:111
#define SB_CTL
Definition: winuser.h:554
Definition: http.c:6587
#define SB_VERT
Definition: winuser.h:553
#define SCROLL_REPEAT_DELAY
Definition: uxthemep.h:237
#define pt(x, y)
Definition: drawing.c:79
DWORD dwStyle
Definition: winuser.h:3743
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1827
#define SB_HORZ
Definition: winuser.h:552
void ThemeCleanupDrawContext(PDRAW_CONTEXT pcontext)
Definition: nonclient.c:180
#define SCROLL_BOTTOM_RECT
Definition: scrollbar.c:18
HWND hWnd
Definition: settings.c:17
LONG top
Definition: windef.h:292
static void ScreenToWindow(HWND hWnd, POINT *pt)
Definition: ncscrollbar.c:16
#define GET_X_LPARAM(lp)
Definition: windowsx.h:274
void ThemeInitDrawContext(PDRAW_CONTEXT pcontext, HWND hWnd, HRGN hRgn)
Definition: nonclient.c:156
#define assert(x)
Definition: debug.h:53
#define SCROLL_BOTTOM_ARROW
Definition: scrollbar.c:19
UINT_PTR WPARAM
Definition: windef.h:207
LONG left
Definition: windef.h:291
static enum SCROLL_HITTEST SCROLL_HitTest(HWND hwnd, SCROLLBARINFO *psbi, BOOL vertical, POINT pt, BOOL bDragging)
Definition: ncscrollbar.c:87
#define SCROLL_TOP_ARROW
Definition: scrollbar.c:15
LONG right
Definition: windef.h:293
HRESULT WINAPI DrawThemeBackground(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, const RECT *pClipRect)
Definition: draw.c:128
int32_t INT
Definition: typedefs.h:56
& rect
Definition: startmenu.cpp:1413
WPARAM wParam
Definition: combotst.c:138
static POINT SCROLL_ClipPos(LPRECT lpRect, POINT pt)
Definition: ncscrollbar.c:328
static LONG SCROLL_getObjectId(INT nBar)
Definition: ncscrollbar.c:38
BOOL WINAPI CallMsgFilterW(_In_ LPMSG, _In_ INT)
LRESULT WINAPI DispatchMessageW(_In_ const MSG *)
BOOL WINAPI HideCaret(_In_opt_ HWND)
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
HTHEME scrolltheme
Definition: uxthemep.h:178
static void SCROLL_DrawInterior(PDRAW_CONTEXT pcontext, SCROLLBARINFO *psbi, INT thumbPos, BOOL vertical, int htDown, int htHot)
Definition: ncscrollbar.c:182
#define SCROLL_THUMB
Definition: scrollbar.c:17
HWND WINAPI GetCapture(void)
Definition: message.c:2879
static INT max_size
Definition: history.c:51
BOOL WINAPI IsRectEmpty(_In_ LPCRECT)
smooth NULL
Definition: ftsmooth.c:416
SCROLL_HITTEST
#define SB_THUMBPOSITION
Definition: winuser.h:572
static void SCROLL_TrackScrollBar(HWND hwnd, INT scrollbar, POINT pt)
Definition: ncscrollbar.c:627
LONG_PTR LPARAM
Definition: windef.h:208
void ThemeDrawScrollBar(PDRAW_CONTEXT pcontext, INT nBar, POINT *pt)
Definition: ncscrollbar.c:276
#define SCROLL_ARROW_THUMB_OVERLAP
Definition: uxthemep.h:231
RECT rcWindow
Definition: winuser.h:3741
static BOOL SCROLL_PtInRectEx(LPRECT lpRect, POINT pt, BOOL vertical)
Definition: ncscrollbar.c:55
static void SCROLL_HandleScrollEvent(PWND_DATA pwndData, HWND hwnd, INT nBar, UINT msg, POINT pt)
Definition: ncscrollbar.c:384
#define SB_ENDSCROLL
Definition: winuser.h:574
BOOL WINAPI GetScrollBarInfo(_In_ HWND, _In_ LONG, _Inout_ PSCROLLBARINFO)
UINT_PTR WINAPI SetSystemTimer(HWND, UINT_PTR, UINT, TIMERPROC)
Definition: ntwrapper.h:106
static UINT SCROLL_GetThumbVal(SCROLLINFO *psi, RECT *rect, BOOL vertical, INT pos)
Definition: ncscrollbar.c:353
WINDOWINFO wi
Definition: uxthemep.h:180
GLuint GLfloat * val
Definition: glext.h:7180
DWORD rgstate[CCHILDREN_SCROLLBAR+1]
Definition: winuser.h:3728
BOOL SCROLL_MovingThumb
Definition: uxthemep.h:165
INT SCROLL_TrackingBar
Definition: uxthemep.h:167
static BOOL SCROLL_IsVertical(HWND hwnd, INT nBar)
Definition: ncscrollbar.c:24
#define OBJID_HSCROLL
Definition: winable.h:21
#define SB_THUMBTRACK
Definition: winuser.h:573
void NC_TrackScrollBar(HWND hwnd, WPARAM wParam, POINT pt)
Definition: ncscrollbar.c:665
int WINAPI GetSystemMetrics(_In_ int)
#define OBJID_VSCROLL
Definition: winable.h:20
#define WS_HSCROLL
Definition: pedump.c:628
static void SCROLL_ThemeDrawPart(PDRAW_CONTEXT pcontext, int iPartId, int iStateId, SCROLLBARINFO *psbi, int htCurrent, int htDown, int htHot, RECT *r)
Definition: ncscrollbar.c:127
BOOL WINAPI GetScrollInfo(_In_ HWND, _In_ int, _Inout_ LPSCROLLINFO)
#define SCROLL_FIRST_DELAY
Definition: uxthemep.h:234
INT SCROLL_TrackingPos
Definition: uxthemep.h:168
#define SCROLL_MIN_THUMB
BOOL WINAPI KillSystemTimer(HWND, UINT_PTR)
Definition: timer.c:35
GLenum GLint * range
Definition: glext.h:7539
HWND WINAPI GetParent(_In_ HWND)
HWND WINAPI SetCapture(_In_ HWND hWnd)
#define MSGF_SCROLLBAR
Definition: winuser.h:1164
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define WM_LBUTTONUP
Definition: winuser.h:1759
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
Definition: gl.h:1546
unsigned int UINT
Definition: ndis.h:50
#define SB_LINEDOWN
Definition: winuser.h:565
#define WM_MOUSEMOVE
Definition: winuser.h:1757
#define WM_HSCROLL
Definition: winuser.h:1725
#define SB_LINEUP
Definition: winuser.h:564
#define WS_VSCROLL
Definition: pedump.c:627
#define SM_CXVSCROLL
Definition: winuser.h:951
HWND SCROLL_TrackingWin
Definition: uxthemep.h:166
BOOL WINAPI GetMessageW(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT)
#define GET_Y_LPARAM(lp)
Definition: windowsx.h:275
#define HTVSCROLL
Definition: winuser.h:2457
BOOL WINAPI PtInRect(_In_ LPCRECT, _In_ POINT)
HWND WINAPI GetFocus(void)
Definition: window.c:1875
#define msg(x)
Definition: auth_time.c:54
BOOL WINAPI ReleaseCapture(void)
Definition: message.c:2888
static void SCROLL_DrawMovingThumb(PWND_DATA pwndData, PDRAW_CONTEXT pcontext, SCROLLBARINFO *psbi, BOOL vertical)
Definition: ncscrollbar.c:252
LONG bottom
Definition: windef.h:294
BOOL WINAPI ShowCaret(_In_opt_ HWND)
BOOL WINAPI GetWindowRect(_In_ HWND, _Out_ LPRECT)
PWND_DATA ThemeGetWndData(HWND hWnd)
Definition: themehooks.c:17
RECT rcClient
Definition: winuser.h:3742
BOOL SCROLL_trackVertical
Definition: uxthemep.h:163
#define SCROLL_TOP_RECT
Definition: scrollbar.c:16
#define SCROLL_TIMER
Definition: uxthemep.h:228
#define MulDiv(x, y, z)
Definition: gdifloat.h:86
#define WM_VSCROLL
Definition: winuser.h:1726
#define SIF_ALL
Definition: winuser.h:1218
enum SCROLL_HITTEST SCROLL_trackHitTest
Definition: uxthemep.h:164
static void SCROLL_DrawArrows(PDRAW_CONTEXT pcontext, SCROLLBARINFO *psbi, BOOL vertical, int htDown, int htHot)
Definition: ncscrollbar.c:147
#define SC_HSCROLL
Definition: winuser.h:2569