Revert the sync.
[reactos.git] / subsystems / win32 / win32k / ntuser / scrollbar.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * PURPOSE: Scrollbars
5 * FILE: subsys/win32k/ntuser/scrollbar.c
6 * PROGRAMER: Thomas Weidenmueller (w3seek@users.sourceforge.net)
7 * Jason Filby (jasonfilby@yahoo.com)
8 * REVISION HISTORY:
9 * 16-11-2002 Jason Filby Created
10 */
11 /* INCLUDES ******************************************************************/
12
13 #include <w32k.h>
14
15 #define NDEBUG
16 #include <debug.h>
17
18 #define MINTRACKTHUMB 8 /* Minimum size of the rectangle between the arrows */
19
20 #define SBRG_SCROLLBAR 0 /* the scrollbar itself */
21 #define SBRG_TOPRIGHTBTN 1 /* the top or right button */
22 #define SBRG_PAGEUPRIGHT 2 /* the page up or page right region */
23 #define SBRG_SCROLLBOX 3 /* the scroll box */
24 #define SBRG_PAGEDOWNLEFT 4 /* the page down or page left region */
25 #define SBRG_BOTTOMLEFTBTN 5 /* the bottom or left button */
26
27 #define CHANGERGSTATE(item, status) \
28 if(Info->rgstate[(item)] != (status)) \
29 Chg = TRUE; \
30 Info->rgstate[(item)] = (status);
31
32 /* FUNCTIONS *****************************************************************/
33
34 /* Ported from WINE20020904 */
35 /* Compute the scroll bar rectangle, in drawing coordinates (i.e. client coords for SB_CTL, window coords for SB_VERT and
36 * SB_HORZ). 'arrowSize' returns the width or height of an arrow (depending on * the orientation of the scrollbar),
37 * 'thumbSize' returns the size of the thumb, and 'thumbPos' returns the position of the thumb relative to the left or to
38 * the top. Return TRUE if the scrollbar is vertical, FALSE if horizontal.
39 */
40 BOOL FASTCALL
41 IntGetScrollBarRect (PWINDOW_OBJECT Window, INT nBar, RECTL *lprect)
42 {
43 BOOL vertical;
44 PWND Wnd = Window->Wnd;
45 RECTL ClientRect = Window->Wnd->rcClient;
46 RECTL WindowRect = Window->Wnd->rcWindow;
47
48 switch (nBar)
49 {
50 case SB_HORZ:
51 lprect->left = ClientRect.left - WindowRect.left;
52 lprect->top = ClientRect.bottom - WindowRect.top;
53 lprect->right = ClientRect.right - WindowRect.left;
54 lprect->bottom = lprect->top + UserGetSystemMetrics (SM_CYHSCROLL);
55 vertical = FALSE;
56 break;
57
58 case SB_VERT:
59 if(Wnd->ExStyle & WS_EX_LEFTSCROLLBAR)
60 {
61 lprect->right = ClientRect.left - WindowRect.left;
62 lprect->left = lprect->right - UserGetSystemMetrics(SM_CXVSCROLL);
63 }
64 else
65 {
66 lprect->left = ClientRect.right - WindowRect.left;
67 lprect->right = lprect->left + UserGetSystemMetrics(SM_CXVSCROLL);
68 }
69 lprect->top = ClientRect.top - WindowRect.top;
70 lprect->bottom = ClientRect.bottom - WindowRect.top;
71 vertical = TRUE;
72 break;
73
74 case SB_CTL:
75 IntGetClientRect (Window, lprect);
76 vertical = ((Wnd->style & SBS_VERT) != 0);
77 break;
78
79 default:
80 return FALSE;
81 }
82
83 return vertical;
84 }
85
86 BOOL FASTCALL
87 IntCalculateThumb(PWINDOW_OBJECT Window, LONG idObject, PSCROLLBARINFO psbi, LPSCROLLINFO psi)
88 {
89 PWND Wnd = Window->Wnd;
90 INT Thumb, ThumbBox, ThumbPos, cxy, mx;
91 RECTL ClientRect;
92
93 switch(idObject)
94 {
95 case SB_HORZ:
96 Thumb = UserGetSystemMetrics(SM_CXHSCROLL);
97 cxy = psbi->rcScrollBar.right - psbi->rcScrollBar.left;
98 break;
99 case SB_VERT:
100 Thumb = UserGetSystemMetrics(SM_CYVSCROLL);
101 cxy = psbi->rcScrollBar.bottom - psbi->rcScrollBar.top;
102 break;
103 case SB_CTL:
104 IntGetClientRect(Window, &ClientRect);
105 if(Wnd->style & SBS_VERT)
106 {
107 Thumb = UserGetSystemMetrics(SM_CYVSCROLL);
108 cxy = ClientRect.bottom - ClientRect.top;
109 }
110 else
111 {
112 Thumb = UserGetSystemMetrics(SM_CXHSCROLL);
113 cxy = ClientRect.right - ClientRect.left;
114 }
115 break;
116 default:
117 return FALSE;
118 }
119
120 ThumbPos = Thumb;
121 /* calculate Thumb */
122 if(cxy <= (2 * Thumb))
123 {
124 Thumb = cxy / 2;
125 psbi->xyThumbTop = 0;
126 psbi->xyThumbBottom = 0;
127 ThumbPos = Thumb;
128 }
129 else
130 {
131 ThumbBox = psi->nPage ? MINTRACKTHUMB : UserGetSystemMetrics(SM_CXHTHUMB);
132 cxy -= (2 * Thumb);
133 if(cxy >= ThumbBox)
134 {
135 if(psi->nPage)
136 {
137 ThumbBox = max(EngMulDiv(cxy, psi->nPage, psi->nMax - psi->nMin + 1), ThumbBox);
138 }
139
140 if(cxy > ThumbBox)
141 {
142 mx = psi->nMax - max(psi->nPage - 1, 0);
143 if(psi->nMin < mx)
144 ThumbPos = Thumb + EngMulDiv(cxy - ThumbBox, psi->nPos - psi->nMin, mx - psi->nMin);
145 else
146 ThumbPos = Thumb + ThumbBox;
147 }
148
149 psbi->xyThumbTop = ThumbPos;
150 psbi->xyThumbBottom = ThumbPos + ThumbBox;
151 }
152 else
153 {
154 psbi->xyThumbTop = 0;
155 psbi->xyThumbBottom = 0;
156 }
157 }
158 psbi->dxyLineButton = Thumb;
159
160 return TRUE;
161 }
162
163 static VOID FASTCALL
164 IntUpdateSBInfo(PWINDOW_OBJECT Window, int wBar)
165 {
166 PSCROLLBARINFO sbi;
167 LPSCROLLINFO psi;
168
169 ASSERT(Window);
170 ASSERT(Window->pSBInfo);
171
172 sbi = IntGetScrollbarInfoFromWindow(Window, wBar);
173 psi = IntGetScrollInfoFromWindow(Window, wBar);
174 IntGetScrollBarRect(Window, wBar, &(sbi->rcScrollBar));
175 IntCalculateThumb(Window, wBar, sbi, psi);
176 }
177
178 static BOOL FASTCALL
179 co_IntGetScrollInfo(PWINDOW_OBJECT Window, INT nBar, LPSCROLLINFO lpsi)
180 {
181 UINT Mask;
182 LPSCROLLINFO psi;
183
184 ASSERT_REFS_CO(Window);
185
186 if(!SBID_IS_VALID(nBar))
187 {
188 SetLastWin32Error(ERROR_INVALID_PARAMETER);
189 DPRINT1("Trying to get scrollinfo for unknown scrollbar type %d\n", nBar);
190 return FALSE;
191 }
192
193 if(!co_IntCreateScrollBars(Window))
194 {
195 return FALSE;
196 }
197
198 psi = IntGetScrollInfoFromWindow(Window, nBar);
199
200 if (lpsi->fMask == SIF_ALL)
201 {
202 Mask = SIF_PAGE | SIF_POS | SIF_RANGE | SIF_TRACKPOS;
203 }
204 else
205 {
206 Mask = lpsi->fMask;
207 }
208
209 if (0 != (Mask & SIF_PAGE))
210 {
211 lpsi->nPage = psi->nPage;
212 }
213
214 if (0 != (Mask & SIF_POS))
215 {
216 lpsi->nPos = psi->nPos;
217 }
218
219 if (0 != (Mask & SIF_RANGE))
220 {
221 lpsi->nMin = psi->nMin;
222 lpsi->nMax = psi->nMax;
223 }
224
225 if (0 != (Mask & SIF_TRACKPOS))
226 {
227 lpsi->nTrackPos = psi->nTrackPos;
228 }
229
230 return TRUE;
231 }
232
233 BOOL FASTCALL
234 NEWco_IntGetScrollInfo(
235 PWND pWnd,
236 INT nBar,
237 PSBDATA pSBData,
238 LPSCROLLINFO lpsi)
239 {
240 UINT Mask;
241 PSBTRACK pSBTrack = pWnd->head.pti->pSBTrack;
242
243 if (!SBID_IS_VALID(nBar))
244 {
245 SetLastWin32Error(ERROR_INVALID_PARAMETER);
246 DPRINT1("Trying to get scrollinfo for unknown scrollbar type %d\n", nBar);
247 return FALSE;
248 }
249
250 Mask = lpsi->fMask;
251
252 if (0 != (Mask & SIF_PAGE))
253 {
254 lpsi->nPage = pSBData->page;
255 }
256
257 if (0 != (Mask & SIF_POS))
258 {
259 lpsi->nPos = pSBData->pos;
260 }
261
262 if (0 != (Mask & SIF_RANGE))
263 {
264 lpsi->nMin = pSBData->posMin;
265 lpsi->nMax = pSBData->posMax;
266 }
267
268 if (0 != (Mask & SIF_TRACKPOS))
269 {
270 if ( pSBTrack &&
271 pSBTrack->nBar == nBar &&
272 pSBTrack->spwndTrack == pWnd )
273 lpsi->nTrackPos = pSBTrack->posNew;
274 else
275 lpsi->nTrackPos = pSBData->pos;
276 }
277 return (Mask & SIF_ALL) !=0;
278 }
279
280 static DWORD FASTCALL
281 co_IntSetScrollInfo(PWINDOW_OBJECT Window, INT nBar, LPCSCROLLINFO lpsi, BOOL bRedraw)
282 {
283 /*
284 * Update the scrollbar state and set action flags according to
285 * what has to be done graphics wise.
286 */
287
288 LPSCROLLINFO Info;
289 PSCROLLBARINFO psbi;
290 /* UINT new_flags;*/
291 BOOL bChangeParams = FALSE; /* don't show/hide scrollbar if params don't change */
292
293 ASSERT_REFS_CO(Window);
294
295 if(!SBID_IS_VALID(nBar))
296 {
297 SetLastWin32Error(ERROR_INVALID_PARAMETER);
298 DPRINT1("Trying to set scrollinfo for unknown scrollbar type %d", nBar);
299 return FALSE;
300 }
301
302 if(!co_IntCreateScrollBars(Window))
303 {
304 return FALSE;
305 }
306
307 if (lpsi->cbSize != sizeof(SCROLLINFO) &&
308 lpsi->cbSize != (sizeof(SCROLLINFO) - sizeof(lpsi->nTrackPos)))
309 {
310 SetLastWin32Error(ERROR_INVALID_PARAMETER);
311 return 0;
312 }
313 if (lpsi->fMask & ~(SIF_ALL | SIF_DISABLENOSCROLL))
314 {
315 SetLastWin32Error(ERROR_INVALID_PARAMETER);
316 return 0;
317 }
318
319 psbi = IntGetScrollbarInfoFromWindow(Window, nBar);
320 Info = IntGetScrollInfoFromWindow(Window, nBar);
321
322 /* Set the page size */
323 if (0 != (lpsi->fMask & SIF_PAGE))
324 {
325 if (Info->nPage != lpsi->nPage)
326 {
327 Info->nPage = lpsi->nPage;
328 bChangeParams = TRUE;
329 }
330 }
331
332 /* Set the scroll pos */
333 if (0 != (lpsi->fMask & SIF_POS))
334 {
335 if (Info->nPos != lpsi->nPos)
336 {
337 Info->nPos = lpsi->nPos;
338 }
339 }
340
341 /* Set the scroll range */
342 if (0 != (lpsi->fMask & SIF_RANGE))
343 {
344 /* Invalid range -> range is set to (0,0) */
345 if (lpsi->nMin > lpsi->nMax ||
346 0x80000000 <= (UINT)(lpsi->nMax - lpsi->nMin))
347 {
348 Info->nMin = 0;
349 Info->nMax = 0;
350 bChangeParams = TRUE;
351 }
352 else if (Info->nMin != lpsi->nMin || Info->nMax != lpsi->nMax)
353 {
354 Info->nMin = lpsi->nMin;
355 Info->nMax = lpsi->nMax;
356 bChangeParams = TRUE;
357 }
358 }
359
360 /* Make sure the page size is valid */
361 if (Info->nMax - Info->nMin + 1 < Info->nPage)
362 {
363 Info->nPage = Info->nMax - Info->nMin + 1;
364 }
365
366 /* Make sure the pos is inside the range */
367 if (Info->nPos < Info->nMin)
368 {
369 Info->nPos = Info->nMin;
370 }
371 else if (Info->nPos > Info->nMax - max(Info->nPage - 1, 0))
372 {
373 Info->nPos = Info->nMax - max(Info->nPage - 1, 0);
374 }
375
376 /*
377 * Don't change the scrollbar state if SetScrollInfo is just called
378 * with SIF_DISABLENOSCROLL
379 */
380 if (0 == (lpsi->fMask & SIF_ALL))
381 {
382 return Info->nPos;
383 }
384
385 /* Check if the scrollbar should be hidden or disabled */
386 if (0 != (lpsi->fMask & (SIF_RANGE | SIF_PAGE | SIF_DISABLENOSCROLL)))
387 {
388 if (Info->nMin >= (int)(Info->nMax - max(Info->nPage - 1, 0)))
389 {
390 /* Hide or disable scroll-bar */
391 if (0 != (lpsi->fMask & SIF_DISABLENOSCROLL))
392 {
393 /* new_flags = ESB_DISABLE_BOTH;*/
394 }
395 else if ((nBar != SB_CTL) && bChangeParams)
396 {
397 co_UserShowScrollBar(Window, nBar, FALSE);
398 return Info->nPos;
399 }
400 }
401 else /* Show and enable scroll-bar */
402 {
403 /* new_flags = 0;*/
404 if ((nBar != SB_CTL) && bChangeParams)
405 {
406 co_UserShowScrollBar(Window, nBar, TRUE);
407 }
408 }
409
410 #if 0
411 if (infoPtr->flags != new_flags) /* check arrow flags */
412 {
413 infoPtr->flags = new_flags;
414 *Action |= SA_SSI_REPAINT_ARROWS;
415 }
416 #endif
417
418 }
419
420 if (bRedraw)
421 {
422 RECTL UpdateRect = psbi->rcScrollBar;
423 UpdateRect.left -= Window->Wnd->rcClient.left - Window->Wnd->rcWindow.left;
424 UpdateRect.right -= Window->Wnd->rcClient.left - Window->Wnd->rcWindow.left;
425 UpdateRect.top -= Window->Wnd->rcClient.top - Window->Wnd->rcWindow.top;
426 UpdateRect.bottom -= Window->Wnd->rcClient.top - Window->Wnd->rcWindow.top;
427 co_UserRedrawWindow(Window, &UpdateRect, 0, RDW_INVALIDATE | RDW_FRAME);
428 }
429
430 /* Return current position */
431 return Info->nPos;
432 }
433
434 BOOL FASTCALL
435 co_IntGetScrollBarInfo(PWINDOW_OBJECT Window, LONG idObject, PSCROLLBARINFO psbi)
436 {
437 INT Bar;
438 PSCROLLBARINFO sbi;
439 LPSCROLLINFO psi;
440
441 ASSERT_REFS_CO(Window);
442
443 Bar = SBOBJ_TO_SBID(idObject);
444
445 if(!SBID_IS_VALID(Bar))
446 {
447 SetLastWin32Error(ERROR_INVALID_PARAMETER);
448 DPRINT1("Trying to get scrollinfo for unknown scrollbar type %d\n", Bar);
449 return FALSE;
450 }
451
452 if(!co_IntCreateScrollBars(Window))
453 {
454 return FALSE;
455 }
456
457 sbi = IntGetScrollbarInfoFromWindow(Window, Bar);
458 psi = IntGetScrollInfoFromWindow(Window, Bar);
459
460 IntGetScrollBarRect(Window, Bar, &(sbi->rcScrollBar));
461 IntCalculateThumb(Window, Bar, sbi, psi);
462
463 RtlCopyMemory(psbi, sbi, sizeof(SCROLLBARINFO));
464
465 return TRUE;
466 }
467
468 BOOL FASTCALL
469 co_IntCreateScrollBars(PWINDOW_OBJECT Window)
470 {
471 PSCROLLBARINFO psbi;
472 LPSCROLLINFO psi;
473 LRESULT Result;
474 ULONG Size, s;
475 INT i;
476
477 ASSERT_REFS_CO(Window);
478
479 if(Window->pSBInfo)
480 {
481 /* no need to create it anymore */
482 return TRUE;
483 }
484
485 /* allocate memory for all scrollbars (HORZ, VERT, CONTROL) */
486 Size = 3 * (sizeof(SBINFOEX));
487 if(!(Window->pSBInfo = ExAllocatePoolWithTag(PagedPool, Size, TAG_SBARINFO)))
488 {
489 DPRINT1("Unable to allocate memory for scrollbar information for window 0x%x\n", Window->hSelf);
490 return FALSE;
491 }
492
493 RtlZeroMemory(Window->pSBInfo, Size);
494
495 Result = co_WinPosGetNonClientSize(Window,
496 &Window->Wnd->rcWindow,
497 &Window->Wnd->rcClient);
498
499 for(s = SB_HORZ; s <= SB_VERT; s++)
500 {
501 psbi = IntGetScrollbarInfoFromWindow(Window, s);
502 psbi->cbSize = sizeof(SCROLLBARINFO);
503 for (i = 0; i < CCHILDREN_SCROLLBAR + 1; i++)
504 psbi->rgstate[i] = 0;
505
506 psi = IntGetScrollInfoFromWindow(Window, s);
507 psi->cbSize = sizeof(LPSCROLLINFO);
508 psi->nMax = 100;
509
510 IntGetScrollBarRect(Window, s, &(psbi->rcScrollBar));
511 IntCalculateThumb(Window, s, psbi, psi);
512 }
513
514 return TRUE;
515 }
516
517 BOOL FASTCALL
518 IntDestroyScrollBars(PWINDOW_OBJECT Window)
519 {
520 if(Window->pSBInfo)
521 {
522 ExFreePool(Window->pSBInfo);
523 Window->pSBInfo = NULL;
524 return TRUE;
525 }
526 return FALSE;
527 }
528
529 BOOL APIENTRY
530 IntEnableScrollBar(BOOL Horz, PSCROLLBARINFO Info, UINT wArrows)
531 {
532 BOOL Chg = FALSE;
533 switch(wArrows)
534 {
535 case ESB_DISABLE_BOTH:
536 CHANGERGSTATE(SBRG_TOPRIGHTBTN, STATE_SYSTEM_UNAVAILABLE);
537 CHANGERGSTATE(SBRG_BOTTOMLEFTBTN, STATE_SYSTEM_UNAVAILABLE);
538 break;
539 case ESB_DISABLE_RTDN:
540 if(Horz)
541 {
542 CHANGERGSTATE(SBRG_BOTTOMLEFTBTN, STATE_SYSTEM_UNAVAILABLE);
543 }
544 else
545 {
546 CHANGERGSTATE(SBRG_TOPRIGHTBTN, STATE_SYSTEM_UNAVAILABLE);
547 }
548 break;
549 case ESB_DISABLE_LTUP:
550 if(Horz)
551 {
552 CHANGERGSTATE(SBRG_TOPRIGHTBTN, STATE_SYSTEM_UNAVAILABLE);
553 }
554 else
555 {
556 CHANGERGSTATE(SBRG_BOTTOMLEFTBTN, STATE_SYSTEM_UNAVAILABLE);
557 }
558 break;
559 case ESB_ENABLE_BOTH:
560 CHANGERGSTATE(SBRG_TOPRIGHTBTN, 0);
561 CHANGERGSTATE(SBRG_BOTTOMLEFTBTN, 0);
562 break;
563 }
564 return Chg;
565 }
566
567
568 BOOL
569 APIENTRY
570 NtUserGetScrollBarInfo(HWND hWnd, LONG idObject, PSCROLLBARINFO psbi)
571 {
572 NTSTATUS Status;
573 SCROLLBARINFO sbi;
574 PWINDOW_OBJECT Window;
575 BOOL Ret;
576 DECLARE_RETURN(BOOL);
577 USER_REFERENCE_ENTRY Ref;
578
579 DPRINT("Enter NtUserGetScrollBarInfo\n");
580 UserEnterExclusive();
581
582 Status = MmCopyFromCaller(&sbi, psbi, sizeof(SCROLLBARINFO));
583 if(!NT_SUCCESS(Status) || (sbi.cbSize != sizeof(SCROLLBARINFO)))
584 {
585 SetLastNtError(Status);
586 RETURN(FALSE);
587 }
588
589 if(!(Window = UserGetWindowObject(hWnd)))
590 {
591 RETURN(FALSE);
592 }
593
594 UserRefObjectCo(Window, &Ref);
595 Ret = co_IntGetScrollBarInfo(Window, idObject, &sbi);
596 UserDerefObjectCo(Window);
597
598 Status = MmCopyToCaller(psbi, &sbi, sizeof(SCROLLBARINFO));
599 if(!NT_SUCCESS(Status))
600 {
601 SetLastNtError(Status);
602 Ret = FALSE;
603 }
604
605 RETURN( Ret);
606
607 CLEANUP:
608 DPRINT("Leave NtUserGetScrollBarInfo, ret=%i\n",_ret_);
609 UserLeave();
610 END_CLEANUP;
611
612 }
613
614
615 BOOL
616 APIENTRY
617 NtUserSBGetParms(
618 HWND hWnd,
619 int fnBar,
620 PSBDATA pSBData,
621 LPSCROLLINFO lpsi)
622 {
623 NTSTATUS Status;
624 PWINDOW_OBJECT Window;
625 SCROLLINFO psi;
626 DWORD sz;
627 BOOL Ret;
628 DECLARE_RETURN(BOOL);
629 USER_REFERENCE_ENTRY Ref;
630
631 DPRINT("Enter NtUserGetScrollInfo\n");
632 UserEnterExclusive();
633
634 Status = MmCopyFromCaller(&psi.cbSize, &(lpsi->cbSize), sizeof(UINT));
635 if(!NT_SUCCESS(Status) ||
636 !((psi.cbSize == sizeof(SCROLLINFO)) || (psi.cbSize == sizeof(SCROLLINFO) - sizeof(psi.nTrackPos))))
637 {
638 SetLastNtError(Status);
639 RETURN(FALSE);
640 }
641 sz = psi.cbSize;
642 Status = MmCopyFromCaller(&psi, lpsi, sz);
643 if (!NT_SUCCESS(Status))
644 {
645 SetLastNtError(Status);
646 RETURN(FALSE);
647 }
648
649 if(!(Window = UserGetWindowObject(hWnd)))
650 {
651 RETURN(FALSE);
652 }
653
654 UserRefObjectCo(Window, &Ref);
655 Ret = co_IntGetScrollInfo(Window, fnBar, &psi);
656 UserDerefObjectCo(Window);
657
658 Status = MmCopyToCaller(lpsi, &psi, sz);
659 if(!NT_SUCCESS(Status))
660 {
661 SetLastNtError(Status);
662 RETURN( FALSE);
663 }
664
665 RETURN( Ret);
666
667 CLEANUP:
668 DPRINT("Leave NtUserGetScrollInfo, ret=%i\n",_ret_);
669 UserLeave();
670 END_CLEANUP;
671 }
672
673
674 BOOL
675 APIENTRY
676 NtUserEnableScrollBar(
677 HWND hWnd,
678 UINT wSBflags,
679 UINT wArrows)
680 {
681 PWINDOW_OBJECT Window = NULL;
682 PSCROLLBARINFO InfoV = NULL, InfoH = NULL;
683 BOOL Chg = FALSE;
684 DECLARE_RETURN(BOOL);
685 USER_REFERENCE_ENTRY Ref;
686
687 DPRINT("Enter NtUserEnableScrollBar\n");
688 UserEnterExclusive();
689
690 if(!(Window = UserGetWindowObject(hWnd)))
691 {
692 RETURN(FALSE);
693 }
694 UserRefObjectCo(Window, &Ref);
695
696 if(wSBflags == SB_CTL)
697 {
698 /* FIXME Enable or Disable SB Ctrl*/
699 DPRINT1("Enable Scrollbar SB_CTL\n");
700 InfoV = IntGetScrollbarInfoFromWindow(Window, SB_CTL);
701 Chg = IntEnableScrollBar(FALSE, InfoV ,wArrows);
702 /* Chg? Scrollbar is Refresh in user32/controls/scrollbar.c. */
703
704 RETURN(TRUE);
705 }
706
707 if(wSBflags != SB_BOTH && !SBID_IS_VALID(wSBflags))
708 {
709 SetLastWin32Error(ERROR_INVALID_PARAMETER);
710 DPRINT1("Trying to set scrollinfo for unknown scrollbar type %d", wSBflags);
711 RETURN(FALSE);
712 }
713
714 if(!co_IntCreateScrollBars(Window))
715 {
716 RETURN( FALSE);
717 }
718
719 switch(wSBflags)
720 {
721 case SB_BOTH:
722 InfoV = IntGetScrollbarInfoFromWindow(Window, SB_VERT);
723 /* fall through */
724 case SB_HORZ:
725 InfoH = IntGetScrollbarInfoFromWindow(Window, SB_HORZ);
726 break;
727 case SB_VERT:
728 InfoV = IntGetScrollbarInfoFromWindow(Window, SB_VERT);
729 break;
730 default:
731 RETURN(FALSE);
732 }
733
734 if(InfoV)
735 Chg = IntEnableScrollBar(FALSE, InfoV, wArrows);
736
737 if(InfoH)
738 Chg = (IntEnableScrollBar(TRUE, InfoH, wArrows) || Chg);
739
740 //if(Chg && (Window->style & WS_VISIBLE))
741 /* FIXME - repaint scrollbars */
742
743 RETURN( TRUE);
744
745 CLEANUP:
746 if (Window)
747 UserDerefObjectCo(Window);
748
749 DPRINT("Leave NtUserEnableScrollBar, ret=%i\n",_ret_);
750 UserLeave();
751 END_CLEANUP;
752 }
753
754 BOOL
755 APIENTRY
756 NtUserSetScrollBarInfo(
757 HWND hWnd,
758 LONG idObject,
759 SETSCROLLBARINFO *info)
760 {
761 PWINDOW_OBJECT Window = NULL;
762 SETSCROLLBARINFO Safeinfo;
763 PSCROLLBARINFO sbi;
764 LPSCROLLINFO psi;
765 NTSTATUS Status;
766 LONG Obj;
767 DECLARE_RETURN(BOOL);
768 USER_REFERENCE_ENTRY Ref;
769
770 DPRINT("Enter NtUserSetScrollBarInfo\n");
771 UserEnterExclusive();
772
773 if(!(Window = UserGetWindowObject(hWnd)))
774 {
775 RETURN( FALSE);
776 }
777 UserRefObjectCo(Window, &Ref);
778
779 Obj = SBOBJ_TO_SBID(idObject);
780 if(!SBID_IS_VALID(Obj))
781 {
782 SetLastWin32Error(ERROR_INVALID_PARAMETER);
783 DPRINT1("Trying to set scrollinfo for unknown scrollbar type %d\n", Obj);
784 RETURN( FALSE);
785 }
786
787 if(!co_IntCreateScrollBars(Window))
788 {
789 RETURN(FALSE);
790 }
791
792 Status = MmCopyFromCaller(&Safeinfo, info, sizeof(SETSCROLLBARINFO));
793 if(!NT_SUCCESS(Status))
794 {
795 SetLastNtError(Status);
796 RETURN(FALSE);
797 }
798
799 sbi = IntGetScrollbarInfoFromWindow(Window, Obj);
800 psi = IntGetScrollInfoFromWindow(Window, Obj);
801
802 psi->nTrackPos = Safeinfo.nTrackPos;
803 sbi->reserved = Safeinfo.reserved;
804 RtlCopyMemory(&sbi->rgstate, &Safeinfo.rgstate, sizeof(Safeinfo.rgstate));
805
806 RETURN(TRUE);
807
808 CLEANUP:
809 if (Window)
810 UserDerefObjectCo(Window);
811
812 DPRINT("Leave NtUserSetScrollBarInfo, ret=%i\n",_ret_);
813 UserLeave();
814 END_CLEANUP;
815 }
816
817 DWORD
818 APIENTRY
819 NtUserSetScrollInfo(
820 HWND hWnd,
821 int fnBar,
822 LPCSCROLLINFO lpsi,
823 BOOL bRedraw)
824 {
825 PWINDOW_OBJECT Window = NULL;
826 NTSTATUS Status;
827 SCROLLINFO ScrollInfo;
828 DECLARE_RETURN(DWORD);
829 USER_REFERENCE_ENTRY Ref;
830
831 DPRINT("Enter NtUserSetScrollInfo\n");
832 UserEnterExclusive();
833
834 if(!(Window = UserGetWindowObject(hWnd)))
835 {
836 RETURN( 0);
837 }
838 UserRefObjectCo(Window, &Ref);
839
840 Status = MmCopyFromCaller(&ScrollInfo, lpsi, sizeof(SCROLLINFO) - sizeof(ScrollInfo.nTrackPos));
841 if(!NT_SUCCESS(Status))
842 {
843 SetLastNtError(Status);
844 RETURN( 0);
845 }
846
847 RETURN(co_IntSetScrollInfo(Window, fnBar, &ScrollInfo, bRedraw));
848
849 CLEANUP:
850 if (Window)
851 UserDerefObjectCo(Window);
852
853 DPRINT("Leave NtUserSetScrollInfo, ret=%i\n",_ret_);
854 UserLeave();
855 END_CLEANUP;
856
857 }
858
859 /* Ported from WINE20020904 (SCROLL_ShowScrollBar) */
860 DWORD FASTCALL
861 co_UserShowScrollBar(PWINDOW_OBJECT Window, int wBar, DWORD bShow)
862 {
863 DWORD Style, OldStyle;
864 PWND Wnd;
865
866 ASSERT_REFS_CO(Window);
867
868 Wnd = Window->Wnd;
869
870 switch(wBar)
871 {
872 case SB_HORZ:
873 Style = WS_HSCROLL;
874 break;
875 case SB_VERT:
876 Style = WS_VSCROLL;
877 break;
878 case SB_BOTH:
879 Style = WS_HSCROLL | WS_VSCROLL;
880 break;
881 case SB_CTL:
882 Style = 0;
883 break;
884 default:
885 SetLastWin32Error(ERROR_INVALID_PARAMETER);
886 return( FALSE);
887 }
888
889 if(!co_IntCreateScrollBars(Window))
890 {
891 return( FALSE);
892 }
893
894 if (wBar == SB_CTL)
895 {
896 IntUpdateSBInfo(Window, SB_CTL);
897
898 co_WinPosShowWindow(Window, bShow ? SW_SHOW : SW_HIDE);
899 return( TRUE);
900 }
901
902 OldStyle = Wnd->style;
903 if(bShow)
904 Wnd->style |= Style;
905 else
906 Wnd->style &= ~Style;
907
908 if(Wnd->style != OldStyle)
909 {
910 if(Wnd->style & WS_HSCROLL)
911 IntUpdateSBInfo(Window, SB_HORZ);
912 if(Wnd->style & WS_VSCROLL)
913 IntUpdateSBInfo(Window, SB_VERT);
914
915 if(Wnd->style & WS_VISIBLE)
916 {
917 /* Frame has been changed, let the window redraw itself */
918 co_WinPosSetWindowPos(Window, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
919 SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOSENDCHANGING);
920 }
921 }
922
923 return( TRUE);
924 }
925
926
927 DWORD APIENTRY
928 NtUserShowScrollBar(HWND hWnd, int wBar, DWORD bShow)
929 {
930 PWINDOW_OBJECT Window;
931 DECLARE_RETURN(DWORD);
932 DWORD ret;
933 USER_REFERENCE_ENTRY Ref;
934
935 DPRINT("Enter NtUserShowScrollBar\n");
936 UserEnterExclusive();
937
938 if (!(Window = UserGetWindowObject(hWnd)))
939 {
940 RETURN(0);
941 }
942
943 UserRefObjectCo(Window, &Ref);
944 ret = co_UserShowScrollBar(Window, wBar, bShow);
945 UserDerefObjectCo(Window);
946
947 RETURN(ret);
948
949 CLEANUP:
950 DPRINT("Leave NtUserShowScrollBar, ret%i\n",_ret_);
951 UserLeave();
952 END_CLEANUP;
953
954 }
955 /* EOF */