3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
6 * FILE: subsys/win32k/ntuser/scrollbar.c
7 * PROGRAMER: Jason Filby (jasonfilby@yahoo.com)
9 * 16-11-2002 Jason Filby Created
11 /* INCLUDES ******************************************************************/
13 #include <ddk/ntddk.h>
14 #include <win32k/win32k.h>
15 #include <include/object.h>
16 #include <include/window.h>
17 #include <include/class.h>
18 #include <include/error.h>
19 #include <include/winsta.h>
20 #include <include/winpos.h>
21 #include <include/rect.h>
26 #define SCROLL_MIN_RECT 4 /* Minimum size of the rectangle between the arrows */
27 #define SCROLL_ARROW_THUMB_OVERLAP 0 /* Overlap between arrows and thumb */
29 /* FUNCTIONS *****************************************************************/
31 /* Ported from WINE20020904 */
32 /* Compute the scroll bar rectangle, in drawing coordinates (i.e. client coords for SB_CTL, window coords for SB_VERT and
33 * SB_HORZ). 'arrowSize' returns the width or height of an arrow (depending on * the orientation of the scrollbar),
34 * 'thumbSize' returns the size of the thumb, and 'thumbPos' returns the position of the thumb relative to the left or to
35 * the top. Return TRUE if the scrollbar is vertical, FALSE if horizontal.
38 SCROLL_GetScrollBarRect (PWINDOW_OBJECT Window, INT nBar, PRECT lprect)
41 INT pixels, thumbSize, arrowSize;
43 RECT ClientRect = Window->ClientRect;
44 RECT WindowRect = Window->WindowRect;
50 lprect->left = ClientRect.left - WindowRect.left;
51 lprect->top = ClientRect.bottom - WindowRect.top;
52 lprect->right = ClientRect.right - WindowRect.left;
53 lprect->bottom = lprect->top + NtUserGetSystemMetrics (SM_CYHSCROLL);
54 if (Window->Style & WS_BORDER)
59 else if (Window->Style & WS_VSCROLL)
65 lprect->left = ClientRect.right - WindowRect.left;
66 lprect->top = ClientRect.top - WindowRect.top;
67 lprect->right = lprect->left + NtUserGetSystemMetrics (SM_CXVSCROLL);
68 lprect->bottom = ClientRect.bottom - WindowRect.top;
69 if (Window->Style & WS_BORDER)
74 else if (Window->Style & WS_HSCROLL)
80 W32kGetClientRect (Window, lprect);
81 vertical = ((Window->Style & SBS_VERT) != 0);
85 W32kReleaseWindowObject(Window);
90 pixels = lprect->bottom - lprect->top;
92 pixels = lprect->right - lprect->left;
94 info.cbSize = sizeof(SCROLLBARINFO);
95 SCROLL_GetScrollBarInfo (Window, nBar, &info);
97 if (pixels <= 2 * NtUserGetSystemMetrics (SM_CXVSCROLL) + SCROLL_MIN_RECT)
99 info.dxyLineButton = info.xyThumbTop = info.xyThumbBottom = 0;
103 arrowSize = NtUserGetSystemMetrics (SM_CXVSCROLL);
104 pixels -= (2 * (NtUserGetSystemMetrics (SM_CXVSCROLL) - SCROLL_ARROW_THUMB_OVERLAP));
106 /* Temporary initialization - to be removed once proper code is in */
107 info.dxyLineButton = info.xyThumbTop = info.xyThumbBottom = 0;
111 thumbSize = MulDiv(pixels,info->Page,(info->MaxVal-info->MinVal+1));
112 if (*thumbSize < SCROLL_MIN_THUMB) *thumbSize = SCROLL_MIN_THUMB;
114 else *thumbSize = NtUserGetSystemMetrics(SM_CXVSCROLL); */
116 if (((pixels -= *thumbSize ) < 0) ||
117 ((info->flags & ESB_DISABLE_BOTH) == ESB_DISABLE_BOTH))
119 /* Rectangle too small or scrollbar disabled -> no thumb */
120 /* *thumbPos = *thumbSize = 0;
124 /* INT max = info->MaxVal - max( info->Page-1, 0 );
125 if (info->MinVal >= max)
126 *thumbPos = *arrowSize - SCROLL_ARROW_THUMB_OVERLAP;
128 *thumbPos = *arrowSize - SCROLL_ARROW_THUMB_OVERLAP
129 + MulDiv(pixels, (info->CurVal-info->MinVal),(max - info->MinVal));
136 DWORD SCROLL_CreateScrollBar(PWINDOW_OBJECT Window, LONG idObject)
142 Result = WinPosGetNonClientSize(Window->Self,
144 &Window->ClientRect);
146 psbi = ExAllocatePool(NonPagedPool, sizeof(SCROLLBARINFO));
148 for (i=0; i<CCHILDREN_SCROLLBAR+1; i++)
149 psbi->rgstate[i] = 0;
154 Window->pHScroll = psbi;
157 Window->pVScroll = psbi;
160 Window->wExtra = psbi;
166 SCROLL_GetScrollBarRect (Window, idObject, &(psbi->rcScrollBar));
171 DWORD SCROLL_GetScrollBarInfo(PWINDOW_OBJECT Window, LONG idObject, PSCROLLBARINFO psbi)
176 memcpy(psbi, Window->pHScroll, psbi->cbSize);
179 memcpy(psbi, Window->pVScroll, psbi->cbSize);
182 memcpy(psbi, Window->wExtra, psbi->cbSize);
185 W32kReleaseWindowObject(Window);
194 NtUserGetScrollBarInfo(HWND hWnd, LONG idObject, PSCROLLBARINFO psbi)
196 PWINDOW_OBJECT Window = W32kGetWindowObject(hWnd);
198 if (!Window) return FALSE;
200 SCROLL_GetScrollBarInfo(Window, idObject, psbi);
202 W32kReleaseWindowObject(Window);
209 NtUserEnableScrollBar(
247 /* Ported from WINE20020904 (SCROLL_ShowScrollBar) */
250 NtUserShowScrollBar(HWND hWnd, int wBar, DWORD bShow)
252 BOOL fShowV = (wBar == SB_VERT) ? 0 : bShow;
253 BOOL fShowH = (wBar == SB_HORZ) ? 0 : bShow;
254 PWINDOW_OBJECT Window = W32kGetWindowObject(hWnd);
259 NtUserShowWindow (hWnd, fShowH ? SW_SHOW : SW_HIDE);
266 fShowH = !(Window->Style & WS_HSCROLL);
267 Window->Style |= WS_HSCROLL;
271 fShowH = (Window->Style & WS_HSCROLL);
272 Window->Style &= ~WS_HSCROLL;
284 fShowV = !(Window->Style & WS_VSCROLL);
285 Window->Style |= WS_VSCROLL;
289 fShowV = (Window->Style & WS_VSCROLL);
290 Window->Style &= ~WS_VSCROLL;
297 return FALSE; /* Nothing to do! */
300 if (fShowH || fShowV) /* frame has been changed, let the window redraw itself */
302 NtUserSetWindowPos (hWnd, 0, 0, 0, 0, 0,
303 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED);
306 return FALSE; /* no frame changes */