ReactOS  0.4.15-dev-338-g3dad100
scrollbar.c
Go to the documentation of this file.
1 /*
2  * ReactOS User32 Library
3  * - ScrollBar control
4  *
5  * Copyright 2001 Casper S. Hornstrup
6  * Copyright 2003 Thomas Weidenmueller
7  * Copyright 2003 Filip Navara
8  *
9  * Based on Wine code.
10  *
11  * Copyright 1993 Martin Ayotte
12  * Copyright 1994, 1996 Alexandre Julliard
13  *
14  * This library is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU Lesser General Public
16  * License as published by the Free Software Foundation; either
17  * version 2.1 of the License, or (at your option) any later version.
18  *
19  * This library is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22  * Lesser General Public License for more details.
23  *
24  * You should have received a copy of the GNU Lesser General Public
25  * License along with this library; if not, write to the Free Software
26  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
27  */
28 
29 #include <user32.h>
30 
32 
33 /* Definitions for scrollbar hit testing [See SCROLLBARINFO in MSDN] */
34 #define SCROLL_NOWHERE 0x00 /* Outside the scroll bar */
35 #define SCROLL_TOP_ARROW 0x01 /* Top or left arrow */
36 #define SCROLL_TOP_RECT 0x02 /* Rectangle between the top arrow and the thumb */
37 #define SCROLL_THUMB 0x03 /* Thumb rectangle */
38 #define SCROLL_BOTTOM_RECT 0x04 /* Rectangle between the thumb and the bottom arrow */
39 #define SCROLL_BOTTOM_ARROW 0x05 /* Bottom or right arrow */
40 
41 #define SCROLL_FIRST_DELAY 200 /* Delay (in ms) before first repetition when
42  holding the button down */
43 #define SCROLL_REPEAT_DELAY 50 /* Delay (in ms) between scroll repetitions */
44 
45 #define SCROLL_TIMER 0 /* Scroll timer id */
46 
47  /* Minimum size of the rectangle between the arrows */
48 #define SCROLL_MIN_RECT 4
49 
50  /* Minimum size of the thumb in pixels */
51 #define SCROLL_MIN_THUMB 6
52 
53  /* Overlap between arrows and thumb */
54 #define SCROLL_ARROW_THUMB_OVERLAP 0
55 
56  /* Thumb-tracking info */
61  /* Hit test code of the last button-down event */
64 
65  /* Is the moving thumb being displayed? */
67 
68 HBRUSH DefWndControlColor(HDC hDC, UINT ctlType);
69 
72 
73 /*********************************************************************
74  * scrollbar class descriptor
75  */
77 {
78  L"ScrollBar", /* name */
79  CS_DBLCLKS | CS_VREDRAW | CS_HREDRAW | CS_PARENTDC, /* style */
80  ScrollBarWndProcA, /* procA */
81  ScrollBarWndProcW, /* procW */
82  sizeof(SBWND)-sizeof(WND), /* extra */
83  IDC_ARROW, /* cursor */
84  0 /* brush */
85 };
86 
87 /* PRIVATE FUNCTIONS **********************************************************/
88 
89 static PSBDATA
90 IntGetSBData(PWND pwnd, INT Bar)
91 {
92  PSBWND pSBWnd;
93  PSBINFO pSBInfo;
94 
95  pSBInfo = DesktopPtrToUser(pwnd->pSBInfo);
96  switch (Bar)
97  {
98  case SB_HORZ:
99  return &pSBInfo->Horz;
100  case SB_VERT:
101  return &pSBInfo->Vert;
102  case SB_CTL:
103  if ( pwnd->cbwndExtra < (sizeof(SBWND)-sizeof(WND)) )
104  {
105  ERR("IntGetSBData Wrong Extra bytes for CTL Scrollbar!\n");
106  return 0;
107  }
108  pSBWnd = (PSBWND)pwnd;
109  return (PSBDATA)&pSBWnd->SBCalc;
110  default:
111  ERR("IntGetSBData Bad Bar!\n");
112  }
113  return NULL;
114 }
115 
116 static void
118  PSCROLLBARINFO ScrollBarInfo)
119 {
120  INT ThumbSize = ScrollBarInfo->xyThumbBottom - ScrollBarInfo->xyThumbTop;
121  INT ThumbTop = ScrollBarInfo->xyThumbTop;
122  RECT Rect;
123  HBRUSH hSaveBrush, hBrush;
124  BOOL TopSelected = FALSE, BottomSelected = FALSE;
125 
126  if (ScrollBarInfo->rgstate[SCROLL_TOP_RECT] & STATE_SYSTEM_PRESSED)
127  TopSelected = TRUE;
128  if (ScrollBarInfo->rgstate[SCROLL_BOTTOM_RECT] & STATE_SYSTEM_PRESSED)
129  BottomSelected = TRUE;
130 
131  /*
132  * Only scrollbar controls send WM_CTLCOLORSCROLLBAR.
133  * The window-owned scrollbars need to call DefWndControlColor
134  * to correctly setup default scrollbar colors
135  */
136  if (nBar == SB_CTL)
137  {
139  if (!hBrush)
141  }
142  else
143  {
145  }
146 
147  hSaveBrush = SelectObject(hDC, hBrush);
148 
149  /* Calculate the scroll rectangle */
150  if (Vertical)
151  {
152  Rect.top = ScrollBarInfo->rcScrollBar.top + ScrollBarInfo->dxyLineButton;
153  Rect.bottom = ScrollBarInfo->rcScrollBar.bottom - ScrollBarInfo->dxyLineButton;
154  Rect.left = ScrollBarInfo->rcScrollBar.left;
155  Rect.right = ScrollBarInfo->rcScrollBar.right;
156  }
157  else
158  {
159  Rect.top = ScrollBarInfo->rcScrollBar.top;
160  Rect.bottom = ScrollBarInfo->rcScrollBar.bottom;
161  Rect.left = ScrollBarInfo->rcScrollBar.left + ScrollBarInfo->dxyLineButton;
162  Rect.right = ScrollBarInfo->rcScrollBar.right - ScrollBarInfo->dxyLineButton;
163  }
164 
165  /* Draw the scroll rectangles and thumb */
166  if (!ScrollBarInfo->xyThumbBottom)
167  {
168  PatBlt(hDC, Rect.left, Rect.top, Rect.right - Rect.left,
169  Rect.bottom - Rect.top, PATCOPY);
170 
171  /* Cleanup and return */
172  SelectObject(hDC, hSaveBrush);
173  return;
174  }
175 
176  ThumbTop -= ScrollBarInfo->dxyLineButton;
177 
178  if (ScrollBarInfo->dxyLineButton)
179  {
180  if (Vertical)
181  {
182  if (ThumbSize)
183  {
184  PatBlt(hDC, Rect.left, Rect.top, Rect.right - Rect.left,
185  ThumbTop, TopSelected ? BLACKNESS : PATCOPY);
186  Rect.top += ThumbTop;
187  PatBlt(hDC, Rect.left, Rect.top + ThumbSize, Rect.right - Rect.left,
188  Rect.bottom - Rect.top - ThumbSize, BottomSelected ? BLACKNESS : PATCOPY);
189  Rect.bottom = Rect.top + ThumbSize;
190  }
191  else
192  {
193  if (ThumbTop)
194  {
195  PatBlt(hDC, Rect.left, ScrollBarInfo->dxyLineButton,
196  Rect.right - Rect.left, Rect.bottom - Rect.top, PATCOPY);
197  }
198  }
199  }
200  else
201  {
202  if (ThumbSize)
203  {
204  PatBlt(hDC, Rect.left, Rect.top, ThumbTop,
205  Rect.bottom - Rect.top, TopSelected ? BLACKNESS : PATCOPY);
206  Rect.left += ThumbTop;
207  PatBlt(hDC, Rect.left + ThumbSize, Rect.top,
208  Rect.right - Rect.left - ThumbSize, Rect.bottom - Rect.top,
209  BottomSelected ? BLACKNESS : PATCOPY);
210  Rect.right = Rect.left + ThumbSize;
211  }
212  else
213  {
214  if (ThumbTop)
215  {
216  PatBlt(hDC, ScrollBarInfo->dxyLineButton, Rect.top,
217  Rect.right - Rect.left, Rect.bottom - Rect.top, PATCOPY);
218  }
219  }
220  }
221  }
222 
223  /* Draw the thumb */
224  if (ThumbSize)
226 
227  /* Cleanup */
228  SelectObject(hDC, hSaveBrush);
229 }
230 
231 static VOID FASTCALL
232 IntDrawScrollArrows(HDC hDC, PSCROLLBARINFO ScrollBarInfo, BOOL Vertical)
233 {
234  RECT RectLT, RectRB;
235  INT ScrollDirFlagLT, ScrollDirFlagRB;
236 
237  RectLT = RectRB = ScrollBarInfo->rcScrollBar;
238  if (Vertical)
239  {
240  ScrollDirFlagLT = DFCS_SCROLLUP;
241  ScrollDirFlagRB = DFCS_SCROLLDOWN;
242  RectLT.bottom = RectLT.top + ScrollBarInfo->dxyLineButton;
243  RectRB.top = RectRB.bottom - ScrollBarInfo->dxyLineButton;
244  }
245  else
246  {
247  ScrollDirFlagLT = DFCS_SCROLLLEFT;
248  ScrollDirFlagRB = DFCS_SCROLLRIGHT;
249  RectLT.right = RectLT.left + ScrollBarInfo->dxyLineButton;
250  RectRB.left = RectRB.right - ScrollBarInfo->dxyLineButton;
251  }
252 
253  if (ScrollBarInfo->rgstate[SCROLL_TOP_ARROW] & STATE_SYSTEM_PRESSED)
254  {
255  ScrollDirFlagLT |= DFCS_PUSHED | DFCS_FLAT;
256  }
257  if (ScrollBarInfo->rgstate[SCROLL_TOP_ARROW] & STATE_SYSTEM_UNAVAILABLE)
258  {
259  ScrollDirFlagLT |= DFCS_INACTIVE;
260  }
261  if (ScrollBarInfo->rgstate[SCROLL_BOTTOM_ARROW] & STATE_SYSTEM_PRESSED)
262  {
263  ScrollDirFlagRB |= DFCS_PUSHED | DFCS_FLAT;
264  }
266  {
267  ScrollDirFlagRB |= DFCS_INACTIVE;
268  }
269 
270  DrawFrameControl(hDC, &RectLT, DFC_SCROLL, ScrollDirFlagLT);
271  DrawFrameControl(hDC, &RectRB, DFC_SCROLL, ScrollDirFlagRB);
272 }
273 
274 static VOID FASTCALL
275 IntScrollDrawMovingThumb(HDC Dc, PSCROLLBARINFO ScrollBarInfo, BOOL Vertical)
276 {
278  INT MaxSize;
279  INT OldTop;
280 
281  if (Vertical)
282  MaxSize = ScrollBarInfo->rcScrollBar.bottom - ScrollBarInfo->rcScrollBar.top;
283  else
284  MaxSize = ScrollBarInfo->rcScrollBar.right - ScrollBarInfo->rcScrollBar.left;
285 
286  MaxSize -= ScrollBarInfo->dxyLineButton + ScrollBarInfo->xyThumbBottom - ScrollBarInfo->xyThumbTop;
287 
288  if (Pos < ScrollBarInfo->dxyLineButton)
289  Pos = ScrollBarInfo->dxyLineButton;
290  else if (MaxSize < Pos)
291  Pos = MaxSize;
292 
293  OldTop = ScrollBarInfo->xyThumbTop;
294  ScrollBarInfo->xyThumbBottom = Pos + ScrollBarInfo->xyThumbBottom - ScrollBarInfo->xyThumbTop;
295  ScrollBarInfo->xyThumbTop = Pos;
296  IntDrawScrollInterior(ScrollTrackingWin, Dc, ScrollTrackingBar, Vertical, ScrollBarInfo);
297  ScrollBarInfo->xyThumbBottom = OldTop + ScrollBarInfo->xyThumbBottom - ScrollBarInfo->xyThumbTop;
298  ScrollBarInfo->xyThumbTop = OldTop;
299 
301 }
302 
303 static LONG FASTCALL
305 {
306  if (SBType == SB_VERT)
307  return OBJID_VSCROLL;
308  if (SBType == SB_HORZ)
309  return OBJID_HSCROLL;
310  return OBJID_CLIENT;
311 }
312 
313 static BOOL FASTCALL
314 IntGetScrollBarInfo(HWND Wnd, INT Bar, PSCROLLBARINFO ScrollBarInfo)
315 {
316  ScrollBarInfo->cbSize = sizeof(SCROLLBARINFO);
317 
318  return NtUserGetScrollBarInfo(Wnd, IntScrollGetObjectId(Bar), ScrollBarInfo);
319 }
320 
321 static VOID FASTCALL
323  SETSCROLLBARINFO *info, INT SBType, INT Arrow,
324  BOOL Vertical, BOOL Pressed)
325 {
326  if (Pressed)
327  {
328  ScrollBarInfo->rgstate[Arrow] |= STATE_SYSTEM_PRESSED;
329  }
330  else
331  {
332  ScrollBarInfo->rgstate[Arrow] &= ~STATE_SYSTEM_PRESSED;
333  }
334  /* Update arrow state */
335  info->rgstate[Arrow] = ScrollBarInfo->rgstate[Arrow];
337 
338  IntDrawScrollArrows(hDC, ScrollBarInfo, Vertical);
339 }
340 
341 void
343 {
344  //PSBWND pSBWnd;
345  //INT ThumbSize;
347  BOOL Vertical;
348 
349  /*
350  * Get scroll bar info.
351  */
352  switch (Bar)
353  {
354  case SB_HORZ:
355  Vertical = FALSE;
356  break;
357 
358  case SB_VERT:
359  Vertical = TRUE;
360  break;
361 
362  case SB_CTL:
363  Vertical = (GetWindowLongPtrW(Wnd, GWL_STYLE) & SBS_VERT) != 0;
364  break;
365 
366  default:
367  return;
368  }
369  if (!IntGetScrollBarInfo(Wnd, Bar, &Info))
370  {
371  return;
372  }
373 
374  if (IsRectEmpty(&Info.rcScrollBar))
375  {
376  return;
377  }
378 
379  //ThumbSize = pSBWnd->pSBCalc->pxThumbBottom - pSBWnd->pSBCalc->pxThumbTop;
380 
381  /*
382  * Draw the arrows.
383  */
384  if (Info.dxyLineButton)
385  {
386  IntDrawScrollArrows(DC, &Info, Vertical);
387  }
388 
389  /*
390  * Draw the interior.
391  */
392  IntDrawScrollInterior(Wnd, DC, Bar, Vertical, &Info);
393 
394  /*
395  * If scroll bar has focus, reposition the caret.
396  */
397  if (Wnd == GetFocus() && SB_CTL == Bar)
398  {
399  if (Vertical)
400  {
401  SetCaretPos(Info.rcScrollBar.top + 1, Info.dxyLineButton + 1);
402  }
403  else
404  {
405  SetCaretPos(Info.dxyLineButton + 1, Info.rcScrollBar.top + 1);
406  }
407  }
408 }
409 
410 static BOOL FASTCALL
412 {
413  RECT TempRect = *Rect;
414  int scrollbarWidth;
415 
416  /* Pad hit rect to allow mouse to be dragged outside of scrollbar and
417  * still be considered in the scrollbar. */
418  if (Vertical)
419  {
420  scrollbarWidth = Rect->right - Rect->left;
421  TempRect.left -= scrollbarWidth*8;
422  TempRect.right += scrollbarWidth*8;
423  TempRect.top -= scrollbarWidth*2;
424  TempRect.bottom += scrollbarWidth*2;
425  }
426  else
427  {
428  scrollbarWidth = Rect->bottom - Rect->top;
429  TempRect.left -= scrollbarWidth*2;
430  TempRect.right += scrollbarWidth*2;
431  TempRect.top -= scrollbarWidth*8;
432  TempRect.bottom += scrollbarWidth*8;
433  }
434 
435  return PtInRect(&TempRect, Pt);
436 }
437 
438 static DWORD FASTCALL
439 IntScrollHitTest(PSCROLLBARINFO ScrollBarInfo, BOOL Vertical, POINT Pt, BOOL Dragging)
440 {
441  INT ArrowSize, ThumbSize, ThumbPos;
442 
443  if ((Dragging && ! IntScrollPtInRectEx(&ScrollBarInfo->rcScrollBar, Pt, Vertical)) ||
444  ! PtInRect(&ScrollBarInfo->rcScrollBar, Pt)) return SCROLL_NOWHERE;
445 
446  ThumbPos = ScrollBarInfo->xyThumbTop;
447  ThumbSize = ScrollBarInfo->xyThumbBottom - ThumbPos;
448  ArrowSize = ScrollBarInfo->dxyLineButton;
449 
450  if (Vertical)
451  {
452  if (Pt.y < ScrollBarInfo->rcScrollBar.top + ArrowSize) return SCROLL_TOP_ARROW;
453  if (Pt.y >= ScrollBarInfo->rcScrollBar.bottom - ArrowSize) return SCROLL_BOTTOM_ARROW;
454  if (!ThumbPos) return SCROLL_TOP_RECT;
455  Pt.y -= ScrollBarInfo->rcScrollBar.top;
456  if (Pt.y < ThumbPos) return SCROLL_TOP_RECT;
457  if (Pt.y >= ThumbPos + ThumbSize) return SCROLL_BOTTOM_RECT;
458  }
459  else
460  {
461  if (Pt.x < ScrollBarInfo->rcScrollBar.left + ArrowSize) return SCROLL_TOP_ARROW;
462  if (Pt.x >= ScrollBarInfo->rcScrollBar.right - ArrowSize) return SCROLL_BOTTOM_ARROW;
463  if (!ThumbPos) return SCROLL_TOP_RECT;
464  Pt.x -= ScrollBarInfo->rcScrollBar.left;
465  if (Pt.x < ThumbPos) return SCROLL_TOP_RECT;
466  if (Pt.x >= ThumbPos + ThumbSize) return SCROLL_BOTTOM_RECT;
467  }
468 
469  return SCROLL_THUMB;
470 }
471 
472 
473 /***********************************************************************
474  * IntScrollGetScrollBarRect
475  *
476  * Compute the scroll bar rectangle, in drawing coordinates (i.e. client
477  * coords for SB_CTL, window coords for SB_VERT and SB_HORZ).
478  * 'arrowSize' returns the width or height of an arrow (depending on
479  * the orientation of the scrollbar), 'thumbSize' returns the size of
480  * the thumb, and 'thumbPos' returns the position of the thumb
481  * relative to the left or to the top.
482  * Return TRUE if the scrollbar is vertical, FALSE if horizontal.
483  */
484 static BOOL FASTCALL
486  INT *ArrowSize, INT *ThumbSize,
487  INT *ThumbPos)
488 {
489  INT Pixels;
490  BOOL Vertical;
491  PWND pWnd;
492  PSBINFO pSBInfo;
493  PSBDATA pSBData;
494  PSBWND pSBWnd;
495 
496  pWnd = ValidateHwnd( Wnd );
497  if (!pWnd) return FALSE;
498  pSBInfo = DesktopPtrToUser(pWnd->pSBInfo);
499 
500  *Rect = pWnd->rcClient;
501  OffsetRect( Rect, -pWnd->rcWindow.left, -pWnd->rcWindow.top );
502  if (pWnd->ExStyle & WS_EX_LAYOUTRTL)
503  mirror_rect( &pWnd->rcWindow, Rect );
504 
505  switch (Bar)
506  {
507  case SB_HORZ:
508 // WIN_GetRectangles( Wnd, COORDS_WINDOW, NULL, Rect );
509  Rect->top = Rect->bottom;
510  Rect->bottom += GetSystemMetrics(SM_CYHSCROLL);
511  if (pWnd->style & WS_BORDER)
512  {
513  Rect->left--;
514  Rect->right++;
515  }
516  else if (pWnd->style & WS_VSCROLL)
517  {
518  Rect->right++;
519  }
520  Vertical = FALSE;
521  pSBData = &pSBInfo->Horz;
522  break;
523 
524  case SB_VERT:
525 // WIN_GetRectangles( Wnd, COORDS_WINDOW, NULL, Rect );
526  if (pWnd->ExStyle & WS_EX_LEFTSCROLLBAR)
527  {
528  Rect->right = Rect->left;
530  }
531  else
532  {
533  Rect->left = Rect->right;
535  }
536  if (pWnd->style & WS_BORDER)
537  {
538  Rect->top--;
539  Rect->bottom++;
540  }
541  else if (pWnd->style & WS_HSCROLL)
542  {
543  Rect->bottom++;
544  }
545  Vertical = TRUE;
546  pSBData = &pSBInfo->Vert;
547  break;
548 
549  case SB_CTL:
550  GetClientRect( Wnd, Rect );
551  Vertical = (pWnd->style & SBS_VERT);
552  pSBWnd = (PSBWND)pWnd;
553  pSBData = (PSBDATA)&pSBWnd->SBCalc;
554  break;
555 
556  default:
557  return FALSE;
558  }
559 
560  if (Vertical) Pixels = Rect->bottom - Rect->top;
561  else Pixels = Rect->right - Rect->left;
562 
563  if (Pixels <= 2 * GetSystemMetrics(SM_CXVSCROLL) + SCROLL_MIN_RECT)
564  {
565  if (SCROLL_MIN_RECT < Pixels)
566  *ArrowSize = (Pixels - SCROLL_MIN_RECT) / 2;
567  else
568  *ArrowSize = 0;
569  *ThumbPos = *ThumbSize = 0;
570  }
571  else
572  {
573  *ArrowSize = GetSystemMetrics(SM_CXVSCROLL);
575  if (pSBData->page)
576  {
577  *ThumbSize = MulDiv(Pixels, pSBData->page, (pSBData->posMax - pSBData->posMin + 1));
578  if (*ThumbSize < SCROLL_MIN_THUMB) *ThumbSize = SCROLL_MIN_THUMB;
579  }
580  else *ThumbSize = GetSystemMetrics(SM_CXVSCROLL);
581 
582  if (((Pixels -= *ThumbSize ) < 0) ||
583  (( pSBInfo->WSBflags & ESB_DISABLE_BOTH) == ESB_DISABLE_BOTH))
584  {
585  /* Rectangle too small or scrollbar disabled -> no thumb */
586  *ThumbPos = *ThumbSize = 0;
587  }
588  else
589  {
590  INT Max = pSBData->posMax - max(pSBData->page - 1, 0);
591  if (pSBData->posMin >= Max)
592  *ThumbPos = *ArrowSize - SCROLL_ARROW_THUMB_OVERLAP;
593  else
594  *ThumbPos = *ArrowSize - SCROLL_ARROW_THUMB_OVERLAP
595  + MulDiv(Pixels, (pSBData->pos - pSBData->posMin),(Max - pSBData->posMin));
596  }
597  }
598  return Vertical;
599 }
600 
601 /***********************************************************************
602  * IntScrollGetThumbVal
603  *
604  * Compute the current scroll position based on the thumb position in pixels
605  * from the top of the scroll-bar.
606  */
607 static UINT FASTCALL
608 IntScrollGetThumbVal(HWND Wnd, INT SBType, PSCROLLBARINFO ScrollBarInfo,
609  BOOL Vertical, INT Pos)
610 {
611  PWND pWnd;
612  PSBDATA pSBData;
613  INT Pixels = Vertical ? ScrollBarInfo->rcScrollBar.bottom
614  - ScrollBarInfo->rcScrollBar.top
615  : ScrollBarInfo->rcScrollBar.right
616  - ScrollBarInfo->rcScrollBar.left;
617 
618  pWnd = ValidateHwnd( Wnd );
619  if (!pWnd) return FALSE;
620 
621  pSBData = IntGetSBData(pWnd, SBType);
622 
623  if ((Pixels -= 2 * ScrollBarInfo->dxyLineButton) <= 0)
624  {
625  return pSBData->posMin;
626  }
627 
628  if ((Pixels -= (ScrollBarInfo->xyThumbBottom - ScrollBarInfo->xyThumbTop)) <= 0)
629  {
630  return pSBData->posMin;
631  }
632 
633  Pos = Pos - ScrollBarInfo->dxyLineButton;
634  if (Pos < 0)
635  {
636  Pos = 0;
637  }
638  if (Pos > Pixels) Pos = Pixels;
639 
640  if (!pSBData->page)
641  Pos *= pSBData->posMax - pSBData->posMin;
642  else
643  Pos *= pSBData->posMax - pSBData->posMin - pSBData->page + 1;
644 
645  return pSBData->posMin + ((Pos + Pixels / 2) / Pixels);
646 }
647 
648 /***********************************************************************
649  * IntScrollClipPos
650  */
652 {
653  if( pt.x < lpRect->left )
654  pt.x = lpRect->left;
655  else
656  if( pt.x > lpRect->right )
657  pt.x = lpRect->right;
658 
659  if( pt.y < lpRect->top )
660  pt.y = lpRect->top;
661  else
662  if( pt.y > lpRect->bottom )
663  pt.y = lpRect->bottom;
664 
665  return pt;
666 }
667 
668 /***********************************************************************
669  * IntScrollDrawSizeGrip
670  *
671  * Draw the size grip.
672  */
673 static void FASTCALL
675 {
676  RECT Rect;
677 
678  GetClientRect(Wnd, &Rect);
680  Rect.left = max(Rect.left, Rect.right - GetSystemMetrics(SM_CXVSCROLL) - 1);
681  Rect.top = max(Rect.top, Rect.bottom - GetSystemMetrics(SM_CYHSCROLL) - 1);
683 }
684 
685 /***********************************************************************
686  * SCROLL_RefreshScrollBar
687  *
688  * Repaint the scroll bar interior after a SetScrollRange() or
689  * SetScrollPos() call.
690  */
692  BOOL arrows, BOOL interior )
693 {
694  HDC hdc = GetDCEx( hwnd, 0,
695  DCX_CACHE | ((nBar == SB_CTL) ? 0 : DCX_WINDOW) );
696  if (!hdc) return;
697 
698  IntDrawScrollBar( hwnd, hdc, nBar);//, arrows, interior );
699  ReleaseDC( hwnd, hdc );
700 }
701 
702 
703 /***********************************************************************
704  * IntScrollHandleKbdEvent
705  *
706  * Handle a keyboard event (only for SB_CTL scrollbars with focus).
707  */
708 static void FASTCALL
710  HWND Wnd /* [in] Handle of window with scrollbar(s) */,
711  WPARAM wParam /* [in] Variable input including enable state */,
712  LPARAM lParam /* [in] Variable input including input point */)
713 {
714  TRACE("Wnd=%p wParam=%ld lParam=%ld\n", Wnd, wParam, lParam);
715 
716  /* hide caret on first KEYDOWN to prevent flicker */
717  if (0 == (lParam & PFD_DOUBLEBUFFER_DONTCARE))
718  {
719  HideCaret(Wnd);
720  }
721 
722  switch(wParam)
723  {
724  case VK_PRIOR:
725  wParam = SB_PAGEUP;
726  break;
727 
728  case VK_NEXT:
730  break;
731 
732  case VK_HOME:
733  wParam = SB_TOP;
734  break;
735 
736  case VK_END:
737  wParam = SB_BOTTOM;
738  break;
739 
740  case VK_UP:
741  wParam = SB_LINEUP;
742  break;
743 
744  case VK_DOWN:
746  break;
747 
748  default:
749  return;
750  }
751 
752  SendMessageW(GetParent(Wnd),
753  (0 != (GetWindowLongPtrW(Wnd, GWL_STYLE ) & SBS_VERT) ?
754  WM_VSCROLL : WM_HSCROLL), wParam, (LPARAM) Wnd);
755 }
756 
757 /***********************************************************************
758  * IntScrollHandleScrollEvent
759  *
760  * Handle a mouse or timer event for the scrollbar.
761  * 'Pt' is the location of the mouse event in drawing coordinates
762  */
763 static VOID FASTCALL
765 {
766  static POINT PrevPt; /* Previous mouse position for timer events */
767  static UINT TrackThumbPos; /* Thumb position when tracking started. */
768  static INT LastClickPos; /* Position in the scroll-bar of the last
769  button-down event. */
770  static INT LastMousePos; /* Position in the scroll-bar of the last
771  mouse event. */
772 
773  DWORD HitTest;
774  HWND WndOwner, WndCtl;
775  BOOL Vertical;
776  HDC Dc;
777  SCROLLBARINFO ScrollBarInfo;
778  SETSCROLLBARINFO NewInfo;
779 
780  if (! IntGetScrollBarInfo(Wnd, SBType, &ScrollBarInfo))
781  {
782  return;
783  }
785  {
787  if (Wnd == GetCapture())
788  {
789  ReleaseCapture();
790  }
792  return;
793  }
794 
795  NewInfo.nTrackPos = ScrollTrackingVal;
796  NewInfo.reserved = ScrollBarInfo.reserved;
797  memcpy(NewInfo.rgstate, ScrollBarInfo.rgstate, (CCHILDREN_SCROLLBAR + 1) * sizeof(DWORD));
798 
799  if (SBType == SB_CTL && (GetWindowLongPtrW(Wnd, GWL_STYLE) & (SBS_SIZEGRIP | SBS_SIZEBOX)))
800  {
801  switch(Msg)
802  {
803  case WM_LBUTTONDOWN: /* Initialise mouse tracking */
804  HideCaret(Wnd); /* hide caret while holding down LBUTTON */
805  SetCapture(Wnd);
806  PrevPt = Pt;
807  ScrollTrackHitTest = HitTest = SCROLL_THUMB;
808  break;
809  case WM_MOUSEMOVE:
810  GetClientRect(GetParent(GetParent(Wnd)), &ScrollBarInfo.rcScrollBar);
811  PrevPt = Pt;
812  break;
813  case WM_LBUTTONUP:
814  ReleaseCapture();
816  if (Wnd == GetFocus()) ShowCaret(Wnd);
817  break;
818  case WM_SYSTIMER:
819  Pt = PrevPt;
820  break;
821  }
822  return;
823  }
824 
825  Dc = GetDCEx(Wnd, 0, DCX_CACHE | ((SB_CTL == SBType) ? 0 : DCX_WINDOW));
826  if (SB_VERT == SBType)
827  {
828  Vertical = TRUE;
829  }
830  else if (SB_HORZ == SBType)
831  {
832  Vertical = FALSE;
833  }
834  else
835  {
836  Vertical = (0 != (GetWindowLongPtrW(Wnd, GWL_STYLE) & SBS_VERT));
837  }
838  WndOwner = (SB_CTL == SBType) ? GetParent(Wnd) : Wnd;
839  WndCtl = (SB_CTL == SBType) ? Wnd : NULL;
840 
841  switch (Msg)
842  {
843  case WM_LBUTTONDOWN: /* Initialise mouse tracking */
844  HideCaret(Wnd); /* hide caret while holding down LBUTTON */
845  ScrollTrackVertical = Vertical;
846  ScrollTrackHitTest = HitTest = IntScrollHitTest(&ScrollBarInfo, Vertical, Pt, FALSE );
847  LastClickPos = Vertical ? (Pt.y - ScrollBarInfo.rcScrollBar.top)
848  : (Pt.x - ScrollBarInfo.rcScrollBar.left);
849  LastMousePos = LastClickPos;
850  TrackThumbPos = ScrollBarInfo.xyThumbTop;
851  PrevPt = Pt;
852  if (SBType == SB_CTL && (GetWindowLongPtrW(Wnd, GWL_STYLE) & WS_TABSTOP)) SetFocus(Wnd);
853  SetCapture(Wnd);
854  /* Don't update scrollbar if disabled. */
856  {
857  IntUpdateScrollArrows (Wnd, Dc, &ScrollBarInfo, &NewInfo, SBType, ScrollTrackHitTest, Vertical, TRUE);
858  }
859  break;
860 
861  case WM_MOUSEMOVE:
862  HitTest = IntScrollHitTest(&ScrollBarInfo, Vertical, Pt, TRUE);
863  PrevPt = Pt;
864  break;
865 
866  case WM_LBUTTONUP:
867  HitTest = SCROLL_NOWHERE;
868  ReleaseCapture();
869  /* if scrollbar has focus, show back caret */
870  if (Wnd == GetFocus()) ShowCaret(Wnd);
871  /* Don't update scrollbar if disabled. */
873  {
874  IntUpdateScrollArrows (Wnd, Dc, &ScrollBarInfo, &NewInfo, SBType, ScrollTrackHitTest, Vertical, FALSE);
875  IntDrawScrollInterior(Wnd,Dc,SBType,Vertical,&ScrollBarInfo);
876  }
877  break;
878 
879  case WM_SYSTIMER:
880  Pt = PrevPt;
881  HitTest = IntScrollHitTest(&ScrollBarInfo, Vertical, Pt, FALSE);
882  break;
883 
884  default:
885  return; /* Should never happen */
886  }
887 
888  TRACE("Event: hwnd=%p bar=%d msg=%s pt=%d,%d hit=%d\n",
889  Wnd, SBType, SPY_GetMsgName(Msg,Wnd), Pt.x, Pt.y, HitTest );
890 
891  switch (ScrollTrackHitTest)
892  {
893  case SCROLL_NOWHERE: /* No tracking in progress */
894  break;
895 
896  case SCROLL_TOP_ARROW:
897  if (HitTest == ScrollTrackHitTest)
898  {
899  if ((WM_LBUTTONDOWN == Msg) || (WM_SYSTIMER == Msg))
900  {
901  SendMessageW(WndOwner, Vertical ? WM_VSCROLL : WM_HSCROLL,
902  SB_LINEUP, (LPARAM) WndCtl);
903  }
906  (TIMERPROC) NULL);
908  {
909  if (!(ScrollBarInfo.rgstate[ScrollTrackHitTest] &= STATE_SYSTEM_PRESSED))
910  {
911  IntUpdateScrollArrows (Wnd, Dc, &ScrollBarInfo, &NewInfo, SBType, ScrollTrackHitTest, Vertical, TRUE);
912  }
913  }
914  }
915  else
916  {
917  IntUpdateScrollArrows (Wnd, Dc, &ScrollBarInfo, &NewInfo, SBType, ScrollTrackHitTest, Vertical, FALSE);
919  }
920  break;
921 
922  case SCROLL_TOP_RECT:
923  if (HitTest == ScrollTrackHitTest)
924  {
925  if ((WM_LBUTTONDOWN == Msg) || (WM_SYSTIMER == Msg))
926  {
927  SendMessageW(WndOwner, Vertical ? WM_VSCROLL : WM_HSCROLL,
928  SB_PAGEUP, (LPARAM) WndCtl);
929  }
932  (TIMERPROC) NULL);
933  }
934  else
935  {
937  }
938  break;
939 
940  case SCROLL_THUMB:
941  if (Msg == WM_LBUTTONDOWN)
942  {
943  ScrollTrackingWin = Wnd;
944  ScrollTrackingBar = SBType;
945  ScrollTrackingPos = TrackThumbPos + LastMousePos - LastClickPos;
946  ScrollTrackingVal = IntScrollGetThumbVal(Wnd, SBType, &ScrollBarInfo,
947  Vertical, ScrollTrackingPos);
948  NewInfo.nTrackPos = ScrollTrackingVal;
949  NtUserSetScrollBarInfo(Wnd, IntScrollGetObjectId(SBType), &NewInfo);
950  IntScrollDrawMovingThumb(Dc, &ScrollBarInfo, Vertical);
951  }
952  else if (Msg == WM_LBUTTONUP)
953  {
954  ScrollTrackingWin = 0;
955  ScrollTrackingVal = 0;
956  IntDrawScrollInterior(Wnd, Dc, SBType, Vertical, &ScrollBarInfo);
957  }
958  else /* WM_MOUSEMOVE */
959  {
960  UINT Pos;
961 
962  if (! IntScrollPtInRectEx(&ScrollBarInfo.rcScrollBar, Pt, Vertical))
963  {
964  Pos = LastClickPos;
965  }
966  else
967  {
968  Pt = IntScrollClipPos(&ScrollBarInfo.rcScrollBar, Pt);
969  Pos = Vertical ? (Pt.y - ScrollBarInfo.rcScrollBar.top)
970  : (Pt.x - ScrollBarInfo.rcScrollBar.left);
971  }
972  if (Pos != LastMousePos || ! ScrollMovingThumb)
973  {
974  LastMousePos = Pos;
975  ScrollTrackingPos = TrackThumbPos + Pos - LastClickPos;
976  ScrollTrackingVal = IntScrollGetThumbVal(Wnd, SBType, &ScrollBarInfo,
977  Vertical, ScrollTrackingPos);
978  NewInfo.nTrackPos = ScrollTrackingVal;
979  NtUserSetScrollBarInfo(Wnd, IntScrollGetObjectId(SBType), &NewInfo);
980  IntScrollDrawMovingThumb(Dc, &ScrollBarInfo, Vertical);
981  SendMessageW(WndOwner, Vertical ? WM_VSCROLL : WM_HSCROLL,
983  (LPARAM) WndCtl);
984  }
985  }
986  break;
987 
988  case SCROLL_BOTTOM_RECT:
989  if (HitTest == ScrollTrackHitTest)
990  {
991  if ((Msg == WM_LBUTTONDOWN) || (Msg == WM_SYSTIMER))
992  {
993  SendMessageW(WndOwner, Vertical ? WM_VSCROLL : WM_HSCROLL,
994  SB_PAGEDOWN, (LPARAM) WndCtl);
995  }
998  (TIMERPROC) NULL);
999  }
1000  else
1001  {
1003  }
1004  break;
1005 
1006  case SCROLL_BOTTOM_ARROW:
1007  if (HitTest == ScrollTrackHitTest)
1008  {
1009  if ((Msg == WM_LBUTTONDOWN) || (Msg == WM_SYSTIMER))
1010  {
1011  SendMessageW(WndOwner, Vertical ? WM_VSCROLL : WM_HSCROLL,
1012  SB_LINEDOWN, (LPARAM) WndCtl);
1013  }
1016  (TIMERPROC) NULL);
1017  if (ScrollBarInfo.rgstate[ScrollTrackHitTest] != STATE_SYSTEM_UNAVAILABLE)
1018  {
1019  if (!(ScrollBarInfo.rgstate[ScrollTrackHitTest] &= STATE_SYSTEM_PRESSED))
1020  {
1021  TRACE("Set Arrow\n");
1022  IntUpdateScrollArrows (Wnd, Dc, &ScrollBarInfo, &NewInfo, SBType, ScrollTrackHitTest, Vertical, TRUE);
1023  }
1024  }
1025  }
1026  else
1027  {
1028  IntUpdateScrollArrows (Wnd, Dc, &ScrollBarInfo, &NewInfo, SBType, ScrollTrackHitTest, Vertical, FALSE);
1030  }
1031  break;
1032  }
1033 
1034  if (Msg == WM_LBUTTONDOWN)
1035  {
1036  if (SCROLL_THUMB == HitTest)
1037  {
1038  UINT Val = IntScrollGetThumbVal(Wnd, SBType, &ScrollBarInfo, Vertical,
1039  TrackThumbPos + LastMousePos - LastClickPos);
1040  SendMessageW(WndOwner, Vertical ? WM_VSCROLL : WM_HSCROLL,
1041  MAKEWPARAM(SB_THUMBTRACK, Val), (LPARAM) WndCtl);
1042  }
1043  }
1044 
1045  if (Msg == WM_LBUTTONUP)
1046  {
1047  HitTest = ScrollTrackHitTest;
1048  ScrollTrackHitTest = SCROLL_NOWHERE; /* Terminate tracking */
1049 
1050  if (SCROLL_THUMB == HitTest)
1051  {
1052  UINT Val = IntScrollGetThumbVal(Wnd, SBType, &ScrollBarInfo, Vertical,
1053  TrackThumbPos + LastMousePos - LastClickPos);
1054  SendMessageW(WndOwner, Vertical ? WM_VSCROLL : WM_HSCROLL,
1055  MAKEWPARAM(SB_THUMBPOSITION, Val), (LPARAM) WndCtl);
1056  }
1057  /* SB_ENDSCROLL doesn't report thumb position */
1058  SendMessageW(WndOwner, Vertical ? WM_VSCROLL : WM_HSCROLL,
1059  SB_ENDSCROLL, (LPARAM) WndCtl);
1060 
1061  /* Terminate tracking */
1062  ScrollTrackingWin = 0;
1063  }
1064 
1065  ReleaseDC(Wnd, Dc);
1066 }
1067 
1068 
1069 /***********************************************************************
1070  * IntScrollCreateScrollBar
1071  *
1072  * Create a scroll bar
1073  */
1075  HWND Wnd /* [in] Handle of window with scrollbar(s) */,
1076  LPCREATESTRUCTW lpCreate /* [in] The style and place of the scroll bar */)
1077 {
1078  SCROLLINFO Info;
1079 
1080  Info.cbSize = sizeof(SCROLLINFO);
1081  Info.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
1082  Info.nMin = 0;
1083  Info.nMax = 0;
1084  Info.nPage = 0;
1085  Info.nPos = 0;
1086  Info.nTrackPos = 0;
1088 
1089  TRACE("hwnd=%p lpCreate=%p\n", Wnd, lpCreate);
1090 
1091 #if 0 /* FIXME */
1092  if (lpCreate->style & WS_DISABLED)
1093  {
1094  // info->flags = ESB_DISABLE_BOTH;
1095  //NtUserEnableScrollBar(Wnd,SB_CTL,(wParam ? ESB_ENABLE_BOTH : ESB_DISABLE_BOTH));
1097  ERR("Created WS_DISABLED scrollbar\n");
1098  }
1099 #endif
1100  if (0 != (lpCreate->style & (SBS_SIZEGRIP | SBS_SIZEBOX)))
1101  {
1102  if (0 != (lpCreate->style & SBS_SIZEBOXTOPLEFTALIGN))
1103  {
1104  MoveWindow(Wnd, lpCreate->x, lpCreate->y, GetSystemMetrics(SM_CXVSCROLL) + 1,
1106  }
1107  else if (0 != (lpCreate->style & SBS_SIZEBOXBOTTOMRIGHTALIGN))
1108  {
1109  MoveWindow(Wnd, lpCreate->x + lpCreate->cx - GetSystemMetrics(SM_CXVSCROLL) - 1,
1110  lpCreate->y + lpCreate->cy - GetSystemMetrics(SM_CYHSCROLL) - 1,
1113  }
1114  }
1115  else if (0 != (lpCreate->style & SBS_VERT))
1116  {
1117  if (0 != (lpCreate->style & SBS_LEFTALIGN))
1118  {
1119  MoveWindow(Wnd, lpCreate->x, lpCreate->y,
1120  GetSystemMetrics(SM_CXVSCROLL) + 1, lpCreate->cy, FALSE);
1121  }
1122  else if (0 != (lpCreate->style & SBS_RIGHTALIGN))
1123  {
1124  MoveWindow(Wnd,
1125  lpCreate->x + lpCreate->cx - GetSystemMetrics(SM_CXVSCROLL) - 1,
1126  lpCreate->y,
1127  GetSystemMetrics(SM_CXVSCROLL) + 1, lpCreate->cy, FALSE);
1128  }
1129  }
1130  else /* SBS_HORZ */
1131  {
1132  if (0 != (lpCreate->style & SBS_TOPALIGN))
1133  {
1134  MoveWindow(Wnd, lpCreate->x, lpCreate->y,
1135  lpCreate->cx, GetSystemMetrics(SM_CYHSCROLL) + 1, FALSE);
1136  }
1137  else if (0 != (lpCreate->style & SBS_BOTTOMALIGN))
1138  {
1139  MoveWindow(Wnd,
1140  lpCreate->x,
1141  lpCreate->y + lpCreate->cy - GetSystemMetrics(SM_CYHSCROLL) - 1,
1142  lpCreate->cx, GetSystemMetrics(SM_CYHSCROLL) + 1, FALSE);
1143  }
1144  }
1145 }
1146 
1147 /* USER32 INTERNAL FUNCTIONS **************************************************/
1148 
1149 /***********************************************************************
1150  * ScrollTrackScrollBar
1151  *
1152  * Track a mouse button press on a scroll-bar.
1153  * pt is in screen-coordinates for non-client scroll bars.
1154  */
1155 VOID FASTCALL
1157 {
1158  MSG Msg;
1159  UINT XOffset = 0, YOffset = 0;
1160 
1161  if (SBType != SB_CTL)
1162  { // Used with CMD mouse tracking.
1163  PWND pwnd = ValidateHwnd(Wnd);
1164  if (!pwnd) return;
1165  XOffset = pwnd->rcClient.left - pwnd->rcWindow.left;
1166  YOffset = pwnd->rcClient.top - pwnd->rcWindow.top;
1167 // RECT rect;
1168 // WIN_GetRectangles( Wnd, COORDS_CLIENT, &rect, NULL );
1169  ScreenToClient(Wnd, &Pt);
1170 // Pt.x -= rect.left;
1171 // Pt.y -= rect.top;
1172  Pt.x += XOffset;
1173  Pt.y += YOffset;
1174  }
1175 
1176  IntScrollHandleScrollEvent(Wnd, SBType, WM_LBUTTONDOWN, Pt);
1177 
1178  do
1179  {
1180  if (!GetMessageW(&Msg, 0, 0, 0)) break;
1181  if (CallMsgFilterW(&Msg, MSGF_SCROLLBAR)) continue;
1182  if ( Msg.message == WM_LBUTTONUP ||
1183  Msg.message == WM_MOUSEMOVE ||
1184  (Msg.message == WM_SYSTIMER && Msg.wParam == SCROLL_TIMER))
1185  {
1186  Pt.x = LOWORD(Msg.lParam) + XOffset;
1187  Pt.y = HIWORD(Msg.lParam) + YOffset;
1188  IntScrollHandleScrollEvent(Wnd, SBType, Msg.message, Pt);
1189  }
1190  else
1191  {
1194  }
1195  if (!IsWindow(Wnd))
1196  {
1197  ReleaseCapture();
1198  break;
1199  }
1200  } while (Msg.message != WM_LBUTTONUP && GetCapture() == Wnd);
1201 }
1202 
1203 
1204 static DWORD FASTCALL
1206 {
1207  DWORD Ret = NtUserSetScrollInfo(Wnd, SB_CTL, Info, bRedraw);
1208  if (Ret) IntNotifyWinEvent(EVENT_OBJECT_VALUECHANGE, Wnd, OBJID_CLIENT, CHILDID_SELF, WEF_SETBYWNDPTI);
1209  return Ret;
1210 }
1211 
1212 
1213 /***********************************************************************
1214  * ScrollBarWndProc
1215  */
1218 {
1219 #ifdef __REACTOS__ // Do this now, remove after Server side is fixed.
1220  PWND pWnd;
1221  PSBWND pSBWnd;
1222  SCROLLINFO ScrollInfo;
1223 
1224  pWnd = ValidateHwnd(Wnd);
1225  if (pWnd)
1226  {
1227  if (!pWnd->fnid)
1228  {
1229  TRACE("ScrollBar CTL size %d\n", (sizeof(SBWND)-sizeof(WND)));
1230  if ( pWnd->cbwndExtra < (sizeof(SBWND)-sizeof(WND)) )
1231  {
1232  ERR("Wrong Extra bytes for Scrollbar!\n");
1233  return 0;
1234  }
1235 
1236  if (Msg != WM_CREATE)
1237  {
1238  return DefWindowProc(Wnd, Msg, wParam, lParam);
1239  }
1241  }
1242  else
1243  {
1244  if (pWnd->fnid != FNID_SCROLLBAR)
1245  {
1246  ERR("Wrong window class for Scrollbar!\n");
1247  return 0;
1248  }
1249  }
1250  }
1251 #endif
1252 
1253  if (! IsWindow(Wnd))
1254  {
1255  return 0;
1256  }
1257 
1258  // Must be a scroll bar control!
1259  pSBWnd = (PSBWND)pWnd;
1260 
1261  switch (Msg)
1262  {
1263  case WM_CREATE:
1265  break;
1266 
1267  case WM_ENABLE:
1268  {
1270  }
1271 
1272  case WM_LBUTTONDBLCLK:
1273  case WM_LBUTTONDOWN:
1274  if (GetWindowLongW( Wnd, GWL_STYLE ) & SBS_SIZEGRIP)
1275  {
1279  }
1280  else
1281  {
1282  POINT Pt;
1283  Pt.x = (short)LOWORD(lParam);
1284  Pt.y = (short)HIWORD(lParam);
1285  ScrollTrackScrollBar(Wnd, SB_CTL, Pt);
1286  }
1287  break;
1288 
1289  case WM_LBUTTONUP:
1290  case WM_MOUSEMOVE:
1291  case WM_SYSTIMER:
1292  {
1293  POINT Pt;
1294  Pt.x = (short)LOWORD(lParam);
1295  Pt.y = (short)HIWORD(lParam);
1297  }
1298  break;
1299 
1300  case WM_KEYDOWN:
1302  break;
1303 
1304  case WM_KEYUP:
1305  ShowCaret(Wnd);
1306  break;
1307 
1308  case WM_SETFOCUS:
1309  {
1310  /* Create a caret when a ScrollBar get focus */
1311  RECT Rect;
1312  int ArrowSize, ThumbSize, ThumbPos, Vertical;
1313 
1314  Vertical = IntScrollGetScrollBarRect(Wnd, SB_CTL, &Rect,
1315  &ArrowSize, &ThumbSize, &ThumbPos);
1316  if (! Vertical)
1317  {
1318  CreateCaret(Wnd, (HBITMAP) 1, ThumbSize - 2, Rect.bottom - Rect.top - 2);
1319  SetCaretPos(ThumbPos + 1, Rect.top + 1);
1320  }
1321  else
1322  {
1323  CreateCaret(Wnd, (HBITMAP) 1, Rect.right - Rect.left - 2, ThumbSize - 2);
1324  SetCaretPos(Rect.top + 1, ThumbPos + 1);
1325  }
1326  ShowCaret(Wnd);
1327  }
1328  break;
1329 
1330  case WM_KILLFOCUS:
1331  {
1332  RECT Rect;
1333  int ArrowSize, ThumbSize, ThumbPos, Vertical;
1334 
1335  Vertical = IntScrollGetScrollBarRect(Wnd, SB_CTL, &Rect,
1336  &ArrowSize, &ThumbSize, &ThumbPos);
1337  if (! Vertical)
1338  {
1339  Rect.left = ThumbPos + 1;
1340  Rect.right = Rect.left + ThumbSize;
1341  }
1342  else
1343  {
1344  Rect.top = ThumbPos + 1;
1345  Rect.bottom = Rect.top + ThumbSize;
1346  }
1347  HideCaret(Wnd);
1348  InvalidateRect(Wnd, &Rect, FALSE);
1349  DestroyCaret();
1350  }
1351  break;
1352 
1353  case WM_ERASEBKGND:
1354  return 1;
1355 
1356  case WM_GETDLGCODE:
1357  return DLGC_WANTARROWS; /* Windows returns this value */
1358 
1359  case WM_PAINT:
1360  {
1361  PAINTSTRUCT Ps;
1362  HDC Dc;
1363 
1364  Dc = (0 != wParam ? (HDC) wParam : BeginPaint(Wnd, &Ps));
1365 
1367  {
1368  IntScrollDrawSizeGrip(Wnd, Dc);
1369  }
1370  else if (0 != (GetWindowLongPtrW(Wnd, GWL_STYLE) & SBS_SIZEBOX))
1371  {
1372  RECT Rect;
1373  GetClientRect(Wnd, &Rect);
1375  }
1376  else
1377  {
1378  IntDrawScrollBar(Wnd, Dc, SB_CTL/*, TRUE, TRUE*/);
1379  }
1380 
1381  if (0 == wParam)
1382  {
1383  EndPaint(Wnd, &Ps);
1384  }
1385  }
1386  break;
1387 
1388  case SBM_GETPOS:
1389  return pSBWnd->SBCalc.pos;
1390 
1391  case SBM_GETRANGE:
1392  *(LPINT)wParam = pSBWnd->SBCalc.posMin;
1393  *(LPINT)lParam = pSBWnd->SBCalc.posMax;
1394  // This message does not return a value.
1395  return 0;
1396 
1397  case SBM_ENABLE_ARROWS:
1398  return EnableScrollBar( Wnd, SB_CTL, wParam );
1399 
1400  case SBM_SETPOS:
1401  {
1402  ScrollInfo.cbSize = sizeof(SCROLLINFO);
1403  ScrollInfo.fMask = SIF_POS|SIF_PREVIOUSPOS;
1404  ScrollInfo.nPos = wParam;
1405  return IntSetScrollInfo(Wnd, &ScrollInfo, lParam);
1406  }
1407 
1408  case SBM_SETRANGEREDRAW:
1409  case SBM_SETRANGE:
1410  {
1411  ScrollInfo.cbSize = sizeof(SCROLLINFO);
1412  ScrollInfo.fMask = SIF_RANGE|SIF_PREVIOUSPOS;
1413  ScrollInfo.nMin = wParam;
1414  ScrollInfo.nMax = lParam;
1415  return IntSetScrollInfo(Wnd, &ScrollInfo, Msg == SBM_SETRANGEREDRAW ? TRUE : FALSE);
1416  }
1417 
1418  case SBM_SETSCROLLINFO:
1420 
1421  case SBM_GETSCROLLINFO:
1422  {
1423  PSBDATA pSBData = (PSBDATA)&pSBWnd->SBCalc;
1424  DWORD ret = NtUserSBGetParms(Wnd, SB_CTL, pSBData, (SCROLLINFO *) lParam);
1425  if (!ret)
1426  {
1427  ERR("SBM_GETSCROLLINFO No ScrollInfo\n");
1428  }
1429  return ret;
1430  }
1431  case SBM_GETSCROLLBARINFO:
1432  ((PSCROLLBARINFO)lParam)->cbSize = sizeof(SCROLLBARINFO);
1434 
1435  case 0x00e5:
1436  case 0x00e7:
1437  case 0x00e8:
1438  case 0x00ec:
1439  case 0x00ed:
1440  case 0x00ee:
1441  case 0x00ef:
1442  WARN("unknown Win32 msg %04x wp=%08lx lp=%08lx\n",
1443  Msg, wParam, lParam );
1444  break;
1445 
1446  default:
1447  if (WM_USER <= Msg)
1448  {
1449  WARN("unknown msg %04x wp=%04lx lp=%08lx\n", Msg, wParam, lParam);
1450  }
1451  if (unicode)
1452  return DefWindowProcW( Wnd, Msg, wParam, lParam );
1453  else
1454  return DefWindowProcA( Wnd, Msg, wParam, lParam );
1455  }
1456 
1457  return 0;
1458 }
1459 
1462 {
1464 }
1465 
1468 {
1470 }
1471 
1472 
1473 /* PUBLIC FUNCTIONS ***********************************************************/
1474 
1475 /*
1476  * @implemented
1477  */
1478 BOOL
1479 WINAPI
1482 {
1483  BOOL Hook, Ret = FALSE;
1484 
1485  LoadUserApiHook();
1486 
1487  Hook = BeginIfHookedUserApiHook();
1488 
1489  /* Bypass SEH and go direct. */
1490  if (!Hook)
1491  {
1492  Ret = NtUserEnableScrollBar(hwnd, nBar, flags);
1493  if (!Ret) return Ret;
1495  return Ret;
1496  }
1497  _SEH2_TRY
1498  {
1499  Ret = guah.EnableScrollBar(hwnd, nBar, flags);
1500  }
1502  {
1503  ERR("Got exception in hooked EnableScrollBar!\n");
1504  }
1505  _SEH2_END;
1506 
1507  EndUserApiHook();
1508 
1509  return Ret;
1510 }
1511 
1512 BOOL WINAPI
1514 {
1515  PWND pWnd;
1516  PSBDATA pSBData;
1517 
1518  if (SB_CTL == SBType)
1519  {
1520  return SendMessageW(Wnd, SBM_GETSCROLLINFO, 0, (LPARAM) Info);
1521  }
1522 
1523  pWnd = ValidateHwnd(Wnd);
1524  if (!pWnd) return FALSE;
1525 
1526  if (SBType < SB_HORZ || SBType > SB_VERT)
1527  {
1529  return FALSE;
1530  }
1531  if (!pWnd->pSBInfo)
1532  {
1534  return FALSE;
1535  }
1536  pSBData = IntGetSBData(pWnd, SBType);
1537  return NtUserSBGetParms(Wnd, SBType, pSBData, Info);
1538 }
1539 
1540 /*
1541  * @implemented
1542  */
1544 {
1545  BOOL Ret;
1546  PWND pWnd = ValidateHwnd(hwnd);
1547  TRACE("hwnd=%p idObject=%d info=%p\n", hwnd, idObject, info);
1548  if (!pWnd) return FALSE;
1549  Ret = NtUserGetScrollBarInfo(hwnd, idObject, info); // This will be fixed once SB is server side.
1550  /* rcScrollBar needs to be in screen coordinates */
1551  OffsetRect( &(info->rcScrollBar), pWnd->rcWindow.left, pWnd->rcWindow.top );
1552  return Ret;
1553 }
1554 
1555 /*
1556  * @implemented
1557  */
1558 BOOL
1559 WINAPI
1562 {
1563  BOOL Hook, Ret = FALSE;
1564 
1565  LoadUserApiHook();
1566 
1567  Hook = BeginIfHookedUserApiHook();
1568 
1569  /* Bypass SEH and go direct. */
1570  if (!Hook) return RealGetScrollInfo(Wnd, SBType, Info);
1571 
1572  _SEH2_TRY
1573  {
1574  Ret = guah.GetScrollInfo(Wnd, SBType, Info);
1575  }
1577  {
1578  ERR("Got exception in hooked GetScrollInfo!\n");
1579  }
1580  _SEH2_END;
1581 
1582  EndUserApiHook();
1583 
1584  return Ret;
1585 }
1586 
1587 /*
1588  * @implemented
1589  */
1590 INT
1591 WINAPI
1594 {
1595  PWND pwnd;
1596  PSBDATA pSBData;
1597 
1598  TRACE("Wnd=%p Bar=%d\n", Wnd, Bar);
1599 
1600  /* Refer SB_CTL requests to the window */
1601  if (SB_CTL == Bar)
1602  {
1603  return SendMessageW(Wnd, SBM_GETPOS, (WPARAM) 0, (LPARAM) 0);
1604  }
1605  else if (Bar == SB_HORZ || Bar == SB_VERT )
1606  {
1607  pwnd = ValidateHwnd(Wnd);
1608  if (!pwnd) return 0;
1609 
1610  if (pwnd->pSBInfo)
1611  {
1612  pSBData = IntGetSBData(pwnd, Bar);
1613  return pSBData->pos;
1614  }
1615 
1617  TRACE("GetScrollPos No Scroll Info\n");
1618  return 0;
1619  }
1621  return 0;
1622 }
1623 
1624 /*
1625  * @implemented
1626  */
1627 BOOL
1628 WINAPI
1630 GetScrollRange(HWND Wnd, int Bar, LPINT MinPos, LPINT MaxPos)
1631 {
1632  PWND pwnd;
1633  PSBDATA pSBData;
1634 
1635  TRACE("Wnd=%x Bar=%d Min=%p Max=%p\n", Wnd, Bar, MinPos, MaxPos);
1636 
1637  /* Refer SB_CTL requests to the window */
1638  if (SB_CTL == Bar)
1639  {
1640  return SendMessageW(Wnd, SBM_GETRANGE, (WPARAM) MinPos, (LPARAM) MaxPos);
1641  }
1642  else if (Bar == SB_HORZ || Bar == SB_VERT )
1643  {
1644  pwnd = ValidateHwnd(Wnd);
1645  if (!pwnd) return FALSE;
1646 
1647  if (pwnd->pSBInfo)
1648  {
1649  pSBData = IntGetSBData(pwnd, Bar);
1650  *MinPos = pSBData->posMin;
1651  *MaxPos = pSBData->posMax;
1652  }
1653  else
1654  {
1656  *MinPos = 0;
1657  *MaxPos = 0;
1658  }
1659  return TRUE;
1660  }
1662  return FALSE;
1663 }
1664 
1665 INT WINAPI
1666 RealSetScrollInfo(HWND Wnd, int SBType, LPCSCROLLINFO Info, BOOL bRedraw)
1667 {
1668  if (SB_CTL == SBType)
1669  {
1670  return SendMessageW(Wnd, SBM_SETSCROLLINFO, (WPARAM) bRedraw, (LPARAM) Info);
1671  }
1672  else
1673  {
1674  return NtUserSetScrollInfo(Wnd, SBType, Info, bRedraw);
1675  }
1676 }
1677 
1678 /*
1679  * @implemented
1680  */
1681 INT
1682 WINAPI
1684 SetScrollInfo(HWND Wnd, int SBType, LPCSCROLLINFO Info, BOOL bRedraw)
1685 {
1686  BOOL Hook;
1687  INT Ret = 0;
1688 
1689  LoadUserApiHook();
1690 
1691  Hook = BeginIfHookedUserApiHook();
1692 
1693  /* Bypass SEH and go direct. */
1694  if (!Hook) return RealSetScrollInfo(Wnd, SBType, Info, bRedraw);
1695 
1696  _SEH2_TRY
1697  {
1698  Ret = guah.SetScrollInfo(Wnd, SBType, Info, bRedraw);
1699  }
1701  {
1702  ERR("Got exception in hooked SetScrollInfo!\n");
1703  }
1704  _SEH2_END;
1705 
1706  EndUserApiHook();
1707 
1708  return Ret;
1709 
1710 }
1711 
1712 /*
1713  * @implemented
1714  */
1715 INT
1716 WINAPI
1718 SetScrollPos(HWND hWnd, INT nBar, INT nPos, BOOL bRedraw)
1719 {
1720  SCROLLINFO ScrollInfo;
1721 
1722  ScrollInfo.cbSize = sizeof(SCROLLINFO);
1723  ScrollInfo.fMask = SIF_POS|SIF_PREVIOUSPOS;
1724  ScrollInfo.nPos = nPos;
1725 
1726  return RealSetScrollInfo(hWnd, nBar, &ScrollInfo, bRedraw);
1727 }
1728 
1729 /*
1730  * @implemented
1731  */
1732 BOOL
1733 WINAPI
1735 SetScrollRange(HWND hWnd, INT nBar, INT nMinPos, INT nMaxPos, BOOL bRedraw)
1736 {
1737  PWND pWnd;
1738  SCROLLINFO ScrollInfo;
1739 
1740  pWnd = ValidateHwnd(hWnd);
1741  if ( !pWnd ) return FALSE;
1742 
1743  if (((LONGLONG)nMaxPos - nMinPos) > MAXLONG)
1744  {
1746  return FALSE;
1747  }
1748 
1749  ScrollInfo.cbSize = sizeof(SCROLLINFO);
1750  ScrollInfo.fMask = SIF_RANGE;
1751  ScrollInfo.nMin = nMinPos;
1752  ScrollInfo.nMax = nMaxPos;
1753  SetScrollInfo(hWnd, nBar, &ScrollInfo, bRedraw); // do not bypass themes.
1754  return TRUE;
1755 }
struct @1608 Msg[]
#define SBS_SIZEBOXTOPLEFTALIGN
Definition: winuser.h:331
static INT ScrollTrackingPos
Definition: scrollbar.c:59
PSBDATA FASTCALL IntGetSBData(PWND pwnd, INT Bar)
Definition: scrollbar.c:83
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
static BOOL FASTCALL IntGetScrollBarInfo(HWND Wnd, INT Bar, PSCROLLBARINFO ScrollBarInfo)
Definition: scrollbar.c:314
INT WINAPI DECLSPEC_HOTPATCH SetScrollPos(HWND hWnd, INT nBar, INT nPos, BOOL bRedraw)
Definition: scrollbar.c:1718
#define WS_DISABLED
Definition: pedump.c:621
static void SCROLL_RefreshScrollBar(HWND hwnd, INT nBar, BOOL arrows, BOOL interior)
Definition: scrollbar.c:691
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
#define DFCS_FLAT
Definition: winuser.h:510
#define SB_PAGEDOWN
Definition: winuser.h:569
BOOL FASTCALL EndUserApiHook(VOID)
Definition: usrapihk.c:164
#define BF_MIDDLE
Definition: winuser.h:468
const struct builtin_class_descr SCROLL_builtin_class
Definition: scrollbar.c:76
#define WMSZ_BOTTOMRIGHT
Definition: winuser.h:2446
HDC WINAPI GetDCEx(_In_opt_ HWND, _In_opt_ HRGN, _In_ DWORD)
#define SB_PAGEUP
Definition: winuser.h:568
#define max(a, b)
Definition: svc.c:63
BOOL WINAPI TranslateMessage(_In_ const MSG *)
DWORD ExStyle
Definition: ntuser.h:668
#define STATE_SYSTEM_UNAVAILABLE
Definition: winuser.h:2837
static LONG FASTCALL IntScrollGetObjectId(INT SBType)
Definition: scrollbar.c:304
#define SM_CYHSCROLL
Definition: winuser.h:952
#define TRUE
Definition: types.h:120
#define MAKEWPARAM(l, h)
Definition: winuser.h:3984
#define SCROLL_ARROW_THUMB_OVERLAP
Definition: scrollbar.c:54
static BOOL FASTCALL IntScrollPtInRectEx(LPRECT Rect, POINT Pt, BOOL Vertical)
Definition: scrollbar.c:411
#define SIF_RANGE
Definition: winuser.h:1221
long y
Definition: polytest.cpp:48
#define SBS_SIZEBOX
Definition: winuser.h:329
#define WM_GETDLGCODE
Definition: winuser.h:1671
#define WM_LBUTTONDOWN
Definition: winuser.h:1758
#define SCROLL_MIN_RECT
Definition: scrollbar.c:48
BOOL WINAPI OffsetRect(_Inout_ LPRECT, _In_ int, _In_ int)
static POINT IntScrollClipPos(PRECT lpRect, POINT pt)
Definition: scrollbar.c:651
BOOL WINAPI IsWindow(_In_opt_ HWND)
#define WM_SYSTIMER
Definition: comctl32.h:112
#define MAXLONG
Definition: umtypes.h:116
#define SB_CTL
Definition: winuser.h:554
long x
Definition: polytest.cpp:48
#define ESB_DISABLE_BOTH
Definition: winuser.h:556
#define SB_VERT
Definition: winuser.h:553
#define pt(x, y)
Definition: drawing.c:79
INT page
Definition: ntuser.h:475
SBDATA Vert
Definition: ntuser.h:483
static void IntScrollCreateScrollBar(HWND Wnd, LPCREATESTRUCTW lpCreate)
Definition: scrollbar.c:1074
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1827
#define SB_HORZ
Definition: winuser.h:552
VOID FASTCALL IntNotifyWinEvent(DWORD Event, PWND pWnd, LONG idObject, LONG idChild, DWORD flags)
Definition: event.c:179
#define WARN(fmt,...)
Definition: debug.h:112
static DWORD ScrollTrackHitTest
Definition: scrollbar.c:62
USERAPIHOOK guah
Definition: usrapihk.c:344
static HDC
Definition: imagelist.c:92
#define DFCS_INACTIVE
Definition: winuser.h:502
ush Pos
Definition: deflate.h:92
HWND hWnd
Definition: settings.c:17
#define CCHILDREN_SCROLLBAR
Definition: winuser.h:3720
LONG top
Definition: windef.h:307
#define WS_EX_LAYOUTRTL
Definition: winuser.h:390
static DWORD FASTCALL IntScrollHitTest(PSCROLLBARINFO ScrollBarInfo, BOOL Vertical, POINT Pt, BOOL Dragging)
Definition: scrollbar.c:439
#define CTLCOLOR_SCROLLBAR
Definition: winuser.h:946
INT pos
Definition: ntuser.h:476
PSBINFO pSBInfo
Definition: ntuser.h:690
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1497
#define CS_HREDRAW
Definition: winuser.h:648
#define GWL_EXSTYLE
Definition: winuser.h:845
#define SBM_SETRANGE
Definition: winuser.h:2063
HWND WINAPI SetFocus(_In_opt_ HWND)
static INT ScrollTrackingBar
Definition: scrollbar.c:58
struct _SBWND SBWND
static void FASTCALL IntScrollDrawSizeGrip(HWND Wnd, HDC Dc)
Definition: scrollbar.c:674
#define SCROLL_BOTTOM_ARROW
Definition: scrollbar.c:39
BOOL WINAPI DrawFrameControl(_In_ HDC, _Inout_ LPRECT, _In_ UINT, _In_ UINT)
UINT_PTR WPARAM
Definition: windef.h:207
#define ERROR_INVALID_SCROLLBAR_RANGE
Definition: winerror.h:929
#define VK_DOWN
Definition: winuser.h:2202
BOOL WINAPI DECLSPEC_HOTPATCH EnableScrollBar(HWND hwnd, UINT nBar, UINT flags)
Definition: scrollbar.c:1481
#define VK_PRIOR
Definition: winuser.h:2195
RECT rcClient
Definition: ntuser.h:681
#define GetWindowLongPtrW
Definition: winuser.h:4804
LONG left
Definition: windef.h:306
static BOOL ScrollTrackVertical
Definition: scrollbar.c:63
BOOL WINAPI EndPaint(_In_ HWND, _In_ const PAINTSTRUCT *)
static BOOL ScrollMovingThumb
Definition: scrollbar.c:66
INT WSBflags
Definition: ntuser.h:481
LONG right
Definition: windef.h:308
#define WS_EX_LEFTSCROLLBAR
Definition: winuser.h:392
#define FASTCALL
Definition: nt_native.h:50
int32_t INT
Definition: typedefs.h:57
#define SIF_PAGE
Definition: winuser.h:1219
LRESULT WINAPI ScrollBarWndProcW(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: scrollbar.c:1461
WPARAM wParam
Definition: combotst.c:138
VOID(CALLBACK * TIMERPROC)(HWND, UINT, UINT_PTR, DWORD)
Definition: winuser.h:2872
struct TraceInfo Info
#define WM_ENABLE
Definition: winuser.h:1597
LRESULT WINAPI DefWindowProcW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define DCX_WINDOW
Definition: winuser.h:2095
#define VK_NEXT
Definition: winuser.h:2196
SBCALC SBCalc
Definition: ntuser.h:738
const char * SPY_GetMsgName(UINT msg, HWND hWnd)
Definition: spy.c:2218
_SEH2_TRY
Definition: create.c:4250
struct tagSCROLLBARINFO * PSCROLLBARINFO
DWORD APIENTRY NtUserSetScrollInfo(HWND hWnd, int fnBar, LPCSCROLLINFO lpsi, BOOL bRedraw)
Definition: scrollbar.c:1396
BOOL WINAPI PatBlt(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int, _In_ DWORD)
#define SBM_GETPOS
Definition: winuser.h:2060
#define BF_RECT
Definition: winuser.h:462
unsigned short(__cdecl typeof(TIFFCurrentDirectory))(struct tiff *)
Definition: typeof.h:94
ULONG cbwndExtra
Definition: ntuser.h:702
#define DFCS_PUSHED
Definition: winuser.h:503
BOOL APIENTRY NtUserGetScrollBarInfo(HWND hWnd, LONG idObject, PSCROLLBARINFO psbi)
Definition: scrollbar.c:1201
BOOL WINAPI CallMsgFilterW(_In_ LPMSG, _In_ INT)
#define VK_HOME
Definition: winuser.h:2198
BOOL WINAPI KillSystemTimer(HWND, UINT_PTR)
Definition: timer.c:35
static __inline PVOID DesktopPtrToUser(PVOID Ptr)
Definition: user_x.h:12
#define VK_UP
Definition: winuser.h:2200
LRESULT WINAPI DispatchMessageW(_In_ const MSG *)
DWORD fnid
Definition: ntuser.h:673
BOOL WINAPI HideCaret(_In_opt_ HWND)
unsigned int BOOL
Definition: ntddk_ex.h:94
static VOID FASTCALL IntUpdateScrollArrows(HWND Wnd, HDC hDC, PSCROLLBARINFO ScrollBarInfo, SETSCROLLBARINFO *info, INT SBType, INT Arrow, BOOL Vertical, BOOL Pressed)
Definition: scrollbar.c:322
#define SBS_BOTTOMALIGN
Definition: winuser.h:325
long LONG
Definition: pedump.c:60
ENABLESCROLLBAR EnableScrollBar
Definition: undocuser.h:336
BOOL WINAPI CreateCaret(_In_ HWND, _In_opt_ HBITMAP, _In_ int, _In_ int)
#define COLOR_SCROLLBAR
Definition: winuser.h:902
HDC WINAPI BeginPaint(_In_ HWND, _Out_ LPPAINTSTRUCT)
#define SCROLL_MIN_THUMB
Definition: scrollbar.c:51
BOOL WINAPI DrawEdge(_In_ HDC, _Inout_ LPRECT, _In_ UINT, _In_ UINT)
void IntDrawScrollBar(PWND Wnd, HDC DC, INT Bar)
Definition: scrollbar.c:1102
#define Max(a, b)
Definition: cdprocs.h:70
HWND WINAPI GetCapture(void)
Definition: message.c:2880
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
#define WM_CTLCOLORSCROLLBAR
Definition: winuser.h:1753
DWORD rgstate[CCHILDREN_SCROLLBAR+1]
Definition: ntuser.h:3584
#define STATE_SYSTEM_PRESSED
Definition: winuser.h:2840
#define CHILDID_SELF
Definition: winable.h:14
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
BOOL WINAPI IsRectEmpty(_In_ LPCRECT)
LONG WINAPI GetWindowLongW(_In_ HWND, _In_ int)
smooth NULL
Definition: ftsmooth.c:416
INT WINAPI DECLSPEC_HOTPATCH SetScrollInfo(HWND Wnd, int SBType, LPCSCROLLINFO Info, BOOL bRedraw)
Definition: scrollbar.c:1684
#define SB_THUMBPOSITION
Definition: winuser.h:572
#define WM_KEYDOWN
Definition: winuser.h:1697
LONG_PTR LPARAM
Definition: windef.h:208
BOOL APIENTRY NtUserSBGetParms(HWND hWnd, int fnBar, PSBDATA pSBData, LPSCROLLINFO lpsi)
Definition: scrollbar.c:1247
#define SBM_ENABLE_ARROWS
Definition: winuser.h:2059
#define SBS_LEFTALIGN
Definition: winuser.h:327
INT WINAPI RealSetScrollInfo(HWND Wnd, int SBType, LPCSCROLLINFO Info, BOOL bRedraw)
Definition: scrollbar.c:1666
#define WEF_SETBYWNDPTI
Definition: ntuser.h:213
INT posMax
Definition: ntuser.h:489
#define SB_ENDSCROLL
Definition: winuser.h:574
#define DFCS_SCROLLDOWN
Definition: winuser.h:490
#define SBS_VERT
Definition: winuser.h:334
BOOL WINAPI DECLSPEC_HOTPATCH SetScrollRange(HWND hWnd, INT nBar, INT nMinPos, INT nMaxPos, BOOL bRedraw)
Definition: scrollbar.c:1735
GETSCROLLINFO GetScrollInfo
Definition: undocuser.h:334
#define DefWindowProc
Definition: ros2win.h:31
VOID FASTCALL ScrollTrackScrollBar(HWND Wnd, INT SBType, POINT Pt)
Definition: scrollbar.c:1156
#define SCROLL_BOTTOM_RECT
Definition: scrollbar.c:38
#define DECLSPEC_HOTPATCH
Definition: _mingw.h:242
struct tagSCROLLINFO SCROLLINFO
DWORD rgstate[CCHILDREN_SCROLLBAR+1]
Definition: winuser.h:3729
#define CS_VREDRAW
Definition: winuser.h:653
int64_t LONGLONG
Definition: typedefs.h:67
struct tagSBDATA * PSBDATA
UINT_PTR WINAPI SetSystemTimer(HWND, UINT_PTR, UINT, TIMERPROC)
Definition: ntwrapper.h:106
#define SBS_SIZEGRIP
Definition: winuser.h:332
#define OBJID_CLIENT
Definition: winable.h:19
#define TRACE(s)
Definition: solgame.cpp:4
Definition: polytest.cpp:40
BOOL WINAPI DECLSPEC_HOTPATCH GetScrollRange(HWND Wnd, int Bar, LPINT MinPos, LPINT MaxPos)
Definition: scrollbar.c:1630
#define WM_KILLFOCUS
Definition: winuser.h:1596
#define OBJID_HSCROLL
Definition: winable.h:21
BOOL WINAPI DECLSPEC_HOTPATCH GetScrollInfo(HWND Wnd, INT SBType, LPSCROLLINFO Info)
Definition: scrollbar.c:1561
INT posMin
Definition: ntuser.h:488
BOOL APIENTRY NtUserSetScrollBarInfo(HWND hWnd, LONG idObject, SETSCROLLBARINFO *info)
Definition: scrollbar.c:1472
#define PFD_DOUBLEBUFFER_DONTCARE
Definition: wingdi.h:315
#define SCROLL_FIRST_DELAY
Definition: scrollbar.c:41
#define SB_THUMBTRACK
Definition: winuser.h:573
#define DFCS_SCROLLSIZEGRIP
Definition: winuser.h:494
#define SBS_SIZEBOXBOTTOMRIGHTALIGN
Definition: winuser.h:330
static void mirror_rect(const RECT *window_rect, RECT *rect)
Definition: scrollbar.c:74
static HWND ScrollTrackingWin
Definition: scrollbar.c:57
#define SBS_TOPALIGN
Definition: winuser.h:333
static DWORD FASTCALL IntSetScrollInfo(HWND Wnd, LPCSCROLLINFO Info, BOOL bRedraw)
Definition: scrollbar.c:1205
#define WINAPI
Definition: msvc.h:6
#define ERROR_NO_SCROLLBARS
Definition: winerror.h:928
#define WM_KEYUP
Definition: winuser.h:1698
BOOL WINAPI InvalidateRect(_In_opt_ HWND, _In_opt_ LPCRECT, _In_ BOOL)
#define SCROLL_TOP_ARROW
Definition: scrollbar.c:35
int WINAPI GetSystemMetrics(_In_ int)
unsigned long DWORD
Definition: ntddk_ex.h:95
#define DFCS_SCROLLRIGHT
Definition: winuser.h:492
#define DFCS_SCROLLUP
Definition: winuser.h:489
#define SetLastError(x)
Definition: compat.h:418
#define _Inout_
Definition: no_sal2.h:244
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
HBRUSH DefWndControlColor(HDC hDC, UINT ctlType)
Definition: defwnd.c:33
#define SCROLL_TOP_RECT
Definition: scrollbar.c:36
static void IntDrawScrollInterior(HWND hWnd, HDC hDC, INT nBar, BOOL Vertical, PSCROLLBARINFO ScrollBarInfo)
Definition: scrollbar.c:117
#define OBJID_VSCROLL
Definition: winable.h:20
LRESULT WINAPI ScrollBarWndProc_common(WNDPROC DefWindowProc, HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam, BOOL unicode)
Definition: scrollbar.c:1217
#define WS_HSCROLL
Definition: pedump.c:628
GLbitfield flags
Definition: glext.h:7161
#define WM_PAINT
Definition: winuser.h:1602
int ret
static const WCHAR L[]
Definition: oid.c:1250
PWND FASTCALL ValidateHwnd(HWND hwnd)
Definition: misc.c:369
HDC hdc
Definition: main.c:9
#define SBM_GETRANGE
Definition: winuser.h:2061
INT pos
Definition: ntuser.h:491
static INT ScrollTrackingVal
Definition: scrollbar.c:60
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define WM_LBUTTONDBLCLK
Definition: winuser.h:1760
INT posMin
Definition: ntuser.h:473
WINE_DEFAULT_DEBUG_CHANNEL(scrollbar)
RECT rcWindow
Definition: ntuser.h:680
#define CS_DBLCLKS
Definition: winuser.h:646
#define WS_TABSTOP
Definition: pedump.c:634
LRESULT WINAPI DefWindowProcA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
BOOL NTAPI NtUserMessageCall(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, ULONG_PTR ResultInfo, DWORD dwType, BOOL Ansi)
Definition: message.c:2486
struct _SBWND * PSBWND
BOOL WINAPI MoveWindow(_In_ HWND, _In_ int, _In_ int, _In_ int, _In_ int, _In_ BOOL)
#define WM_USER
Definition: winuser.h:1877
Definition: ntuser.h:733
#define PATCOPY
Definition: wingdi.h:334
#define SIF_POS
Definition: winuser.h:1220
#define EDGE_RAISED
Definition: winuser.h:450
LRESULT(CALLBACK * WNDPROC)(HWND, UINT, WPARAM, LPARAM)
Definition: winuser.h:2881
#define ERR(fmt,...)
Definition: debug.h:110
#define _In_
Definition: no_sal2.h:204
#define GWL_STYLE
Definition: winuser.h:846
Definition: ntuser.h:657
SBDATA Horz
Definition: ntuser.h:482
static HDC hDC
Definition: 3dtext.c:33
BOOL WINAPI GetScrollBarInfo(_In_ HWND hwnd, _In_ LONG idObject, _Inout_ LPSCROLLBARINFO info)
Definition: scrollbar.c:1543
BOOL WINAPI GetClientRect(_In_ HWND, _Out_ LPRECT)
#define SIF_PREVIOUSPOS
Definition: undocuser.h:87
#define DCX_CACHE
Definition: winuser.h:2096
HWND WINAPI GetParent(_In_ HWND)
HWND WINAPI SetCapture(_In_ HWND hWnd)
#define SB_TOP
Definition: winuser.h:578
_SEH2_END
Definition: create.c:4424
#define WS_BORDER
Definition: pedump.c:625
#define SCROLL_THUMB
Definition: scrollbar.c:37
#define BLACKNESS
Definition: wingdi.h:322
BOOL WINAPI RealGetScrollInfo(HWND Wnd, INT SBType, LPSCROLLINFO Info)
Definition: scrollbar.c:1513
#define MSGF_SCROLLBAR
Definition: winuser.h:1164
#define FNID_SCROLLBAR
Definition: ntuser.h:821
#define SBS_RIGHTALIGN
Definition: winuser.h:328
BOOL WINAPI DestroyCaret(void)
Definition: caret.c:35
#define SC_SIZE
Definition: winuser.h:2559
static __inline void LoadUserApiHook()
Definition: user_x.h:85
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define WM_LBUTTONUP
Definition: winuser.h:1759
struct tagSCROLLBARINFO SCROLLBARINFO
BOOL FASTCALL BeginIfHookedUserApiHook(VOID)
Definition: usrapihk.c:106
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 SB_BOTTOM
Definition: winuser.h:577
#define WS_VSCROLL
Definition: pedump.c:627
static UINT FASTCALL IntScrollGetThumbVal(HWND Wnd, INT SBType, PSCROLLBARINFO ScrollBarInfo, BOOL Vertical, INT Pos)
Definition: scrollbar.c:608
#define SM_CXVSCROLL
Definition: winuser.h:951
BOOL WINAPI GetMessageW(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT)
#define DFC_SCROLL
Definition: winuser.h:475
static BOOL FASTCALL IntScrollGetScrollBarRect(HWND Wnd, INT Bar, RECT *Rect, INT *ArrowSize, INT *ThumbSize, INT *ThumbPos)
Definition: scrollbar.c:485
BOOL WINAPI PtInRect(_In_ LPCRECT, _In_ POINT)
HWND WINAPI GetFocus(void)
Definition: window.c:1909
#define IDC_ARROW
Definition: winuser.h:682
BOOL WINAPI ReleaseCapture(void)
Definition: message.c:2889
LRESULT WINAPI ScrollBarWndProcA(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: scrollbar.c:1467
#define WM_CREATE
Definition: winuser.h:1590
INT WINAPI DECLSPEC_HOTPATCH GetScrollPos(HWND Wnd, INT Bar)
Definition: scrollbar.c:1593
static VOID FASTCALL IntScrollHandleScrollEvent(HWND Wnd, INT SBType, UINT Msg, POINT Pt)
Definition: scrollbar.c:764
#define HIWORD(l)
Definition: typedefs.h:246
static VOID FASTCALL IntScrollDrawMovingThumb(HDC Dc, PSCROLLBARINFO ScrollBarInfo, BOOL Vertical)
Definition: scrollbar.c:275
LONG bottom
Definition: windef.h:309
BOOL NTAPI NtUserSetWindowFNID(HWND hWnd, WORD fnID)
Definition: window.c:4057
#define SCROLL_REPEAT_DELAY
Definition: scrollbar.c:43
BOOL WINAPI ShowCaret(_In_opt_ HWND)
static HBITMAP
Definition: button.c:44
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
BOOL APIENTRY NtUserEnableScrollBar(HWND hWnd, UINT wSBflags, UINT wArrows)
Definition: scrollbar.c:1311
#define WM_ERASEBKGND
Definition: winuser.h:1607
#define WM_SETFOCUS
Definition: winuser.h:1595
#define DFCS_SCROLLLEFT
Definition: winuser.h:491
BOOL WINAPI ScreenToClient(_In_ HWND, _Inout_ LPPOINT)
LONG_PTR LRESULT
Definition: windef.h:209
static void FASTCALL IntScrollHandleKbdEvent(HWND Wnd, WPARAM wParam, LPARAM lParam)
Definition: scrollbar.c:709
#define SBM_SETPOS
Definition: winuser.h:2062
int WINAPI FillRect(HDC, LPCRECT, HBRUSH)
HBRUSH WINAPI GetSysColorBrush(_In_ int)
HBRUSH FASTCALL GetControlBrush(PWND pwnd, HDC hdc, UINT ctlType)
Definition: misc.c:171
#define WM_SYSCOMMAND
Definition: winuser.h:1723
LPARAM lParam
Definition: combotst.c:139
#define LOWORD(l)
Definition: pedump.c:82
BOOL WINAPI SetCaretPos(_In_ int, _In_ int)
#define VK_END
Definition: winuser.h:2197
static VOID FASTCALL IntDrawScrollArrows(HDC hDC, PSCROLLBARINFO ScrollBarInfo, BOOL Vertical)
Definition: scrollbar.c:232
#define MulDiv(x, y, z)
Definition: gdifloat.h:86
#define DLGC_WANTARROWS
Definition: winuser.h:2585
#define ESB_ENABLE_BOTH
Definition: winuser.h:563
#define CS_PARENTDC
Definition: winuser.h:651
#define WMSZ_BOTTOMLEFT
Definition: winuser.h:2445
struct Rect Rect
SETSCROLLINFO SetScrollInfo
Definition: undocuser.h:335
INT posMax
Definition: ntuser.h:474
#define WM_VSCROLL
Definition: winuser.h:1726
#define SBM_SETRANGEREDRAW
Definition: winuser.h:2064
#define SCROLL_NOWHERE
Definition: scrollbar.c:34
int * LPINT
Definition: windef.h:178
DWORD style
Definition: ntuser.h:670
#define SCROLL_TIMER
Definition: scrollbar.c:45