Get rid of windows.h include in win32k. Fixes bug #666.
[reactos.git] / reactos / subsys / 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 RECT ClientRect = Window->ClientRect;
64 RECT WindowRect = Window->WindowRect;
65
66 switch (nBar)
67 {
68 case SB_HORZ:
69 lprect->left = ClientRect.left - WindowRect.left;
70 lprect->top = ClientRect.bottom - WindowRect.top;
71 lprect->right = ClientRect.right - WindowRect.left;
72 lprect->bottom = lprect->top + NtUserGetSystemMetrics (SM_CYHSCROLL);
73 vertical = FALSE;
74 break;
75
76 case SB_VERT:
77 if(Window->ExStyle & WS_EX_LEFTSCROLLBAR)
78 {
79 lprect->right = ClientRect.left - WindowRect.left;
80 lprect->left = lprect->right - NtUserGetSystemMetrics(SM_CXVSCROLL);
81 }
82 else
83 {
84 lprect->left = ClientRect.right - WindowRect.left;
85 lprect->right = lprect->left + NtUserGetSystemMetrics(SM_CXVSCROLL);
86 }
87 lprect->top = ClientRect.top - WindowRect.top;
88 lprect->bottom = ClientRect.bottom - WindowRect.top;
89 vertical = TRUE;
90 break;
91
92 case SB_CTL:
93 IntGetClientRect (Window, lprect);
94 vertical = ((Window->Style & SBS_VERT) != 0);
95 break;
96
97 default:
98 IntReleaseWindowObject(Window);
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 INT Thumb, ThumbBox, ThumbPos, cxy, mx;
109 RECT ClientRect;
110
111 switch(idObject)
112 {
113 case SB_HORZ:
114 Thumb = NtUserGetSystemMetrics(SM_CXHSCROLL);
115 cxy = psbi->rcScrollBar.right - psbi->rcScrollBar.left;
116 break;
117 case SB_VERT:
118 Thumb = NtUserGetSystemMetrics(SM_CYVSCROLL);
119 cxy = psbi->rcScrollBar.bottom - psbi->rcScrollBar.top;
120 break;
121 case SB_CTL:
122 IntGetClientRect (Window, &ClientRect);
123 if(Window->Style & SBS_VERT)
124 {
125 Thumb = NtUserGetSystemMetrics(SM_CYVSCROLL);
126 cxy = ClientRect.bottom - ClientRect.top;
127 }
128 else
129 {
130 Thumb = NtUserGetSystemMetrics(SM_CXHSCROLL);
131 cxy = ClientRect.right - ClientRect.left;
132 }
133 break;
134 default:
135 return FALSE;
136 }
137
138 ThumbPos = Thumb;
139 /* calculate Thumb */
140 if(cxy <= (2 * Thumb))
141 {
142 Thumb = cxy / 2;
143 psbi->xyThumbTop = 0;
144 psbi->xyThumbBottom = 0;
145 ThumbPos = Thumb;
146 }
147 else
148 {
149 ThumbBox = psi->nPage ? MINTRACKTHUMB : NtUserGetSystemMetrics(SM_CXHTHUMB);
150 cxy -= (2 * Thumb);
151 if(cxy >= ThumbBox)
152 {
153 if(psi->nPage)
154 {
155 ThumbBox = max(EngMulDiv(cxy, psi->nPage, psi->nMax - psi->nMin + 1), ThumbBox);
156 }
157
158 if(cxy > ThumbBox)
159 {
160 mx = psi->nMax - max(psi->nPage - 1, 0);
161 if(psi->nMin < mx)
162 ThumbPos = Thumb + EngMulDiv(cxy - ThumbBox, psi->nPos - psi->nMin, mx - psi->nMin);
163 else
164 ThumbPos = Thumb + ThumbBox;
165 }
166
167 psbi->xyThumbTop = ThumbPos;
168 psbi->xyThumbBottom = ThumbPos + ThumbBox;
169 }
170 else
171 {
172 psbi->xyThumbTop = 0;
173 psbi->xyThumbBottom = 0;
174 }
175 }
176 psbi->dxyLineButton = Thumb;
177
178 return TRUE;
179 }
180
181 static VOID FASTCALL
182 IntUpdateSBInfo(PWINDOW_OBJECT Window, int wBar)
183 {
184 PSCROLLBARINFO sbi;
185 LPSCROLLINFO psi;
186
187 ASSERT(Window);
188 ASSERT(Window->Scroll);
189
190 sbi = IntGetScrollbarInfoFromWindow(Window, wBar);
191 psi = IntGetScrollInfoFromWindow(Window, wBar);
192 IntGetScrollBarRect(Window, wBar, &(sbi->rcScrollBar));
193 IntCalculateThumb(Window, wBar, sbi, psi);
194 }
195
196 static BOOL FASTCALL
197 IntGetScrollInfo(PWINDOW_OBJECT Window, INT nBar, LPSCROLLINFO lpsi)
198 {
199 UINT Mask;
200 LPSCROLLINFO psi;
201
202 if(!SBID_IS_VALID(nBar))
203 {
204 SetLastWin32Error(ERROR_INVALID_PARAMETER);
205 DPRINT1("Trying to get scrollinfo for unknown scrollbar type %d\n", nBar);
206 return FALSE;
207 }
208
209 if(!IntCreateScrollBars(Window))
210 {
211 return FALSE;
212 }
213
214 psi = IntGetScrollInfoFromWindow(Window, nBar);
215
216 if (lpsi->fMask == SIF_ALL)
217 {
218 Mask = SIF_PAGE | SIF_POS | SIF_RANGE | SIF_TRACKPOS;
219 }
220 else
221 {
222 Mask = lpsi->fMask;
223 }
224
225 if (0 != (Mask & SIF_PAGE))
226 {
227 lpsi->nPage = psi->nPage;
228 }
229
230 if (0 != (Mask & SIF_POS))
231 {
232 lpsi->nPos = psi->nPos;
233 }
234
235 if (0 != (Mask & SIF_RANGE))
236 {
237 lpsi->nMin = psi->nMin;
238 lpsi->nMax = psi->nMax;
239 }
240
241 if (0 != (Mask & SIF_TRACKPOS))
242 {
243 lpsi->nTrackPos = psi->nTrackPos;
244 }
245
246 return TRUE;
247 }
248
249 static DWORD FASTCALL
250 IntSetScrollInfo(PWINDOW_OBJECT Window, INT nBar, LPCSCROLLINFO lpsi, BOOL bRedraw)
251 {
252 /*
253 * Update the scrollbar state and set action flags according to
254 * what has to be done graphics wise.
255 */
256
257 LPSCROLLINFO Info;
258 PSCROLLBARINFO psbi;
259 /* UINT new_flags;*/
260 BOOL bChangeParams = FALSE; /* don't show/hide scrollbar if params don't change */
261
262 if(!SBID_IS_VALID(nBar))
263 {
264 SetLastWin32Error(ERROR_INVALID_PARAMETER);
265 DPRINT1("Trying to set scrollinfo for unknown scrollbar type %d", nBar);
266 return FALSE;
267 }
268
269 if(!IntCreateScrollBars(Window))
270 {
271 return FALSE;
272 }
273
274 if (lpsi->cbSize != sizeof(SCROLLINFO) &&
275 lpsi->cbSize != (sizeof(SCROLLINFO) - sizeof(lpsi->nTrackPos)))
276 {
277 SetLastWin32Error(ERROR_INVALID_PARAMETER);
278 return 0;
279 }
280 if (lpsi->fMask & ~(SIF_ALL | SIF_DISABLENOSCROLL))
281 {
282 SetLastWin32Error(ERROR_INVALID_PARAMETER);
283 return 0;
284 }
285
286 psbi = IntGetScrollbarInfoFromWindow(Window, nBar);
287 Info = IntGetScrollInfoFromWindow(Window, nBar);
288
289 /* Set the page size */
290 if (0 != (lpsi->fMask & SIF_PAGE))
291 {
292 if (Info->nPage != lpsi->nPage)
293 {
294 Info->nPage = lpsi->nPage;
295 bChangeParams = TRUE;
296 }
297 }
298
299 /* Set the scroll pos */
300 if (0 != (lpsi->fMask & SIF_POS))
301 {
302 if (Info->nPos != lpsi->nPos)
303 {
304 Info->nPos = lpsi->nPos;
305 }
306 }
307
308 /* Set the scroll range */
309 if (0 != (lpsi->fMask & SIF_RANGE))
310 {
311 /* Invalid range -> range is set to (0,0) */
312 if (lpsi->nMin > lpsi->nMax ||
313 0x80000000 <= (UINT)(lpsi->nMax - lpsi->nMin))
314 {
315 Info->nMin = 0;
316 Info->nMax = 0;
317 bChangeParams = TRUE;
318 }
319 else if (Info->nMin != lpsi->nMin || Info->nMax != lpsi->nMax)
320 {
321 Info->nMin = lpsi->nMin;
322 Info->nMax = lpsi->nMax;
323 bChangeParams = TRUE;
324 }
325 }
326
327 /* Make sure the page size is valid */
328 if (Info->nPage < 0)
329 {
330 Info->nPage = 0;
331 }
332 else if (Info->nMax - Info->nMin + 1 < Info->nPage)
333 {
334 Info->nPage = Info->nMax - Info->nMin + 1;
335 }
336
337 /* Make sure the pos is inside the range */
338 if (Info->nPos < Info->nMin)
339 {
340 Info->nPos = Info->nMin;
341 }
342 else if (Info->nPos > Info->nMax - max(Info->nPage - 1, 0))
343 {
344 Info->nPos = Info->nMax - max(Info->nPage - 1, 0);
345 }
346
347 /*
348 * Don't change the scrollbar state if SetScrollInfo is just called
349 * with SIF_DISABLENOSCROLL
350 */
351 if (0 == (lpsi->fMask & SIF_ALL))
352 {
353 return Info->nPos;
354 }
355
356 /* Check if the scrollbar should be hidden or disabled */
357 if (0 != (lpsi->fMask & (SIF_RANGE | SIF_PAGE | SIF_DISABLENOSCROLL)))
358 {
359 if (Info->nMin >= (int)(Info->nMax - max(Info->nPage - 1, 0)))
360 {
361 /* Hide or disable scroll-bar */
362 if (0 != (lpsi->fMask & SIF_DISABLENOSCROLL))
363 {
364 /* new_flags = ESB_DISABLE_BOTH;*/
365 }
366 else if ((nBar != SB_CTL) && bChangeParams)
367 {
368 NtUserShowScrollBar(Window->Self, nBar, FALSE);
369 return Info->nPos;
370 }
371 }
372 else /* Show and enable scroll-bar */
373 {
374 /* new_flags = 0;*/
375 if ((nBar != SB_CTL) && bChangeParams)
376 {
377 NtUserShowScrollBar(Window->Self, nBar, TRUE);
378 }
379 }
380
381 #if 0
382 if (infoPtr->flags != new_flags) /* check arrow flags */
383 {
384 infoPtr->flags = new_flags;
385 *Action |= SA_SSI_REPAINT_ARROWS;
386 }
387 #endif
388 }
389
390 if (bRedraw)
391 {
392 RECT UpdateRect = psbi->rcScrollBar;
393 UpdateRect.left -= Window->ClientRect.left - Window->WindowRect.left;
394 UpdateRect.right -= Window->ClientRect.left - Window->WindowRect.left;
395 UpdateRect.top -= Window->ClientRect.top - Window->WindowRect.top;
396 UpdateRect.bottom -= Window->ClientRect.top - Window->WindowRect.top;
397 IntRedrawWindow(Window, &UpdateRect, 0, RDW_INVALIDATE | RDW_FRAME);
398 }
399
400 /* Return current position */
401 return Info->nPos;
402 }
403
404 BOOL FASTCALL
405 IntGetScrollBarInfo(PWINDOW_OBJECT Window, LONG idObject, PSCROLLBARINFO psbi)
406 {
407 INT Bar;
408 PSCROLLBARINFO sbi;
409 LPSCROLLINFO psi;
410
411 Bar = SBOBJ_TO_SBID(idObject);
412
413 if(!SBID_IS_VALID(Bar))
414 {
415 SetLastWin32Error(ERROR_INVALID_PARAMETER);
416 DPRINT1("Trying to get scrollinfo for unknown scrollbar type %d\n", Bar);
417 return FALSE;
418 }
419
420 if(!IntCreateScrollBars(Window))
421 {
422 return FALSE;
423 }
424
425 sbi = IntGetScrollbarInfoFromWindow(Window, Bar);
426 psi = IntGetScrollInfoFromWindow(Window, Bar);
427
428 IntGetScrollBarRect(Window, Bar, &(sbi->rcScrollBar));
429 IntCalculateThumb(Window, Bar, sbi, psi);
430
431 RtlCopyMemory(psbi, sbi, sizeof(SCROLLBARINFO));
432
433 return TRUE;
434 }
435
436 BOOL FASTCALL
437 IntCreateScrollBars(PWINDOW_OBJECT Window)
438 {
439 PSCROLLBARINFO psbi;
440 LPSCROLLINFO psi;
441 LRESULT Result;
442 ULONG Size, s;
443 INT i;
444
445 if(Window->Scroll)
446 {
447 /* no need to create it anymore */
448 return TRUE;
449 }
450
451 /* allocate memory for all scrollbars (HORZ, VERT, CONTROL) */
452 Size = 3 * (sizeof(WINDOW_SCROLLINFO));
453 if(!(Window->Scroll = ExAllocatePoolWithTag(PagedPool, Size, TAG_SBARINFO)))
454 {
455 DPRINT1("Unable to allocate memory for scrollbar information for window 0x%x\n", Window->Self);
456 return FALSE;
457 }
458
459 RtlZeroMemory(Window->Scroll, Size);
460
461 Result = WinPosGetNonClientSize(Window->Self,
462 &Window->WindowRect,
463 &Window->ClientRect);
464
465 for(s = SB_HORZ; s <= SB_VERT; s++)
466 {
467 psbi = IntGetScrollbarInfoFromWindow(Window, s);
468 psbi->cbSize = sizeof(SCROLLBARINFO);
469 for (i = 0; i < CCHILDREN_SCROLLBAR + 1; i++)
470 psbi->rgstate[i] = 0;
471
472 psi = IntGetScrollInfoFromWindow(Window, s);
473 psi->cbSize = sizeof(LPSCROLLINFO);
474 psi->nMax = 100;
475
476 IntGetScrollBarRect(Window, s, &(psbi->rcScrollBar));
477 IntCalculateThumb(Window, s, psbi, psi);
478 }
479
480 return TRUE;
481 }
482
483 BOOL FASTCALL
484 IntDestroyScrollBars(PWINDOW_OBJECT Window)
485 {
486 if(Window->Scroll)
487 {
488 ExFreePool(Window->Scroll);
489 Window->Scroll = NULL;
490 return TRUE;
491 }
492 return FALSE;
493 }
494
495 BOOL STDCALL
496 IntEnableScrollBar(BOOL Horz, PSCROLLBARINFO Info, UINT wArrows)
497 {
498 BOOL Chg = FALSE;
499 switch(wArrows)
500 {
501 case ESB_DISABLE_BOTH:
502 CHANGERGSTATE(SBRG_TOPRIGHTBTN, STATE_SYSTEM_UNAVAILABLE);
503 CHANGERGSTATE(SBRG_BOTTOMLEFTBTN, STATE_SYSTEM_UNAVAILABLE);
504 break;
505 case ESB_DISABLE_RTDN:
506 if(Horz)
507 {
508 CHANGERGSTATE(SBRG_BOTTOMLEFTBTN, STATE_SYSTEM_UNAVAILABLE);
509 }
510 else
511 {
512 CHANGERGSTATE(SBRG_TOPRIGHTBTN, STATE_SYSTEM_UNAVAILABLE);
513 }
514 break;
515 case ESB_DISABLE_LTUP:
516 if(Horz)
517 {
518 CHANGERGSTATE(SBRG_TOPRIGHTBTN, STATE_SYSTEM_UNAVAILABLE);
519 }
520 else
521 {
522 CHANGERGSTATE(SBRG_BOTTOMLEFTBTN, STATE_SYSTEM_UNAVAILABLE);
523 }
524 break;
525 case ESB_ENABLE_BOTH:
526 CHANGERGSTATE(SBRG_TOPRIGHTBTN, 0);
527 CHANGERGSTATE(SBRG_BOTTOMLEFTBTN, 0);
528 break;
529 }
530 return Chg;
531 }
532
533
534 BOOL
535 STDCALL
536 NtUserGetScrollBarInfo(HWND hWnd, LONG idObject, PSCROLLBARINFO psbi)
537 {
538 NTSTATUS Status;
539 SCROLLBARINFO sbi;
540 PWINDOW_OBJECT Window;
541 BOOL Ret;
542
543 Status = MmCopyFromCaller(&sbi, psbi, sizeof(SCROLLBARINFO));
544 if(!NT_SUCCESS(Status) || (sbi.cbSize != sizeof(SCROLLBARINFO)))
545 {
546 SetLastNtError(Status);
547 return FALSE;
548 }
549
550 Window = IntGetWindowObject(hWnd);
551
552 if(!Window)
553 {
554 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
555 return FALSE;
556 }
557
558 Ret = IntGetScrollBarInfo(Window, idObject, &sbi);
559
560 Status = MmCopyToCaller(psbi, &sbi, sizeof(SCROLLBARINFO));
561 if(!NT_SUCCESS(Status))
562 {
563 SetLastNtError(Status);
564 Ret = FALSE;
565 }
566 IntReleaseWindowObject(Window);
567 return Ret;
568 }
569
570
571 BOOL
572 STDCALL
573 NtUserGetScrollInfo(HWND hwnd, int fnBar, LPSCROLLINFO lpsi)
574 {
575 NTSTATUS Status;
576 PWINDOW_OBJECT Window;
577 SCROLLINFO psi;
578 DWORD sz;
579 BOOL Ret;
580
581 Status = MmCopyFromCaller(&psi.cbSize, &(lpsi->cbSize), sizeof(UINT));
582 if(!NT_SUCCESS(Status) ||
583 !((psi.cbSize == sizeof(SCROLLINFO)) || (psi.cbSize == sizeof(SCROLLINFO) - sizeof(psi.nTrackPos))))
584 {
585 SetLastNtError(Status);
586 return FALSE;
587 }
588 sz = psi.cbSize;
589 Status = MmCopyFromCaller(&psi, lpsi, sz);
590 if (!NT_SUCCESS(Status))
591 {
592 SetLastNtError(Status);
593 return FALSE;
594 }
595
596 Window = IntGetWindowObject(hwnd);
597
598 if(!Window)
599 {
600 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
601 return FALSE;
602 }
603
604 Ret = IntGetScrollInfo(Window, fnBar, &psi);
605
606 IntReleaseWindowObject(Window);
607
608 Status = MmCopyToCaller(lpsi, &psi, sz);
609 if(!NT_SUCCESS(Status))
610 {
611 SetLastNtError(Status);
612 return FALSE;
613 }
614
615 return Ret;
616 }
617
618
619 BOOL
620 STDCALL
621 NtUserEnableScrollBar(
622 HWND hWnd,
623 UINT wSBflags,
624 UINT wArrows)
625 {
626 PWINDOW_OBJECT Window;
627 PSCROLLBARINFO InfoV = NULL, InfoH = NULL;
628 BOOL Chg = FALSE;
629
630 Window = IntGetWindowObject(hWnd);
631
632 if(!Window)
633 {
634 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
635 return FALSE;
636 }
637
638 if(wSBflags == SB_CTL)
639 {
640 /* FIXME Enable or Disable SB Ctrl*/
641 DPRINT1("Enable Scrollbar SB_CTL\n");
642 InfoV = IntGetScrollbarInfoFromWindow(Window, SB_CTL);
643 Chg = IntEnableScrollBar(FALSE, InfoV ,wArrows);
644 /* Chg? Scrollbar is Refresh in user32/controls/scrollbar.c. */
645 IntReleaseWindowObject(Window);
646 return TRUE;
647 }
648
649 if(wSBflags != SB_BOTH && !SBID_IS_VALID(wSBflags))
650 {
651 IntReleaseWindowObject(Window);
652 SetLastWin32Error(ERROR_INVALID_PARAMETER);
653 DPRINT1("Trying to set scrollinfo for unknown scrollbar type %d", wSBflags);
654 return FALSE;
655 }
656
657 if(!IntCreateScrollBars(Window))
658 {
659 IntReleaseWindowObject(Window);
660 return FALSE;
661 }
662
663 switch(wSBflags)
664 {
665 case SB_BOTH:
666 InfoV = IntGetScrollbarInfoFromWindow(Window, SB_VERT);
667 /* fall through */
668 case SB_HORZ:
669 InfoH = IntGetScrollbarInfoFromWindow(Window, SB_HORZ);
670 break;
671 case SB_VERT:
672 InfoV = IntGetScrollbarInfoFromWindow(Window, SB_VERT);
673 break;
674 default:
675 IntReleaseWindowObject(Window);
676 return FALSE;
677 }
678
679 if(InfoV)
680 Chg = IntEnableScrollBar(FALSE, InfoV, wArrows);
681
682 if(InfoH)
683 Chg = (IntEnableScrollBar(TRUE, InfoH, wArrows) || Chg);
684
685 //if(Chg && (Window->Style & WS_VISIBLE))
686 /* FIXME - repaint scrollbars */
687
688 IntReleaseWindowObject(Window);
689 return TRUE;
690 }
691
692 BOOL
693 STDCALL
694 NtUserSetScrollBarInfo(
695 HWND hwnd,
696 LONG idObject,
697 SETSCROLLBARINFO *info)
698 {
699 PWINDOW_OBJECT Window;
700 SETSCROLLBARINFO Safeinfo;
701 PSCROLLBARINFO sbi;
702 LPSCROLLINFO psi;
703 NTSTATUS Status;
704 LONG Obj;
705
706 Window = IntGetWindowObject(hwnd);
707
708 if(!Window)
709 {
710 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
711 return FALSE;
712 }
713
714 Obj = SBOBJ_TO_SBID(idObject);
715 if(!SBID_IS_VALID(Obj))
716 {
717 IntReleaseWindowObject(Window);
718 SetLastWin32Error(ERROR_INVALID_PARAMETER);
719 DPRINT1("Trying to set scrollinfo for unknown scrollbar type %d", Obj);
720 return FALSE;
721 }
722
723 if(!IntCreateScrollBars(Window))
724 {
725 IntReleaseWindowObject(Window);
726 return FALSE;
727 }
728
729 Status = MmCopyFromCaller(&Safeinfo, info, sizeof(SETSCROLLBARINFO));
730 if(!NT_SUCCESS(Status))
731 {
732 IntReleaseWindowObject(Window);
733 SetLastNtError(Status);
734 return FALSE;
735 }
736
737 sbi = IntGetScrollbarInfoFromWindow(Window, Obj);
738 psi = IntGetScrollInfoFromWindow(Window, Obj);
739
740 psi->nTrackPos = Safeinfo.nTrackPos;
741 sbi->reserved = Safeinfo.reserved;
742 RtlCopyMemory(&sbi->rgstate, &Safeinfo.rgstate, sizeof(Safeinfo.rgstate));
743
744 IntReleaseWindowObject(Window);
745 return TRUE;
746 }
747
748 DWORD
749 STDCALL
750 NtUserSetScrollInfo(
751 HWND hwnd,
752 int fnBar,
753 LPCSCROLLINFO lpsi,
754 BOOL bRedraw)
755 {
756 PWINDOW_OBJECT Window;
757 NTSTATUS Status;
758 SCROLLINFO ScrollInfo;
759 DWORD Ret;
760
761 Window = IntGetWindowObject(hwnd);
762
763 if(!Window)
764 {
765 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
766 return 0;
767 }
768
769 Status = MmCopyFromCaller(&ScrollInfo, lpsi, sizeof(SCROLLINFO) - sizeof(ScrollInfo.nTrackPos));
770 if(!NT_SUCCESS(Status))
771 {
772 IntReleaseWindowObject(Window);
773 SetLastNtError(Status);
774 return 0;
775 }
776
777 Ret = IntSetScrollInfo(Window, fnBar, &ScrollInfo, bRedraw);
778 IntReleaseWindowObject(Window);
779
780 return Ret;
781 }
782
783 /* Ported from WINE20020904 (SCROLL_ShowScrollBar) */
784 DWORD STDCALL
785 NtUserShowScrollBar(HWND hWnd, int wBar, DWORD bShow)
786 {
787 DWORD Style, OldStyle;
788 PWINDOW_OBJECT Window = IntGetWindowObject(hWnd);
789
790 if (!Window)
791 {
792 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
793 return FALSE;
794 }
795
796 switch(wBar)
797 {
798 case SB_HORZ:
799 Style = WS_HSCROLL;
800 break;
801 case SB_VERT:
802 Style = WS_VSCROLL;
803 break;
804 case SB_BOTH:
805 Style = WS_HSCROLL | WS_VSCROLL;
806 break;
807 case SB_CTL:
808 Style = 0;
809 break;
810 default:
811 IntReleaseWindowObject(Window);
812 SetLastWin32Error(ERROR_INVALID_PARAMETER);
813 return FALSE;
814 }
815
816 if(!IntCreateScrollBars(Window))
817 {
818 IntReleaseWindowObject(Window);
819 return FALSE;
820 }
821
822 if (wBar == SB_CTL)
823 {
824 IntUpdateSBInfo(Window, SB_CTL);
825
826 WinPosShowWindow(hWnd, bShow ? SW_SHOW : SW_HIDE);
827 IntReleaseWindowObject(Window);
828 return TRUE;
829 }
830
831 OldStyle = Window->Style;
832 if(bShow)
833 Window->Style |= Style;
834 else
835 Window->Style &= ~Style;
836
837 if(Window->Style != OldStyle)
838 {
839 if(Window->Style & WS_HSCROLL)
840 IntUpdateSBInfo(Window, SB_HORZ);
841 if(Window->Style & WS_VSCROLL)
842 IntUpdateSBInfo(Window, SB_VERT);
843
844 if(Window->Style & WS_VISIBLE)
845 {
846 /* Frame has been changed, let the window redraw itself */
847 WinPosSetWindowPos(hWnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
848 SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOSENDCHANGING);
849 }
850 }
851
852 IntReleaseWindowObject(Window);
853 return TRUE;
854 }
855
856 /* EOF */