1 /* $Id: scrollbar.c,v 1.1 2002/11/24 20:15:37 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
,
39 PINT arrowSize
, PINT thumbSize
, PINT thumbPos
)
45 DbgPrint("[SCROLL_GetScrollBarRect]");
46 W32kGetClientRect (Window
, &ClientRect
);
47 DbgPrint("[WindowRect:%d,%d,%d,%d]\n", Window
->WindowRect
.left
, Window
->WindowRect
.top
, Window
->WindowRect
.right
, Window
->WindowRect
.bottom
);
48 DbgPrint("[ClientRect:%d,%d,%d,%d]\n", ClientRect
.left
, ClientRect
.top
, ClientRect
.right
, ClientRect
.bottom
);
53 DbgPrint ("[SCROLL_GetScrollBarRect:SB_HORZ]");
54 lprect
->left
= ClientRect
.left
- Window
->WindowRect
.left
;
55 lprect
->top
= ClientRect
.bottom
- Window
->WindowRect
.top
;
56 lprect
->right
= ClientRect
.right
- Window
->WindowRect
.left
;
57 lprect
->bottom
= lprect
->top
+ NtUserGetSystemMetrics (SM_CYHSCROLL
);
58 if (Window
->Style
& WS_BORDER
)
63 else if (Window
->Style
& WS_VSCROLL
)
69 DbgPrint ("[SCROLL_GetScrollBarRect:SB_VERT]\n");
70 /* lprect->left = ClientRect.right - Window->WindowRect.left;
71 lprect->top = ClientRect.top - Window->WindowRect.top;
72 lprect->right = lprect->left + NtUserGetSystemMetrics (SM_CXVSCROLL);
73 lprect->bottom = ClientRect.bottom - WindowRect.top; */
74 lprect
->left
= Window
->WindowRect
.left
+ ClientRect
.right
;
75 lprect
->top
= Window
->WindowRect
.bottom
- ClientRect
.bottom
;
76 lprect
->right
= lprect
->left
+ NtUserGetSystemMetrics (SM_CXVSCROLL
);
77 lprect
->bottom
= Window
->WindowRect
.bottom
;
78 if (Window
->Style
& WS_BORDER
)
83 else if (Window
->Style
& WS_HSCROLL
)
85 DbgPrint ("[VERTDIMEN:%d,%d,%d,%d]\n", lprect
->left
, lprect
->top
,
86 lprect
->right
, lprect
->bottom
);
87 DbgPrint ("[Window:%d,%d,%d,%d]\n", Window
->WindowRect
.left
, Window
->WindowRect
.top
,
88 Window
->WindowRect
.right
, Window
->WindowRect
.bottom
);
89 DbgPrint ("[Client:%d,%d,%d,%d]\n", ClientRect
.left
, ClientRect
.top
,
90 ClientRect
.right
, ClientRect
.bottom
);
91 DbgPrint ("[NtUserGetSystemMetrics(SM_CXVSCROLL):%d]\n",
92 NtUserGetSystemMetrics (SM_CXVSCROLL
));
97 DbgPrint ("[SCROLL_GetScrollBarRect:SB_CTL]");
98 W32kGetClientRect (Window
, lprect
);
99 vertical
= ((Window
->Style
& SBS_VERT
) != 0);
103 DbgPrint ("[SCROLL_GetScrollBarRect:FAIL]");
104 W32kReleaseWindowObject(Window
);
109 pixels
= lprect
->bottom
- lprect
->top
;
111 pixels
= lprect
->right
- lprect
->left
;
113 if (pixels
<= 2 * NtUserGetSystemMetrics (SM_CXVSCROLL
) + SCROLL_MIN_RECT
)
115 if (pixels
> SCROLL_MIN_RECT
)
116 *arrowSize
= (pixels
- SCROLL_MIN_RECT
) / 2;
119 *thumbPos
= *thumbSize
= 0;
123 /* PSCROLLBARINFO info;
125 NtUserGetScrollBarInfo (hWnd, nBar, info); recursive loop.. since called function calls this function */
127 *arrowSize
= NtUserGetSystemMetrics (SM_CXVSCROLL
);
129 (2 * (NtUserGetSystemMetrics (SM_CXVSCROLL
) - SCROLL_ARROW_THUMB_OVERLAP
));
132 thumbSize = MulDiv(pixels,info->Page,(info->MaxVal-info->MinVal+1));
133 if (*thumbSize < SCROLL_MIN_THUMB) *thumbSize = SCROLL_MIN_THUMB;
135 else *thumbSize = NtUserGetSystemMetrics(SM_CXVSCROLL); */
137 if (((pixels -= *thumbSize ) < 0) ||
138 ((info->flags & ESB_DISABLE_BOTH) == ESB_DISABLE_BOTH))
140 /* Rectangle too small or scrollbar disabled -> no thumb */
141 /* *thumbPos = *thumbSize = 0;
145 /* INT max = info->MaxVal - max( info->Page-1, 0 );
146 if (info->MinVal >= max)
147 *thumbPos = *arrowSize - SCROLL_ARROW_THUMB_OVERLAP;
149 *thumbPos = *arrowSize - SCROLL_ARROW_THUMB_OVERLAP
150 + MulDiv(pixels, (info->CurVal-info->MinVal),(max - info->MinVal));
153 W32kReleaseWindowObject(Window
);
160 NtUserGetScrollBarInfo(HWND hWnd
, LONG idObject
, PSCROLLBARINFO psbi
)
162 PWINDOW_OBJECT Window
= W32kGetWindowObject(hWnd
);
163 int thumbSize
= 20, arrowSize
= 20, thumbPos
= 0;
165 if (!Window
) return FALSE
;
169 case SB_HORZ
: psbi
= Window
->pHScroll
; break;
170 case SB_VERT
: psbi
= Window
->pVScroll
; break;
171 case SB_CTL
: psbi
= Window
->wExtra
; break;
173 W32kReleaseWindowObject(Window
);
177 if (!psbi
) /* Create the info structure if needed */
179 if ((psbi
= ExAllocatePool(NonPagedPool
, sizeof(SCROLLBARINFO
))))
181 DbgPrint("Creating PSCROLLBARINFO for %d - psbi: %08x\n", idObject
, psbi
);
182 SCROLL_GetScrollBarRect (Window
, idObject
, &(psbi
->rcScrollBar
), &arrowSize
, &thumbSize
, &thumbPos
);
183 DbgPrint("NtUserGetScrollBarInfo: Creating with rect (%d,%d,%d,%d)\n",
184 psbi
->rcScrollBar
.left
, psbi
->rcScrollBar
.top
, psbi
->rcScrollBar
.right
, psbi
->rcScrollBar
.bottom
);
186 if (idObject
== SB_HORZ
) Window
->pHScroll
= psbi
;
187 else Window
->pVScroll
= psbi
;
189 /* if (!hUpArrow) SCROLL_LoadBitmaps(); FIXME: This must be moved somewhere in user32 code */
191 DbgPrint("z1: psbi: %08x\n", psbi
);
192 W32kReleaseWindowObject(Window
);
193 DbgPrint("z2: psbi: %08x\n", psbi
);
197 /* Ported from WINE20020904 */
199 SCROLL_ShowScrollBar (HWND hwnd
, INT nBar
, BOOL fShowH
, BOOL fShowV
)
201 PWINDOW_OBJECT Window
= W32kGetWindowObject(hwnd
);
206 NtUserShowWindow (hwnd
, fShowH
? SW_SHOW
: SW_HIDE
);
213 fShowH
= !(Window
->Style
& WS_HSCROLL
);
214 Window
->Style
|= WS_HSCROLL
;
218 fShowH
= (Window
->Style
& WS_HSCROLL
);
219 Window
->Style
&= ~WS_HSCROLL
;
231 fShowV
= !(Window
->Style
& WS_VSCROLL
);
232 Window
->Style
|= WS_VSCROLL
;
236 fShowV
= (Window
->Style
& WS_VSCROLL
);
237 Window
->Style
&= ~WS_VSCROLL
;
244 return FALSE
; /* Nothing to do! */
247 if (fShowH
|| fShowV
) /* frame has been changed, let the window redraw itself */
249 NtUserSetWindowPos (hwnd
, 0, 0, 0, 0, 0,
250 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
| SWP_NOZORDER
| SWP_FRAMECHANGED
);
253 return FALSE
; /* no frame changes */
258 NtUserEnableScrollBar(
298 NtUserShowScrollBar(HWND hWnd
, int wBar
, DWORD bShow
)
300 DbgPrint("[NtUserShowScrollBar:%d]", bShow
);
301 SCROLL_ShowScrollBar (hWnd
, wBar
, (wBar
== SB_VERT
) ? 0 : bShow
, (wBar
== SB_HORZ
) ? 0 : bShow
);