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