1 /* $Id: scrollbar.c,v 1.4 2003/01/24 22:42:15 jfilby Exp $
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 */