ReactOS  0.4.15-dev-489-g75a0787
scrollbar.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS kernel
4  * PURPOSE: Scrollbars
5  * FILE: win32ss/user/ntuser/scrollbar.c
6  * PROGRAMER: Thomas Weidenmueller (w3seek@users.sourceforge.net)
7  * Jason Filby (jasonfilby@yahoo.com)
8  */
9 
10 #include <win32k.h>
11 DBG_DEFAULT_CHANNEL(UserScrollbar);
12 
13 /* Definitions for scrollbar hit testing [See SCROLLBARINFO in MSDN] */
14 #define SCROLL_NOWHERE 0x00 /* Outside the scroll bar */
15 #define SCROLL_TOP_ARROW 0x01 /* Top or left arrow */
16 #define SCROLL_TOP_RECT 0x02 /* Rectangle between the top arrow and the thumb */
17 #define SCROLL_THUMB 0x03 /* Thumb rectangle */
18 #define SCROLL_BOTTOM_RECT 0x04 /* Rectangle between the thumb and the bottom arrow */
19 #define SCROLL_BOTTOM_ARROW 0x05 /* Bottom or right arrow */
20 
21 #define SCROLL_FIRST_DELAY 200 /* Delay (in ms) before first repetition when
22  holding the button down */
23 #define SCROLL_REPEAT_DELAY 50 /* Delay (in ms) between scroll repetitions */
24 
25 #define SCROLL_TIMER 0 /* Scroll timer id */
26 
27  /* Minimum size of the rectangle between the arrows */
28 #define SCROLL_MIN_RECT 4
29 
30  /* Minimum size of the thumb in pixels */
31 #define SCROLL_MIN_THUMB 6
32 
33  /* Overlap between arrows and thumb */
34 #define SCROLL_ARROW_THUMB_OVERLAP 0
35 
36 //
37 //
38 //
39 #define MINTRACKTHUMB 8 /* Minimum size of the rectangle between the arrows */
40 
41  /* What to do after SetScrollInfo() */
42  #define SA_SSI_HIDE 0x0001
43  #define SA_SSI_SHOW 0x0002
44  #define SA_SSI_REFRESH 0x0004
45  #define SA_SSI_REPAINT_ARROWS 0x0008
46 
47 #define SBRG_SCROLLBAR 0 /* The scrollbar itself */
48 #define SBRG_TOPRIGHTBTN 1 /* The top or right button */
49 #define SBRG_PAGEUPRIGHT 2 /* The page up or page right region */
50 #define SBRG_SCROLLBOX 3 /* The scroll box */
51 #define SBRG_PAGEDOWNLEFT 4 /* The page down or page left region */
52 #define SBRG_BOTTOMLEFTBTN 5 /* The bottom or left button */
53 
54 #define CHANGERGSTATE(item, status) \
55  if(Info->rgstate[(item)] != (status)) \
56  Chg = TRUE; \
57  Info->rgstate[(item)] = (status);
58 
59 /* FUNCTIONS *****************************************************************/
60 
63 
64 static void
66 
67 
68 /* Ported from WINE20020904 */
69 /* Compute the scroll bar rectangle, in drawing coordinates (i.e. client coords for SB_CTL, window coords for SB_VERT and
70  * SB_HORZ). 'arrowSize' returns the width or height of an arrow (depending on * the orientation of the scrollbar),
71  * 'thumbSize' returns the size of the thumb, and 'thumbPos' returns the position of the thumb relative to the left or to
72  * the top. Return TRUE if the scrollbar is vertical, FALSE if horizontal.
73  */
74 static inline void mirror_rect( const RECT *window_rect, RECT *rect )
75 {
76  int width = window_rect->right - window_rect->left;
77  int tmp = rect->left;
78  rect->left = width - rect->right;
79  rect->right = width - tmp;
80 }
81 
83 IntGetSBData(PWND pwnd, INT Bar)
84 {
85  PSBWND pSBWnd;
86  PSBINFO pSBInfo;
87 
88  pSBInfo = pwnd->pSBInfo;
89  switch (Bar)
90  {
91  case SB_HORZ:
92  return &pSBInfo->Horz;
93  case SB_VERT:
94  return &pSBInfo->Vert;
95  case SB_CTL:
96  if ( pwnd->cbwndExtra < (sizeof(SBWND)-sizeof(WND)) )
97  {
98  ERR("IntGetSBData Wrong Extra bytes for CTL Scrollbar!\n");
99  return 0;
100  }
101  pSBWnd = (PSBWND)pwnd;
102  return (PSBDATA)&pSBWnd->SBCalc;
103  default:
104  ERR("IntGetSBData Bad Bar!\n");
105  }
106  return NULL;
107 }
108 
110 IntGetScrollBarRect (PWND Wnd, INT nBar, RECTL *lprect)
111 {
112  BOOL vertical;
113  *lprect = Wnd->rcClient;
114 
115  RECTL_vOffsetRect( lprect, -Wnd->rcWindow.left, -Wnd->rcWindow.top );
116  if (Wnd->ExStyle & WS_EX_LAYOUTRTL)
117  mirror_rect( &Wnd->rcWindow, lprect );
118 
119  switch (nBar)
120  {
121  case SB_HORZ:
122  lprect->top = lprect->bottom;
124  if (Wnd->style & WS_BORDER)
125  {
126  lprect->left--;
127  lprect->right++;
128  }
129  else if (Wnd->style & WS_VSCROLL)
130  {
131  lprect->right++;
132  }
133  vertical = FALSE;
134  break;
135 
136  case SB_VERT:
137  if(Wnd->ExStyle & WS_EX_LEFTSCROLLBAR)
138  {
139  lprect->right = lprect->left;
141  }
142  else
143  {
144  lprect->left = lprect->right;
146  }
147  if (Wnd->style & WS_BORDER)
148  {
149  lprect->top--;
150  lprect->bottom++;
151  }
152  else if (Wnd->style & WS_HSCROLL)
153  {
154  lprect->bottom++;
155  }
156  vertical = TRUE;
157  break;
158 
159  case SB_CTL:
160  IntGetClientRect (Wnd, lprect);
161  vertical = !!(Wnd->style & SBS_VERT);
162  break;
163 
164  default:
165  return FALSE;
166  }
167 
168  return vertical;
169 }
170 
172 IntCalculateThumb(PWND Wnd, LONG idObject, PSCROLLBARINFO psbi, PSBDATA pSBData)
173 {
174  INT Thumb, ThumbBox, ThumbPos, cxy, mx;
175  RECTL ClientRect;
176 
177  switch(idObject)
178  {
179  case SB_HORZ:
181  cxy = psbi->rcScrollBar.right - psbi->rcScrollBar.left;
182  break;
183  case SB_VERT:
185  cxy = psbi->rcScrollBar.bottom - psbi->rcScrollBar.top;
186  break;
187  case SB_CTL:
188  IntGetClientRect(Wnd, &ClientRect);
189  if(Wnd->style & SBS_VERT)
190  {
192  cxy = ClientRect.bottom - ClientRect.top;
193  }
194  else
195  {
197  cxy = ClientRect.right - ClientRect.left;
198  }
199  break;
200  default:
201  return FALSE;
202  }
203 
204  ThumbPos = Thumb;
205  /* Calculate Thumb */
206  if(cxy <= (2 * Thumb))
207  {
208  Thumb = cxy / 2;
209  psbi->xyThumbTop = 0;
210  psbi->xyThumbBottom = 0;
211  ThumbPos = Thumb;
212  }
215  pSBData->posMin >= (int)(pSBData->posMax - max(pSBData->page - 1, 0)))
216  {
217  /* Nothing to scroll */
218  psbi->xyThumbTop = 0;
219  psbi->xyThumbBottom = 0;
220  }
221  else
222  {
223  ThumbBox = pSBData->page ? MINTRACKTHUMB : UserGetSystemMetrics(SM_CXHTHUMB);
224  cxy -= (2 * Thumb);
225  if(cxy >= ThumbBox)
226  {
227  if(pSBData->page)
228  {
229  ThumbBox = max(EngMulDiv(cxy, pSBData->page, pSBData->posMax - pSBData->posMin + 1), ThumbBox);
230  }
231 
232  if(cxy > ThumbBox)
233  {
234  mx = pSBData->posMax - max(pSBData->page - 1, 0);
235  if(pSBData->posMin < mx)
236  ThumbPos = Thumb + EngMulDiv(cxy - ThumbBox, pSBData->pos - pSBData->posMin, mx - pSBData->posMin);
237  else
238  ThumbPos = Thumb + ThumbBox;
239  }
240 
241  psbi->xyThumbTop = ThumbPos;
242  psbi->xyThumbBottom = ThumbPos + ThumbBox;
243  }
244  else
245  {
246  psbi->xyThumbTop = 0;
247  psbi->xyThumbBottom = 0;
248  }
249  }
250  psbi->dxyLineButton = Thumb;
251 
252  return TRUE;
253 }
254 /*
255 static VOID FASTCALL
256 IntUpdateSBInfo(PWND Window, int wBar)
257 {
258  PSCROLLBARINFO sbi;
259  PSBDATA pSBData;
260 
261  ASSERT(Window);
262  ASSERT(Window->pSBInfo);
263  ASSERT(Window->pSBInfoex);
264 
265  sbi = IntGetScrollbarInfoFromWindow(Window, wBar);
266  pSBData = IntGetSBData(Window, wBar);
267  IntGetScrollBarRect(Window, wBar, &(sbi->rcScrollBar));
268  IntCalculateThumb(Window, wBar, sbi, pSBData);
269 }
270 */
271 static BOOL FASTCALL
273 {
274  UINT Mask;
275  LPSCROLLINFO psi;
276 
278 
279  if(!SBID_IS_VALID(nBar))
280  {
282  ERR("Trying to get scrollinfo for unknown scrollbar type %d\n", nBar);
283  return FALSE;
284  }
285 
286  if (!Window->pSBInfo)
287  {
288  ERR("IntGetScrollInfo No window scrollbar info!\n");
289  return FALSE;
290  }
291 
292  psi = IntGetScrollInfoFromWindow(Window, nBar);
293 
294  if (lpsi->fMask == SIF_ALL)
295  {
296  Mask = SIF_PAGE | SIF_POS | SIF_RANGE | SIF_TRACKPOS;
297  }
298  else
299  {
300  Mask = lpsi->fMask;
301  }
302 
303  if (0 != (Mask & SIF_PAGE))
304  {
305  lpsi->nPage = psi->nPage;
306  }
307 
308  if (0 != (Mask & SIF_POS))
309  {
310  lpsi->nPos = psi->nPos;
311  }
312 
313  if (0 != (Mask & SIF_RANGE))
314  {
315  lpsi->nMin = psi->nMin;
316  lpsi->nMax = psi->nMax;
317  }
318 
319  if (0 != (Mask & SIF_TRACKPOS))
320  {
321  lpsi->nTrackPos = psi->nTrackPos;
322  }
323 
324  return TRUE;
325 }
326 
329  PWND pWnd,
330  INT nBar,
331  PSBDATA pSBData,
332  LPSCROLLINFO lpsi)
333 {
334  UINT Mask;
335  PSBTRACK pSBTrack = pWnd->head.pti->pSBTrack;
336 
337  if (!SBID_IS_VALID(nBar))
338  {
340  ERR("Trying to get scrollinfo for unknown scrollbar type %d\n", nBar);
341  return FALSE;
342  }
343 
344  if (!pWnd->pSBInfo || !pSBTrack) return FALSE;
345 
346  Mask = lpsi->fMask;
347 
348  if (0 != (Mask & SIF_PAGE))
349  {
350  lpsi->nPage = pSBData->page;
351  }
352 
353  if (0 != (Mask & SIF_POS))
354  {
355  lpsi->nPos = pSBData->pos;
356  }
357 
358  if (0 != (Mask & SIF_RANGE))
359  {
360  lpsi->nMin = pSBData->posMin;
361  lpsi->nMax = pSBData->posMax;
362  }
363 
364  if (0 != (Mask & SIF_TRACKPOS))
365  {
366  if ( pSBTrack &&
367  pSBTrack->nBar == nBar &&
368  pSBTrack->spwndTrack == pWnd )
369  lpsi->nTrackPos = pSBTrack->posNew;
370  else
371  lpsi->nTrackPos = pSBData->pos;
372  }
373  return (Mask & SIF_ALL) !=0;
374 }
375 
376 /*************************************************************************
377  * SCROLL_GetScrollBarInfo
378  *
379  * Internal helper for the API function
380  *
381  * PARAMS
382  * hwnd [I] Handle of window with scrollbar(s)
383  * idObject [I] One of OBJID_CLIENT, OBJID_HSCROLL, or OBJID_VSCROLL
384  * info [IO] cbSize specifies the size of the structure
385  *
386  * RETURNS
387  * FALSE if failed
388  */
389 #if 0
390 static BOOL SCROLL_GetScrollBarInfo(HWND hwnd, LONG idObject, LPSCROLLBARINFO info)
391 {
392  LPSCROLLBAR_INFO infoPtr;
393  INT nBar;
394  INT nDummy;
396  BOOL pressed;
397  RECT rect;
398 
399  switch (idObject)
400  {
401  case OBJID_CLIENT: nBar = SB_CTL; break;
402  case OBJID_HSCROLL: nBar = SB_HORZ; break;
403  case OBJID_VSCROLL: nBar = SB_VERT; break;
404  default: return FALSE;
405  }
406 
407  /* handle invalid data structure */
408  if (info->cbSize != sizeof(*info))
409  return FALSE;
410 
411  SCROLL_GetScrollBarRect(hwnd, nBar, &info->rcScrollBar, &nDummy,
412  &info->dxyLineButton, &info->xyThumbTop);
413  /* rcScrollBar needs to be in screen coordinates */
415  OffsetRect(&info->rcScrollBar, rect.left, rect.top);
416 
417  info->xyThumbBottom = info->xyThumbTop + info->dxyLineButton;
418 
419  infoPtr = SCROLL_GetInternalInfo(hwnd, nBar, TRUE);
420  if (!infoPtr)
421  return FALSE;
422 
423  /* Scroll bar state */
424  info->rgstate[0] = 0;
425  if ((nBar == SB_HORZ && !(style & WS_HSCROLL))
426  || (nBar == SB_VERT && !(style & WS_VSCROLL)))
427  info->rgstate[0] |= STATE_SYSTEM_INVISIBLE;
428  if (infoPtr->minVal >= infoPtr->maxVal - max(infoPtr->page - 1, 0))
429  {
430  if (!(info->rgstate[0] & STATE_SYSTEM_INVISIBLE))
431  info->rgstate[0] |= STATE_SYSTEM_UNAVAILABLE;
432  else
433  info->rgstate[0] |= STATE_SYSTEM_OFFSCREEN;
434  }
435  if (nBar == SB_CTL && !IsWindowEnabled(hwnd))
436  info->rgstate[0] |= STATE_SYSTEM_UNAVAILABLE;
437 
438  pressed = ((nBar == SB_VERT) == SCROLL_trackVertical && GetCapture() == hwnd);
439 
440  /* Top/left arrow button state. MSDN says top/right, but I don't believe it */
441  info->rgstate[1] = 0;
442  if (pressed && SCROLL_trackHitTest == SCROLL_TOP_ARROW)
443  info->rgstate[1] |= STATE_SYSTEM_PRESSED;
444  if (infoPtr->flags & ESB_DISABLE_LTUP)
445  info->rgstate[1] |= STATE_SYSTEM_UNAVAILABLE;
446 
447  /* Page up/left region state. MSDN says up/right, but I don't believe it */
448  info->rgstate[2] = 0;
449  if (infoPtr->curVal == infoPtr->minVal)
450  info->rgstate[2] |= STATE_SYSTEM_INVISIBLE;
451  if (pressed && SCROLL_trackHitTest == SCROLL_TOP_RECT)
452  info->rgstate[2] |= STATE_SYSTEM_PRESSED;
453 
454  /* Thumb state */
455  info->rgstate[3] = 0;
456  if (pressed && SCROLL_trackHitTest == SCROLL_THUMB)
457  info->rgstate[3] |= STATE_SYSTEM_PRESSED;
458 
459  /* Page down/right region state. MSDN says down/left, but I don't believe it */
460  info->rgstate[4] = 0;
461  if (infoPtr->curVal >= infoPtr->maxVal - 1)
462  info->rgstate[4] |= STATE_SYSTEM_INVISIBLE;
463  if (pressed && SCROLL_trackHitTest == SCROLL_BOTTOM_RECT)
464  info->rgstate[4] |= STATE_SYSTEM_PRESSED;
465 
466  /* Bottom/right arrow button state. MSDN says bottom/left, but I don't believe it */
467  info->rgstate[5] = 0;
468  if (pressed && SCROLL_trackHitTest == SCROLL_BOTTOM_ARROW)
469  info->rgstate[5] |= STATE_SYSTEM_PRESSED;
470  if (infoPtr->flags & ESB_DISABLE_RTDN)
471  info->rgstate[5] |= STATE_SYSTEM_UNAVAILABLE;
472 
473  return TRUE;
474 }
475 #endif
476 static DWORD FASTCALL
478 {
479  /*
480  * Update the scrollbar state and set action flags according to
481  * what has to be done graphics wise.
482  */
483 
485  PSCROLLBARINFO psbi;
486  UINT new_flags;
487  INT action = 0;
488  PSBDATA pSBData;
489  DWORD OldPos = 0;
490  BOOL bChangeParams = FALSE; /* Don't show/hide scrollbar if params don't change */
491  UINT MaxPage;
492  int MaxPos;
493 
495 
496  if(!SBID_IS_VALID(nBar))
497  {
499  ERR("Trying to set scrollinfo for unknown scrollbar type %d", nBar);
500  return FALSE;
501  }
502 
504  {
505  return FALSE;
506  }
507 
508  if (lpsi->cbSize != sizeof(SCROLLINFO) &&
509  lpsi->cbSize != (sizeof(SCROLLINFO) - sizeof(lpsi->nTrackPos)))
510  {
512  return 0;
513  }
515  {
517  return 0;
518  }
519 
522  pSBData = IntGetSBData(Window, nBar);
523 
524  /* Set the page size */
525  if (lpsi->fMask & SIF_PAGE)
526  {
527  if (Info->nPage != lpsi->nPage)
528  {
529  Info->nPage = lpsi->nPage;
530  pSBData->page = lpsi->nPage;
531  bChangeParams = TRUE;
532  }
533  }
534 
535  /* Set the scroll pos */
536  if (lpsi->fMask & SIF_POS)
537  {
538  if (Info->nPos != lpsi->nPos)
539  {
540  OldPos = Info->nPos;
541  Info->nPos = lpsi->nPos;
542  pSBData->pos = lpsi->nPos;
543  }
544  }
545 
546  /* Set the scroll range */
547  if (lpsi->fMask & SIF_RANGE)
548  {
549  if (lpsi->nMin > lpsi->nMax)
550  {
551  Info->nMin = lpsi->nMin;
552  Info->nMax = lpsi->nMin;
553  pSBData->posMin = lpsi->nMin;
554  pSBData->posMax = lpsi->nMin;
555  bChangeParams = TRUE;
556  }
557  else if (Info->nMin != lpsi->nMin || Info->nMax != lpsi->nMax)
558  {
559  Info->nMin = lpsi->nMin;
560  Info->nMax = lpsi->nMax;
561  pSBData->posMin = lpsi->nMin;
562  pSBData->posMax = lpsi->nMax;
563  bChangeParams = TRUE;
564  }
565  }
566 
567  /* Make sure the page size is valid */
568  MaxPage = abs(Info->nMax - Info->nMin) + 1;
569  if (Info->nPage > MaxPage)
570  {
571  pSBData->page = Info->nPage = MaxPage;
572  }
573 
574  /* Make sure the pos is inside the range */
575  MaxPos = Info->nMax + 1 - (int)max(Info->nPage, 1);
576  ASSERT(MaxPos >= Info->nMin);
577  if (Info->nPos < Info->nMin)
578  {
579  pSBData->pos = Info->nPos = Info->nMin;
580  }
581  else if (Info->nPos > MaxPos)
582  {
583  pSBData->pos = Info->nPos = MaxPos;
584  }
585 
586  /*
587  * Don't change the scrollbar state if SetScrollInfo is just called
588  * with SIF_DISABLENOSCROLL
589  */
590  if (!(lpsi->fMask & SIF_ALL))
591  {
592  //goto done;
593  return lpsi->fMask & SIF_PREVIOUSPOS ? OldPos : pSBData->pos;
594  }
595 
596  /* Check if the scrollbar should be hidden or disabled */
597  if (lpsi->fMask & (SIF_RANGE | SIF_PAGE | SIF_DISABLENOSCROLL))
598  {
599  new_flags = Window->pSBInfo->WSBflags;
600  if (Info->nMin >= (int)(Info->nMax - max(Info->nPage - 1, 0)))
601  {
602  /* Hide or disable scroll-bar */
603  if (lpsi->fMask & SIF_DISABLENOSCROLL)
604  {
605  new_flags = ESB_DISABLE_BOTH;
606  bChangeParams = TRUE;
607  }
608  else if ((nBar != SB_CTL) && bChangeParams)
609  {
611  }
612  }
613  else /* Show and enable scroll-bar only if no page only changed. */
614  if (lpsi->fMask != SIF_PAGE)
615  {
616  if ((nBar != SB_CTL) && bChangeParams)
617  {
618  new_flags = ESB_ENABLE_BOTH;
619  action |= SA_SSI_SHOW;
620  }
621  else if (nBar == SB_CTL)
622  {
623  new_flags = ESB_ENABLE_BOTH;
624  }
625  }
626 
627  if (Window->pSBInfo->WSBflags != new_flags) /* Check arrow flags */
628  {
629  Window->pSBInfo->WSBflags = new_flags;
631  }
632  }
633 
634 //done:
635  if ( action & SA_SSI_HIDE )
636  {
638  }
639  else
640  {
641  if ( action & SA_SSI_SHOW )
642  if ( co_UserShowScrollBar(Window, nBar, TRUE, TRUE) )
643  return lpsi->fMask & SIF_PREVIOUSPOS ? OldPos : pSBData->pos; /* SetWindowPos() already did the painting */
644  if (bRedraw)
645  {
647  { // Redraw the entire bar.
648  RECTL UpdateRect = psbi->rcScrollBar;
649  UpdateRect.left -= Window->rcClient.left - Window->rcWindow.left;
650  UpdateRect.right -= Window->rcClient.left - Window->rcWindow.left;
651  UpdateRect.top -= Window->rcClient.top - Window->rcWindow.top;
652  UpdateRect.bottom -= Window->rcClient.top - Window->rcWindow.top;
654  }
655  else
656  {
657  // Redraw only the interior part of the bar.
658  IntRefeshScrollInterior(Window, nBar, psbi);
659  }
660  } // FIXME: Arrows
661 /* else if( action & SA_SSI_REPAINT_ARROWS )
662  {
663  RECTL UpdateRect = psbi->rcScrollBar;
664  UpdateRect.left -= Window->rcClient.left - Window->rcWindow.left;
665  UpdateRect.right -= Window->rcClient.left - Window->rcWindow.left;
666  UpdateRect.top -= Window->rcClient.top - Window->rcWindow.top;
667  UpdateRect.bottom -= Window->rcClient.top - Window->rcWindow.top;
668  co_UserRedrawWindow(Window, &UpdateRect, 0, RDW_INVALIDATE | RDW_FRAME);
669  }
670 */ }
671 
672  if (bChangeParams && (nBar == SB_HORZ || nBar == SB_VERT) && (lpsi->fMask & SIF_DISABLENOSCROLL))
673  {
674  IntEnableScrollBar(nBar == SB_HORZ, psbi, Window->pSBInfo->WSBflags);
675  }
676 
677  /* Return current position */
678  return lpsi->fMask & SIF_PREVIOUSPOS ? OldPos : pSBData->pos;
679 }
680 
683 {
684  INT Bar;
685  PSCROLLBARINFO sbi;
686  PSBDATA pSBData;
688 
689  Bar = SBOBJ_TO_SBID(idObject);
690 
691  if(!SBID_IS_VALID(Bar))
692  {
694  ERR("Trying to get scrollinfo for unknown scrollbar type %d\n", Bar);
695  return FALSE;
696  }
697 
699  {
700  ERR("Failed to create scrollbars for window.\n");
701  return FALSE;
702  }
703 
705  pSBData = IntGetSBData(Window, Bar);
706 
707  IntGetScrollBarRect(Window, Bar, &(sbi->rcScrollBar));
708  IntCalculateThumb(Window, Bar, sbi, pSBData);
709 
710  /* Scroll bar state */
711  psbi->rgstate[0] = 0;
712  if ((Bar == SB_HORZ && !(Window->style & WS_HSCROLL))
713  || (Bar == SB_VERT && !(Window->style & WS_VSCROLL)))
714  psbi->rgstate[0] |= STATE_SYSTEM_INVISIBLE;
715  if (pSBData->posMin >= pSBData->posMax - max(pSBData->page - 1, 0))
716  {
717  if (!(psbi->rgstate[0] & STATE_SYSTEM_INVISIBLE))
718  psbi->rgstate[0] |= STATE_SYSTEM_UNAVAILABLE;
719  else
720  psbi->rgstate[0] |= STATE_SYSTEM_OFFSCREEN;
721  }
722  if (Bar == SB_CTL && !(Window->style & WS_DISABLED))
723  psbi->rgstate[0] |= STATE_SYSTEM_UNAVAILABLE;
724 
725  RtlCopyMemory(psbi, sbi, sizeof(SCROLLBARINFO));
726 
727  return TRUE;
728 }
729 
732 {
733  INT Bar;
734  PSCROLLBARINFO sbi;
735  LPSCROLLINFO psi;
737 
738  Bar = SBOBJ_TO_SBID(idObject);
739 
740  if(!SBID_IS_VALID(Bar))
741  {
743  ERR("Trying to get scrollinfo for unknown scrollbar type %d\n", Bar);
744  return FALSE;
745  }
746 
748  {
749  ERR("Failed to create scrollbars for window.\n");
750  return FALSE;
751  }
752 
755 
756  psi->nTrackPos = psbi->nTrackPos;
757  sbi->reserved = psbi->reserved;
758  RtlCopyMemory(&sbi->rgstate, &psbi->rgstate, sizeof(psbi->rgstate));
759 
760  return TRUE;
761 }
762 
765 {
766  PSCROLLBARINFO psbi;
767  PSBDATA pSBData;
768  ULONG Size, s;
769  INT i;
770 
772 
773  if (Window->pSBInfo && Window->pSBInfoex)
774  {
775  /* No need to create it anymore */
776  return TRUE;
777  }
778 
779  /* Allocate memory for all scrollbars (HORZ, VERT, CONTROL) */
780  Size = 3 * (sizeof(SBINFOEX));
782  {
783  ERR("Unable to allocate memory for scrollbar information for window %p\n", Window->head.h);
784  return FALSE;
785  }
786 
787  RtlZeroMemory(Window->pSBInfoex, Size);
788 
789  if(!(Window->pSBInfo = DesktopHeapAlloc( Window->head.rpdesk, sizeof(SBINFO))))
790  {
791  ERR("Unable to allocate memory for scrollbar information for window %p\n", Window->head.h);
792  return FALSE;
793  }
794 
795  RtlZeroMemory(Window->pSBInfo, sizeof(SBINFO));
796  Window->pSBInfo->Vert.posMax = 100;
797  Window->pSBInfo->Horz.posMax = 100;
798 
800  &Window->rcWindow,
801  &Window->rcClient);
802 
803  for(s = SB_HORZ; s <= SB_VERT; s++)
804  {
806  psbi->cbSize = sizeof(SCROLLBARINFO);
807  for (i = 0; i < CCHILDREN_SCROLLBAR + 1; i++)
808  psbi->rgstate[i] = 0;
809 
810  pSBData = IntGetSBData(Window, s);
811 
813  IntCalculateThumb(Window, s, psbi, pSBData);
814  }
815 
816  return TRUE;
817 }
818 
821 {
822  if (Window->pSBInfo && Window->pSBInfoex)
823  {
824  DesktopHeapFree(Window->head.rpdesk, Window->pSBInfo);
825  Window->pSBInfo = NULL;
827  Window->pSBInfoex = NULL;
828  return TRUE;
829  }
830  return FALSE;
831 }
832 
835 {
836  BOOL Chg = FALSE;
837  switch(wArrows)
838  {
839  case ESB_DISABLE_BOTH:
842  break;
843  case ESB_DISABLE_RTDN:
844  if(Horz)
845  {
847  }
848  else
849  {
851  }
852  break;
853  case ESB_DISABLE_LTUP:
854  if(Horz)
855  {
857  }
858  else
859  {
861  }
862  break;
863  case ESB_ENABLE_BOTH:
866  break;
867  }
868  return Chg;
869 }
870 
871 /* Ported from WINE20020904 (SCROLL_ShowScrollBar) */
873 co_UserShowScrollBar(PWND Wnd, int nBar, BOOL fShowH, BOOL fShowV)
874 {
875  ULONG old_style, set_bits = 0, clear_bits = 0;
876 
877  ASSERT_REFS_CO(Wnd);
878 
879  switch(nBar)
880  {
881  case SB_CTL:
882  {
883  //IntUpdateSBInfo(Wnd, SB_CTL); // Is this needed? Was tested w/o!
884 
885  co_WinPosShowWindow(Wnd, fShowH ? SW_SHOW : SW_HIDE);
886  return TRUE;
887  }
888  case SB_BOTH:
889  case SB_HORZ:
890  if (fShowH) set_bits |= WS_HSCROLL;
891  else clear_bits |= WS_HSCROLL;
892  if( nBar == SB_HORZ ) break;
893  /* Fall through */
894  case SB_VERT:
895  if (fShowV) set_bits |= WS_VSCROLL;
896  else clear_bits |= WS_VSCROLL;
897  break;
898  default:
900  return FALSE; /* Nothing to do! */
901  }
902 
903  old_style = IntSetStyle( Wnd, set_bits, clear_bits );
904  if ((old_style & clear_bits) != 0 || (old_style & set_bits) != set_bits)
905  {
907  //if (Wnd->style & WS_HSCROLL) IntUpdateSBInfo(Wnd, SB_HORZ);
908  //if (Wnd->style & WS_VSCROLL) IntUpdateSBInfo(Wnd, SB_VERT);
910  /* Frame has been changed, let the window redraw itself */
911  co_WinPosSetWindowPos( Wnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE
913  return TRUE;
914  }
915  return FALSE; /* no frame changes */
916 }
917 
918 static void
919 IntDrawScrollInterior(PWND pWnd, HDC hDC, INT nBar, BOOL Vertical, PSCROLLBARINFO ScrollBarInfo)
920 {
921  INT ThumbSize = ScrollBarInfo->xyThumbBottom - ScrollBarInfo->xyThumbTop;
922  INT ThumbTop = ScrollBarInfo->xyThumbTop;
923  RECT Rect;
924  HBRUSH hSaveBrush, hBrush;
925  BOOL TopSelected = FALSE, BottomSelected = FALSE;
926 
927  if (ScrollBarInfo->rgstate[SCROLL_TOP_RECT] & STATE_SYSTEM_PRESSED)
928  TopSelected = TRUE;
929  if (ScrollBarInfo->rgstate[SCROLL_BOTTOM_RECT] & STATE_SYSTEM_PRESSED)
930  BottomSelected = TRUE;
931 
932  /*
933  * Only scrollbar controls send WM_CTLCOLORSCROLLBAR.
934  * The window-owned scrollbars need to call DefWndControlColor
935  * to correctly setup default scrollbar colors
936  */
937  if (nBar == SB_CTL)
938  {
939  hBrush = GetControlBrush( pWnd, hDC, WM_CTLCOLORSCROLLBAR);
940  if (!hBrush)
942  }
943  else
944  {
946  }
947 
948  hSaveBrush = NtGdiSelectBrush(hDC, hBrush);
949 
950  /* Calculate the scroll rectangle */
951  if (Vertical)
952  {
953  Rect.top = ScrollBarInfo->rcScrollBar.top + ScrollBarInfo->dxyLineButton;
954  Rect.bottom = ScrollBarInfo->rcScrollBar.bottom - ScrollBarInfo->dxyLineButton;
955  Rect.left = ScrollBarInfo->rcScrollBar.left;
956  Rect.right = ScrollBarInfo->rcScrollBar.right;
957  }
958  else
959  {
960  Rect.top = ScrollBarInfo->rcScrollBar.top;
961  Rect.bottom = ScrollBarInfo->rcScrollBar.bottom;
962  Rect.left = ScrollBarInfo->rcScrollBar.left + ScrollBarInfo->dxyLineButton;
963  Rect.right = ScrollBarInfo->rcScrollBar.right - ScrollBarInfo->dxyLineButton;
964  }
965 
966  /* Draw the scroll rectangles and thumb */
967  if (!ScrollBarInfo->xyThumbBottom)
968  {
969  NtGdiPatBlt(hDC, Rect.left, Rect.top, Rect.right - Rect.left,
970  Rect.bottom - Rect.top, PATCOPY);
971 
972  /* Cleanup and return */
973  NtGdiSelectBrush(hDC, hSaveBrush);
974  return;
975  }
976 
977  ThumbTop -= ScrollBarInfo->dxyLineButton;
978 
979  if (ScrollBarInfo->dxyLineButton)
980  {
981  if (Vertical)
982  {
983  if (ThumbSize)
984  {
985  NtGdiPatBlt(hDC, Rect.left, Rect.top, Rect.right - Rect.left,
986  ThumbTop, TopSelected ? BLACKNESS : PATCOPY);
987  Rect.top += ThumbTop;
988  NtGdiPatBlt(hDC, Rect.left, Rect.top + ThumbSize, Rect.right - Rect.left,
989  Rect.bottom - Rect.top - ThumbSize, BottomSelected ? BLACKNESS : PATCOPY);
990  Rect.bottom = Rect.top + ThumbSize;
991  }
992  else
993  {
994  if (ThumbTop)
995  {
996  NtGdiPatBlt(hDC, Rect.left, ScrollBarInfo->dxyLineButton,
997  Rect.right - Rect.left, Rect.bottom - Rect.top, PATCOPY);
998  }
999  }
1000  }
1001  else
1002  {
1003  if (ThumbSize)
1004  {
1005  NtGdiPatBlt(hDC, Rect.left, Rect.top, ThumbTop,
1006  Rect.bottom - Rect.top, TopSelected ? BLACKNESS : PATCOPY);
1007  Rect.left += ThumbTop;
1008  NtGdiPatBlt(hDC, Rect.left + ThumbSize, Rect.top,
1009  Rect.right - Rect.left - ThumbSize, Rect.bottom - Rect.top,
1010  BottomSelected ? BLACKNESS : PATCOPY);
1011  Rect.right = Rect.left + ThumbSize;
1012  }
1013  else
1014  {
1015  if (ThumbTop)
1016  {
1017  NtGdiPatBlt(hDC, ScrollBarInfo->dxyLineButton, Rect.top,
1018  Rect.right - Rect.left, Rect.bottom - Rect.top, PATCOPY);
1019  }
1020  }
1021  }
1022  }
1023 
1024  /* Draw the thumb */
1025  if (ThumbSize)
1027 
1028  /* Cleanup */
1029  NtGdiSelectBrush(hDC, hSaveBrush);
1030 }
1031 
1032 
1033 static VOID FASTCALL
1034 IntDrawScrollArrows(HDC hDC, PSCROLLBARINFO ScrollBarInfo, BOOL Vertical)
1035 {
1036  RECT RectLT, RectRB;
1037  INT ScrollDirFlagLT, ScrollDirFlagRB;
1038 
1039  RectLT = RectRB = ScrollBarInfo->rcScrollBar;
1040  if (Vertical)
1041  {
1042  ScrollDirFlagLT = DFCS_SCROLLUP;
1043  ScrollDirFlagRB = DFCS_SCROLLDOWN;
1044  RectLT.bottom = RectLT.top + ScrollBarInfo->dxyLineButton;
1045  RectRB.top = RectRB.bottom - ScrollBarInfo->dxyLineButton;
1046  }
1047  else
1048  {
1049  ScrollDirFlagLT = DFCS_SCROLLLEFT;
1050  ScrollDirFlagRB = DFCS_SCROLLRIGHT;
1051  RectLT.right = RectLT.left + ScrollBarInfo->dxyLineButton;
1052  RectRB.left = RectRB.right - ScrollBarInfo->dxyLineButton;
1053  }
1054 
1055  if (ScrollBarInfo->rgstate[SCROLL_TOP_ARROW] & STATE_SYSTEM_PRESSED)
1056  {
1057  ScrollDirFlagLT |= DFCS_PUSHED | DFCS_FLAT;
1058  }
1059  if (ScrollBarInfo->rgstate[SCROLL_TOP_ARROW] & STATE_SYSTEM_UNAVAILABLE)
1060  {
1061  ScrollDirFlagLT |= DFCS_INACTIVE;
1062  }
1063  if (ScrollBarInfo->rgstate[SCROLL_BOTTOM_ARROW] & STATE_SYSTEM_PRESSED)
1064  {
1065  ScrollDirFlagRB |= DFCS_PUSHED | DFCS_FLAT;
1066  }
1068  {
1069  ScrollDirFlagRB |= DFCS_INACTIVE;
1070  }
1071 
1072  DrawFrameControl(hDC, &RectLT, DFC_SCROLL, ScrollDirFlagLT);
1073  DrawFrameControl(hDC, &RectRB, DFC_SCROLL, ScrollDirFlagRB);
1074 }
1075 
1076 static LONG FASTCALL
1078 {
1079  if (SBType == SB_VERT)
1080  return OBJID_VSCROLL;
1081  if (SBType == SB_HORZ)
1082  return OBJID_HSCROLL;
1083  return OBJID_CLIENT;
1084 }
1085 
1086 static void
1088 {
1089  HDC hdc;
1090  BOOL Vertical = ((nBar == SB_CTL) ? ((pWnd->style & SBS_VERT) != 0) : (nBar == SB_VERT));
1091 
1092  hdc = UserGetDCEx(pWnd, NULL, DCX_CACHE | ((nBar == SB_CTL) ? 0 : DCX_WINDOW));
1093  if (hdc)
1094  { /* Get updated info. */
1095  co_IntGetScrollBarInfo(pWnd, IntScrollGetObjectId(nBar), psbi);
1096  IntDrawScrollInterior(pWnd, hdc, nBar, Vertical, psbi);
1097  UserReleaseDC(pWnd, hdc, FALSE);
1098  }
1099 }
1100 
1101 void
1103 {
1104  //PSBWND pSBWnd;
1105  //INT ThumbSize;
1106  PTHREADINFO pti;
1108  BOOL Vertical;
1109 
1111 
1112  /*
1113  * Get scroll bar info.
1114  */
1115  switch (Bar)
1116  {
1117  case SB_HORZ:
1118  Vertical = FALSE;
1119  break;
1120 
1121  case SB_VERT:
1122  Vertical = TRUE;
1123  break;
1124 
1125  case SB_CTL:
1126  Vertical = (Wnd->style & SBS_VERT) != 0;
1127  break;
1128 
1129  default:
1130  return;
1131  }
1132 
1134  {
1135  return;
1136  }
1137 
1138  if (RECTL_bIsEmptyRect(&Info.rcScrollBar))
1139  {
1140  return;
1141  }
1142 
1143  //ThumbSize = pSBWnd->pSBCalc->pxThumbBottom - pSBWnd->pSBCalc->pxThumbTop;
1144 
1145  /*
1146  * Draw the arrows.
1147  */
1148  if (Info.dxyLineButton)
1149  {
1150  IntDrawScrollArrows(DC, &Info, Vertical);
1151  }
1152 
1153  /*
1154  * Draw the interior.
1155  */
1156  IntDrawScrollInterior(Wnd, DC, Bar, Vertical, &Info);
1157 
1158  /*
1159  * If scroll bar has focus, reposition the caret.
1160  */
1161  if ( Wnd == pti->MessageQueue->spwndFocus && Bar == SB_CTL )
1162  {
1163  if (Vertical)
1164  {
1165  co_IntSetCaretPos(Info.rcScrollBar.top + 1, Info.dxyLineButton + 1);
1166  }
1167  else
1168  {
1169  co_IntSetCaretPos(Info.dxyLineButton + 1, Info.rcScrollBar.top + 1);
1170  }
1171  }
1172 }
1173 
1174 
1177 {
1178  LRESULT lResult = 0;
1179  PWND pWnd;
1180  pWnd = UserGetWindowObject(hWnd);
1181  if (!pWnd) return 0;
1182 
1183  switch(Msg)
1184  {
1185  case WM_ENABLE:
1186  {
1187  if (pWnd->pSBInfo)
1188  {
1190  }
1191  }
1192  break;
1193  }
1194  return lResult;
1195 }
1196 
1198 
1199 BOOL
1200 APIENTRY
1202 {
1203  NTSTATUS Status;
1204  SCROLLBARINFO sbi;
1205  PWND Window;
1206  BOOL Ret;
1209 
1210  TRACE("Enter NtUserGetScrollBarInfo\n");
1212 
1213  Status = MmCopyFromCaller(&sbi, psbi, sizeof(SCROLLBARINFO));
1214  if(!NT_SUCCESS(Status) || (sbi.cbSize != sizeof(SCROLLBARINFO)))
1215  {
1217  RETURN(FALSE);
1218  }
1219 
1220  if(!(Window = UserGetWindowObject(hWnd)))
1221  {
1222  RETURN(FALSE);
1223  }
1224 
1225  UserRefObjectCo(Window, &Ref);
1226  Ret = co_IntGetScrollBarInfo(Window, idObject, &sbi);
1228 
1229  Status = MmCopyToCaller(psbi, &sbi, sizeof(SCROLLBARINFO));
1230  if(!NT_SUCCESS(Status))
1231  {
1233  Ret = FALSE;
1234  }
1235 
1236  RETURN( Ret);
1237 
1238 CLEANUP:
1239  TRACE("Leave NtUserGetScrollBarInfo, ret=%i\n",_ret_);
1240  UserLeave();
1241  END_CLEANUP;
1242 
1243 }
1244 
1245 BOOL
1246 APIENTRY
1248  HWND hWnd,
1249  int fnBar,
1250  PSBDATA pSBData,
1251  LPSCROLLINFO lpsi)
1252 {
1253  PWND Window;
1254  SCROLLINFO psi;
1255  BOOL Ret;
1256  SBDATA SBDataSafe;
1259 
1260  TRACE("Enter NtUserGetScrollInfo\n");
1261  UserEnterShared();
1262 
1263  _SEH2_TRY
1264  {
1265  RtlCopyMemory(&psi, lpsi, sizeof(SCROLLINFO));
1266  if (pSBData)
1267  {
1268  RtlCopyMemory(&SBDataSafe, pSBData, sizeof(SBDATA));
1269  }
1270  }
1272  {
1273  ERR("NtUserGetScrollInfo Failed size.\n");
1276  }
1277  _SEH2_END
1278 
1279  if(!(Window = UserGetWindowObject(hWnd)))
1280  {
1281  ERR("NtUserGetScrollInfo Bad window.\n");
1282  RETURN(FALSE);
1283  }
1284 
1285  UserRefObjectCo(Window, &Ref);
1286  Ret = co_IntGetScrollInfo(Window, fnBar, &SBDataSafe, &psi);
1288 
1289  _SEH2_TRY
1290  {
1291  RtlCopyMemory(lpsi, &psi, sizeof(SCROLLINFO));
1292  }
1294  {
1295  ERR("NtUserGetScrollInfo Failed copy to user.\n");
1298  }
1299  _SEH2_END
1300 
1301  RETURN( Ret);
1302 
1303 CLEANUP:
1304  TRACE("Leave NtUserGetScrollInfo, ret=%i\n",_ret_);
1305  UserLeave();
1306  END_CLEANUP;
1307 }
1308 
1309 BOOL
1310 APIENTRY
1312  HWND hWnd,
1313  UINT wSBflags,
1314  UINT wArrows)
1315 {
1316  UINT OrigArrows;
1317  PWND Window = NULL;
1318  PSCROLLBARINFO InfoV = NULL, InfoH = NULL;
1319  BOOL Chg = FALSE;
1322 
1323  TRACE("Enter NtUserEnableScrollBar\n");
1325 
1326  if (!(Window = UserGetWindowObject(hWnd)) ||
1328  {
1329  RETURN(FALSE);
1330  }
1331  UserRefObjectCo(Window, &Ref);
1332 
1334  {
1335  RETURN( FALSE);
1336  }
1337 
1338  OrigArrows = Window->pSBInfo->WSBflags;
1339  Window->pSBInfo->WSBflags = wArrows;
1340 
1341  if (wSBflags == SB_CTL)
1342  {
1343  if ((wArrows == ESB_DISABLE_BOTH || wArrows == ESB_ENABLE_BOTH))
1344  IntEnableWindow(hWnd, (wArrows == ESB_ENABLE_BOTH));
1345 
1346  RETURN(TRUE);
1347  }
1348 
1349  if(wSBflags != SB_BOTH && !SBID_IS_VALID(wSBflags))
1350  {
1352  ERR("Trying to set scrollinfo for unknown scrollbar type %u", wSBflags);
1353  RETURN(FALSE);
1354  }
1355 
1356  switch(wSBflags)
1357  {
1358  case SB_BOTH:
1360  /* Fall through */
1361  case SB_HORZ:
1363  break;
1364  case SB_VERT:
1366  break;
1367  default:
1368  RETURN(FALSE);
1369  }
1370 
1371  if(InfoV)
1372  Chg = IntEnableScrollBar(FALSE, InfoV, wArrows);
1373 
1374  if(InfoH)
1375  Chg = (IntEnableScrollBar(TRUE, InfoH, wArrows) || Chg);
1376 
1377  ERR("FIXME: EnableScrollBar wSBflags %u wArrows %u Chg %d\n", wSBflags, wArrows, Chg);
1378 // Done in user32:
1379 // SCROLL_RefreshScrollBar( hwnd, nBar, TRUE, TRUE );
1380 
1381  RETURN( Chg);
1382  if (OrigArrows == wArrows) RETURN( FALSE);
1383  RETURN( TRUE);
1384 
1385 CLEANUP:
1386  if (Window)
1388 
1389  TRACE("Leave NtUserEnableScrollBar, ret=%i\n",_ret_);
1390  UserLeave();
1391  END_CLEANUP;
1392 }
1393 
1394 DWORD
1395 APIENTRY
1397  HWND hWnd,
1398  int fnBar,
1399  LPCSCROLLINFO lpsi,
1400  BOOL bRedraw)
1401 {
1402  PWND Window = NULL;
1403  NTSTATUS Status;
1404  SCROLLINFO ScrollInfo;
1407 
1408  TRACE("Enter NtUserSetScrollInfo\n");
1410 
1411  if(!(Window = UserGetWindowObject(hWnd)) ||
1413  {
1414  RETURN( 0);
1415  }
1416  UserRefObjectCo(Window, &Ref);
1417 
1418  Status = MmCopyFromCaller(&ScrollInfo, lpsi, sizeof(SCROLLINFO) - sizeof(ScrollInfo.nTrackPos));
1419  if(!NT_SUCCESS(Status))
1420  {
1422  RETURN( 0);
1423  }
1424 
1425  RETURN(co_IntSetScrollInfo(Window, fnBar, &ScrollInfo, bRedraw));
1426 
1427 CLEANUP:
1428  if (Window)
1430 
1431  TRACE("Leave NtUserSetScrollInfo, ret=%lu\n", _ret_);
1432  UserLeave();
1433  END_CLEANUP;
1434 
1435 }
1436 
1439 {
1440  PWND Window;
1442  DWORD ret;
1444 
1445  TRACE("Enter NtUserShowScrollBar\n");
1447 
1448  if (!(Window = UserGetWindowObject(hWnd)))
1449  {
1450  RETURN(0);
1451  }
1452 
1453  UserRefObjectCo(Window, &Ref);
1454  ret = co_UserShowScrollBar(Window, nBar, (nBar == SB_VERT) ? 0 : bShow,
1455  (nBar == SB_HORZ) ? 0 : bShow);
1457 
1458  RETURN(ret);
1459 
1460 CLEANUP:
1461  TRACE("Leave NtUserShowScrollBar, ret%lu\n", _ret_);
1462  UserLeave();
1463  END_CLEANUP;
1464 
1465 }
1466 
1467 
1469 
1470 BOOL
1471 APIENTRY
1473  HWND hWnd,
1474  LONG idObject,
1476 {
1477  PWND Window = NULL;
1478  SETSCROLLBARINFO Safeinfo;
1479  PSCROLLBARINFO sbi;
1480  LPSCROLLINFO psi;
1481  NTSTATUS Status;
1482  LONG Obj;
1485 
1486  TRACE("Enter NtUserSetScrollBarInfo\n");
1488 
1489  if(!(Window = UserGetWindowObject(hWnd)))
1490  {
1491  RETURN( FALSE);
1492  }
1493  UserRefObjectCo(Window, &Ref);
1494 
1495  Obj = SBOBJ_TO_SBID(idObject);
1496  if(!SBID_IS_VALID(Obj))
1497  {
1499  ERR("Trying to set scrollinfo for unknown scrollbar type %d\n", Obj);
1500  RETURN( FALSE);
1501  }
1502 
1504  {
1505  RETURN(FALSE);
1506  }
1507 
1508  Status = MmCopyFromCaller(&Safeinfo, info, sizeof(SETSCROLLBARINFO));
1509  if(!NT_SUCCESS(Status))
1510  {
1512  RETURN(FALSE);
1513  }
1514 
1517 
1518  psi->nTrackPos = Safeinfo.nTrackPos;
1519  sbi->reserved = Safeinfo.reserved;
1520  RtlCopyMemory(&sbi->rgstate, &Safeinfo.rgstate, sizeof(Safeinfo.rgstate));
1521 
1522  RETURN(TRUE);
1523 
1524 CLEANUP:
1525  if (Window)
1527 
1528  TRACE("Leave NtUserSetScrollBarInfo, ret=%i\n",_ret_);
1529  UserLeave();
1530  END_CLEANUP;
1531 }
1532 
1533 /* EOF */
BOOL FASTCALL IntGetScrollBarRect(PWND Wnd, INT nBar, RECTL *lprect)
Definition: scrollbar.c:110
PSBDATA FASTCALL IntGetSBData(PWND pwnd, INT Bar)
Definition: scrollbar.c:83
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
BOOL FASTCALL co_IntGetScrollBarInfo(PWND Window, LONG idObject, PSCROLLBARINFO psbi)
Definition: scrollbar.c:682
#define WS_DISABLED
Definition: pedump.c:621
#define abs(i)
Definition: fconv.c:206
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
#define DFCS_FLAT
Definition: winuser.h:510
VOID FASTCALL UserEnterShared(VOID)
Definition: ntuser.c:241
#define BF_MIDDLE
Definition: winuser.h:468
GLint GLint GLsizei width
Definition: gl.h:1546
static DWORD FASTCALL co_IntSetScrollInfo(PWND Window, INT nBar, LPCSCROLLINFO lpsi, BOOL bRedraw)
Definition: scrollbar.c:477
#define max(a, b)
Definition: svc.c:63
static void IntDrawScrollInterior(PWND pWnd, HDC hDC, INT nBar, BOOL Vertical, PSCROLLBARINFO ScrollBarInfo)
Definition: scrollbar.c:919
DWORD ExStyle
Definition: ntuser.h:668
#define STATE_SYSTEM_UNAVAILABLE
Definition: winuser.h:2837
#define SM_CYHSCROLL
Definition: winuser.h:952
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define CLEANUP
Definition: ntuser.h:5
#define STATE_SYSTEM_OFFSCREEN
Definition: winuser.h:2853
#define SIF_RANGE
Definition: winuser.h:1221
#define RETURN(value)
Definition: ntuser.h:4
__kernel_entry W32KAPI BOOL APIENTRY NtGdiPatBlt(_In_ HDC hdcDest, _In_ INT x, _In_ INT y, _In_ INT cx, _In_ INT cy, _In_ DWORD dwRop)
Definition: bitblt.c:919
BOOL WINAPI OffsetRect(_Inout_ LPRECT, _In_ int, _In_ int)
#define SA_SSI_HIDE
Definition: scrollbar.c:42
HGDIOBJ FASTCALL IntGetSysColorBrush(INT Object)
Definition: stockobj.c:317
#define UserIsDesktopWindow(pWnd)
Definition: desktop.h:220
#define SB_CTL
Definition: winuser.h:554
#define ESB_DISABLE_BOTH
Definition: winuser.h:556
#define ESB_DISABLE_RTDN
Definition: winuser.h:561
#define SB_VERT
Definition: winuser.h:553
static BOOL FASTCALL co_IntGetScrollInfo(PWND Window, INT nBar, PSBDATA pSBData, LPSCROLLINFO lpsi)
Definition: scrollbar.c:272
#define SW_HIDE
Definition: winuser.h:762
INT page
Definition: ntuser.h:475
#define ASSERT_REFS_CO(_obj_)
Definition: userfuncs.h:13
SBDATA Vert
Definition: ntuser.h:483
static void IntRefeshScrollInterior(PWND pWnd, INT nBar, PSCROLLBARINFO psbi)
Definition: scrollbar.c:1087
#define SB_HORZ
Definition: winuser.h:552
PVOID NTAPI PsGetCurrentThreadWin32Thread(VOID)
Definition: thread.c:805
BOOLEAN FASTCALL co_WinPosSetWindowPos(PWND Window, HWND WndInsertAfter, INT x, INT y, INT cx, INT cy, UINT flags)
Definition: winpos.c:1720
LONG NTSTATUS
Definition: precomp.h:26
#define SCROLL_BOTTOM_RECT
Definition: scrollbar.c:18
static HDC
Definition: imagelist.c:92
#define SM_CYVSCROLL
Definition: winuser.h:971
#define DFCS_INACTIVE
Definition: winuser.h:502
HWND hWnd
Definition: settings.c:17
#define CCHILDREN_SCROLLBAR
Definition: winuser.h:3720
#define SBOBJ_TO_SBID(Obj)
Definition: scroll.h:39
LONG top
Definition: windef.h:307
#define WS_EX_LAYOUTRTL
Definition: winuser.h:390
static __inline VOID UserRefObjectCo(PVOID obj, PUSER_REFERENCE_ENTRY UserReferenceEntry)
Definition: object.h:25
#define CTLCOLOR_SCROLLBAR
Definition: winuser.h:946
long bottom
Definition: polytest.cpp:53
INT pos
Definition: ntuser.h:476
PSBINFO pSBInfo
Definition: ntuser.h:690
#define SCROLL_BOTTOM_ARROW
Definition: scrollbar.c:19
#define MmCopyFromCaller
Definition: polytest.cpp:29
HDC FASTCALL UserGetDCEx(PWND Window OPTIONAL, HANDLE ClipRegion, ULONG Flags)
#define MmCopyToCaller(x, y, z)
Definition: mmcopy.h:19
BOOL WINAPI DrawFrameControl(_In_ HDC, _Inout_ LPRECT, _In_ UINT, _In_ UINT)
struct @1604 Msg[]
UINT_PTR WPARAM
Definition: windef.h:207
RECT rcClient
Definition: ntuser.h:681
#define CHANGERGSTATE(item, status)
Definition: scrollbar.c:54
#define RDW_FRAME
Definition: winuser.h:1198
LONG left
Definition: windef.h:306
DBG_DEFAULT_CHANNEL(UserScrollbar)
#define SWP_NOZORDER
Definition: winuser.h:1232
VOID FASTCALL IntGetClientRect(PWND WindowObject, RECTL *Rect)
Definition: winpos.c:91
#define SCROLL_TOP_ARROW
Definition: scrollbar.c:15
DWORD APIENTRY NtUserShowScrollBar(HWND hWnd, int nBar, DWORD bShow)
Definition: scrollbar.c:1438
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
& rect
Definition: startmenu.cpp:1413
WPARAM wParam
Definition: combotst.c:138
struct TraceInfo Info
#define WM_ENABLE
Definition: winuser.h:1597
#define DCX_WINDOW
Definition: winuser.h:2095
SBCALC SBCalc
Definition: ntuser.h:738
_SEH2_TRY
Definition: create.c:4226
__kernel_entry W32KAPI HBRUSH APIENTRY NtGdiSelectBrush(_In_ HDC hdc, _In_ HBRUSH hbrush)
BOOL FASTCALL NEWco_IntGetScrollInfo(PWND pWnd, INT nBar, PSBDATA pSBData, LPSCROLLINFO lpsi)
Definition: scrollbar.c:328
DWORD APIENTRY NtUserSetScrollInfo(HWND hWnd, int fnBar, LPCSCROLLINFO lpsi, BOOL bRedraw)
Definition: scrollbar.c:1396
#define TAG_SBARINFO
Definition: tags.h:9
#define IntGetScrollbarInfoFromWindow(Window, i)
Definition: scroll.h:33
#define BF_RECT
Definition: winuser.h:462
ULONG cbwndExtra
Definition: ntuser.h:702
#define DFCS_PUSHED
Definition: winuser.h:503
long right
Definition: polytest.cpp:53
Definition: window.c:28
BOOL APIENTRY NtUserGetScrollBarInfo(HWND hWnd, LONG idObject, PSCROLLBARINFO psbi)
Definition: scrollbar.c:1201
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static __inline PVOID DesktopHeapAlloc(IN PDESKTOP Desktop, IN SIZE_T Bytes)
Definition: desktop.h:230
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
INT posNew
Definition: scroll.h:21
static __inline VOID UserDerefObjectCo(PVOID obj)
Definition: object.h:38
#define COLOR_SCROLLBAR
Definition: winuser.h:902
BOOL WINAPI DrawEdge(_In_ HDC, _Inout_ LPRECT, _In_ UINT, _In_ UINT)
static LONG FASTCALL IntScrollGetObjectId(INT SBType)
Definition: scrollbar.c:1077
long top
Definition: polytest.cpp:53
void IntDrawScrollBar(PWND Wnd, HDC DC, INT Bar)
Definition: scrollbar.c:1102
#define SCROLL_THUMB
Definition: scrollbar.c:17
HWND WINAPI GetCapture(void)
Definition: message.c:2880
#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 EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
BOOL FASTCALL co_IntCreateScrollBars(PWND Window)
Definition: scrollbar.c:764
THRDESKHEAD head
Definition: ntuser.h:659
LONG WINAPI GetWindowLongW(_In_ HWND, _In_ int)
Definition: object.h:3
#define SM_CXHTHUMB
Definition: winuser.h:961
smooth NULL
Definition: ftsmooth.c:416
#define MINTRACKTHUMB
Definition: scrollbar.c:39
LONG_PTR LPARAM
Definition: windef.h:208
BOOL WINAPI IsWindowEnabled(_In_ HWND)
BOOL APIENTRY NtUserSBGetParms(HWND hWnd, int fnBar, PSBDATA pSBData, LPSCROLLINFO lpsi)
Definition: scrollbar.c:1247
#define SW_SHOW
Definition: winuser.h:769
long left
Definition: polytest.cpp:53
PWND FASTCALL UserGetWindowObject(HWND hWnd)
Definition: window.c:103
#define DFCS_SCROLLDOWN
Definition: winuser.h:490
#define SBS_VERT
Definition: winuser.h:334
LONG NTAPI UserGetSystemMetrics(ULONG Index)
Definition: metric.c:180
BOOLEAN FASTCALL co_WinPosShowWindow(PWND Wnd, INT Cmd)
Definition: winpos.c:2472
DWORD rgstate[CCHILDREN_SCROLLBAR+1]
Definition: winuser.h:3729
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:247
#define OBJID_CLIENT
Definition: winable.h:19
#define ESB_DISABLE_LTUP
Definition: winuser.h:559
#define TRACE(s)
Definition: solgame.cpp:4
Definition: polytest.cpp:40
BOOL FASTCALL IntCalculateThumb(PWND Wnd, LONG idObject, PSCROLLBARINFO psbi, PSBDATA pSBData)
Definition: scrollbar.c:172
#define OBJID_HSCROLL
Definition: winable.h:21
#define _SEH2_YIELD(STMT_)
Definition: pseh2_64.h:8
#define SM_CXHSCROLL
Definition: winuser.h:972
BOOL APIENTRY NtUserSetScrollBarInfo(HWND hWnd, LONG idObject, SETSCROLLBARINFO *info)
Definition: scrollbar.c:1472
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define SWP_NOACTIVATE
Definition: winuser.h:1227
static void mirror_rect(const RECT *window_rect, RECT *rect)
Definition: scrollbar.c:74
PWND spwndTrack
Definition: scroll.h:11
BOOL FASTCALL IntDestroyScrollBars(PWND Window)
Definition: scrollbar.c:820
unsigned long DWORD
Definition: ntddk_ex.h:95
#define DECLARE_RETURN(type)
Definition: ntuser.h:3
#define DFCS_SCROLLRIGHT
Definition: winuser.h:492
#define DFCS_SCROLLUP
Definition: winuser.h:489
HBRUSH DefWndControlColor(HDC hDC, UINT ctlType)
Definition: defwnd.c:33
#define OBJID_VSCROLL
Definition: winable.h:20
#define UserIsMessageWindow(pWnd)
Definition: desktop.h:223
int Window
Definition: x11stubs.h:26
#define WS_HSCROLL
Definition: pedump.c:628
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
BOOL FASTCALL co_IntSetCaretPos(int X, int Y)
Definition: caret.c:205
int ret
HDC hdc
Definition: main.c:9
#define SA_SSI_SHOW
Definition: scrollbar.c:43
#define SWP_FRAMECHANGED
Definition: winuser.h:1225
INT posMin
Definition: ntuser.h:473
GLdouble s
Definition: gl.h:2039
RECT rcWindow
Definition: ntuser.h:680
#define SB_BOTH
Definition: winuser.h:555
static VOID FASTCALL IntDrawScrollArrows(HDC hDC, PSCROLLBARINFO ScrollBarInfo, BOOL Vertical)
Definition: scrollbar.c:1034
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
struct _SBWND * PSBWND
VOID FASTCALL SetLastNtError(NTSTATUS Status)
Definition: error.c:36
BOOL FASTCALL IntEnableWindow(HWND hWnd, BOOL bEnable)
Definition: window.c:201
Definition: ntuser.h:733
#define PATCOPY
Definition: wingdi.h:334
Status
Definition: gdiplustypes.h:24
#define SIF_POS
Definition: winuser.h:1220
#define EDGE_RAISED
Definition: winuser.h:450
#define SWP_NOSIZE
Definition: winuser.h:1230
#define ERR(fmt,...)
Definition: debug.h:110
#define GWL_STYLE
Definition: winuser.h:846
Definition: ntuser.h:657
struct _USER_MESSAGE_QUEUE * MessageQueue
Definition: win32.h:88
FORCEINLINE VOID RECTL_vOffsetRect(_Inout_ RECTL *prcl, _In_ INT cx, _In_ INT cy)
Definition: rect.h:31
SBDATA Horz
Definition: ntuser.h:482
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:255
static HDC hDC
Definition: 3dtext.c:33
#define SIF_PREVIOUSPOS
Definition: undocuser.h:87
#define DCX_CACHE
Definition: winuser.h:2096
_SEH2_END
Definition: create.c:4400
#define WS_BORDER
Definition: pedump.c:625
const WCHAR * action
Definition: action.c:7783
#define BLACKNESS
Definition: wingdi.h:322
BOOL APIENTRY IntEnableScrollBar(BOOL Horz, PSCROLLBARINFO Info, UINT wArrows)
Definition: scrollbar.c:834
BOOL FASTCALL co_UserRedrawWindow(PWND Window, const RECTL *UpdateRect, PREGION UpdateRgn, ULONG Flags)
Definition: painting.c:876
DWORD FASTCALL co_UserShowScrollBar(PWND Wnd, int nBar, BOOL fShowH, BOOL fShowV)
Definition: scrollbar.c:873
#define SIF_TRACKPOS
Definition: winuser.h:1223
#define SA_SSI_REPAINT_ARROWS
Definition: scrollbar.c:45
struct tagSCROLLBARINFO SCROLLBARINFO
unsigned int UINT
Definition: ndis.h:50
#define WS_VSCROLL
Definition: pedump.c:627
INT FASTCALL UserReleaseDC(PWND Window, HDC hDc, BOOL EndPaint)
Definition: windc.c:917
#define SM_CXVSCROLL
Definition: winuser.h:951
ENGAPI INT APIENTRY EngMulDiv(_In_ INT a, _In_ INT b, _In_ INT c)
Definition: math.c:26
#define DFC_SCROLL
Definition: winuser.h:475
#define SBRG_TOPRIGHTBTN
Definition: scrollbar.c:48
#define SBRG_BOTTOMLEFTBTN
Definition: scrollbar.c:52
#define SIF_DISABLENOSCROLL
Definition: winuser.h:1222
#define IntGetScrollInfoFromWindow(Window, i)
Definition: scroll.h:36
ULONG FASTCALL IntSetStyle(PWND pwnd, ULONG set_bits, ULONG clear_bits)
Definition: window.c:124
#define SBID_IS_VALID(id)
Definition: scroll.h:40
FORCEINLINE BOOL RECTL_bIsEmptyRect(_In_ const RECTL *prcl)
Definition: rect.h:44
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
LONG bottom
Definition: windef.h:309
#define SWP_NOMOVE
Definition: winuser.h:1229
BOOL WINAPI GetWindowRect(_In_ HWND, _Out_ LPRECT)
INT nBar
Definition: scroll.h:22
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
BOOL APIENTRY NtUserEnableScrollBar(HWND hWnd, UINT wSBflags, UINT wArrows)
Definition: scrollbar.c:1311
static int UpdateRect(TreeListData *pData, unsigned uItem, unsigned uSub)
Definition: treelist.c:1529
static __inline BOOL DesktopHeapFree(IN PDESKTOP Desktop, IN PVOID lpMem)
Definition: desktop.h:239
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
#define DFCS_SCROLLLEFT
Definition: winuser.h:491
LONG_PTR LRESULT
Definition: windef.h:209
LRESULT APIENTRY ScrollBarWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: scrollbar.c:1176
Arabic default style
Definition: afstyles.h:93
HBRUSH FASTCALL GetControlBrush(PWND pwnd, HDC hdc, UINT ctlType)
Definition: misc.c:171
#define SCROLL_TOP_RECT
Definition: scrollbar.c:16
LPARAM lParam
Definition: combotst.c:139
#define ESB_ENABLE_BOTH
Definition: winuser.h:563
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:27
BOOL FASTCALL co_IntSetScrollBarInfo(PWND Window, LONG idObject, PSETSCROLLBARINFO psbi)
Definition: scrollbar.c:731
#define STATE_SYSTEM_INVISIBLE
Definition: winuser.h:2852
struct _SBINFOEX SBINFOEX
#define APIENTRY
Definition: api.h:79
struct Rect Rect
#define END_CLEANUP
Definition: ntuser.h:6
INT posMax
Definition: ntuser.h:474
#define RDW_INVALIDATE
Definition: winuser.h:1200
LRESULT FASTCALL co_WinPosGetNonClientSize(PWND Window, RECT *WindowRect, RECT *ClientRect)
Definition: winpos.c:2273
#define SIF_ALL
Definition: winuser.h:1218
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
DWORD style
Definition: ntuser.h:670