3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
6 * FILE: subsys/win32k/ntuser/window.c
7 * PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
9 * 06-06-2001 CSH Created
11 /* INCLUDES ******************************************************************/
13 /* INCLUDES ******************************************************************/
19 /* GLOBAL VARIABLES **********************************************************/
21 static HBITMAP hUpArrow;
22 static HBITMAP hDnArrow;
23 static HBITMAP hLfArrow;
24 static HBITMAP hRgArrow;
25 static HBITMAP hUpArrowD;
26 static HBITMAP hDnArrowD;
27 static HBITMAP hLfArrowD;
28 static HBITMAP hRgArrowD;
29 static HBITMAP hUpArrowI;
30 static HBITMAP hDnArrowI;
31 static HBITMAP hLfArrowI;
32 static HBITMAP hRgArrowI;
34 #define TOP_ARROW(flags,pressed) \
35 (((flags)&ESB_DISABLE_UP) ? hUpArrowI : ((pressed) ? hUpArrowD:hUpArrow))
36 #define BOTTOM_ARROW(flags,pressed) \
37 (((flags)&ESB_DISABLE_DOWN) ? hDnArrowI : ((pressed) ? hDnArrowD:hDnArrow))
38 #define LEFT_ARROW(flags,pressed) \
39 (((flags)&ESB_DISABLE_LEFT) ? hLfArrowI : ((pressed) ? hLfArrowD:hLfArrow))
40 #define RIGHT_ARROW(flags,pressed) \
41 (((flags)&ESB_DISABLE_RIGHT) ? hRgArrowI : ((pressed) ? hRgArrowD:hRgArrow))
43 #define SCROLL_ARROW_THUMB_OVERLAP 0 /* Overlap between arrows and thumb */
44 #define SCROLL_MIN_THUMB 6 /* Minimum size of the thumb in pixels */
45 #define SCROLL_FIRST_DELAY 200 /* Delay (in ms) before first repetition when holding the button down */
46 #define SCROLL_REPEAT_DELAY 50 /* Delay (in ms) between scroll repetitions */
47 #define SCROLL_TIMER 0 /* Scroll timer id */
49 /* What to do after SCROLL_SetScrollInfo() */
50 #define SA_SSI_HIDE 0x0001
51 #define SA_SSI_SHOW 0x0002
52 #define SA_SSI_REFRESH 0x0004
53 #define SA_SSI_REPAINT_ARROWS 0x0008
55 /* Scroll-bar hit testing */
58 SCROLL_NOWHERE, /* Outside the scroll bar */
59 SCROLL_TOP_ARROW, /* Top or left arrow */
60 SCROLL_TOP_RECT, /* Rectangle between the top arrow and the thumb */
61 SCROLL_THUMB, /* Thumb rectangle */
62 SCROLL_BOTTOM_RECT, /* Rectangle between the thumb and the bottom arrow */
63 SCROLL_BOTTOM_ARROW /* Bottom or right arrow */
66 static BOOL SCROLL_MovingThumb = FALSE; /* Is the moving thumb being displayed? */
68 /* Thumb-tracking info */
69 static HWND SCROLL_TrackingWin = 0;
70 static INT SCROLL_TrackingBar = 0;
71 static INT SCROLL_TrackingPos = 0;
72 /* static INT SCROLL_TrackingVal = 0; */
73 static enum SCROLL_HITTEST SCROLL_trackHitTest; /* Hit test code of the last button-down event */
74 static BOOL SCROLL_trackVertical;
76 /* FUNCTIONS *****************************************************************/
78 HBRUSH DefWndControlColor (HDC hDC, UINT ctlType);
79 HPEN STDCALL GetSysColorPen (int nIndex);
84 GetScrollBarInfo (HWND hwnd, LONG idObject, PSCROLLBARINFO psbi)
86 int ret = NtUserGetScrollBarInfo (hwnd, idObject, psbi);
91 /* Ported from WINE20020904 */
92 /* Draw the scroll bar interior (everything except the arrows). */
94 SCROLL_DrawInterior (HWND hwnd, HDC hdc, INT nBar, INT arrowSize, PSCROLLBARINFO psbi)
96 INT thumbSize = psbi->xyThumbBottom - psbi->xyThumbTop;
98 HBRUSH hSaveBrush, hBrush;
99 BOOLEAN top_selected = FALSE, bottom_selected = FALSE;
100 DbgPrint("[SCROLL_DrawInterior:%d]\n", nBar);
101 if(psbi->rgstate[2] & STATE_SYSTEM_PRESSED)
105 if(psbi->rgstate[4] & STATE_SYSTEM_PRESSED)
107 bottom_selected = TRUE;
110 /* Only scrollbar controls send WM_CTLCOLORSCROLLBAR.
111 * The window-owned scrollbars need to call DefWndControlColor
112 * to correctly setup default scrollbar colors
116 hBrush = (HBRUSH) NtUserSendMessage (GetParent (hwnd), WM_CTLCOLORSCROLLBAR,
117 (WPARAM) hdc, (LPARAM) hwnd);
121 /* hBrush = NtUserGetControlColor (hdc, CTLCOLOR_SCROLLBAR); FIXME */ /* DefWndControlColor */
122 hBrush = GetSysColorBrush(COLOR_SCROLLBAR);
125 hSavePen = SelectObject (hdc, GetSysColorPen (COLOR_WINDOWFRAME));
126 hSaveBrush = SelectObject (hdc, hBrush);
128 /* Calculate the scroll rectangle */
131 psbi->rcScrollBar.top += arrowSize - SCROLL_ARROW_THUMB_OVERLAP;
132 psbi->rcScrollBar.bottom -= (arrowSize - SCROLL_ARROW_THUMB_OVERLAP);
134 else if (nBar == SB_HORZ)
136 psbi->rcScrollBar.left += arrowSize - SCROLL_ARROW_THUMB_OVERLAP;
137 psbi->rcScrollBar.right -= (arrowSize - SCROLL_ARROW_THUMB_OVERLAP);
140 /* Draw the scroll rectangles and thumb */
141 if (!psbi->dxyLineButton) /* No thumb to draw */
144 psbi->rcScrollBar.left,
145 psbi->rcScrollBar.top,
146 psbi->rcScrollBar.right - psbi->rcScrollBar.left,
147 psbi->rcScrollBar.bottom - psbi->rcScrollBar.top,
150 /* cleanup and return */
151 SelectObject (hdc, hSavePen);
152 SelectObject (hdc, hSaveBrush);
159 psbi->rcScrollBar.left,
160 psbi->rcScrollBar.top,
161 psbi->rcScrollBar.right - psbi->rcScrollBar.left,
162 psbi->dxyLineButton - (arrowSize - SCROLL_ARROW_THUMB_OVERLAP),
163 top_selected ? 0x0f0000 : PATCOPY);
164 psbi->rcScrollBar.top += psbi->dxyLineButton - (arrowSize - SCROLL_ARROW_THUMB_OVERLAP);
166 psbi->rcScrollBar.left,
167 psbi->rcScrollBar.top + thumbSize,
168 psbi->rcScrollBar.right - psbi->rcScrollBar.left,
169 psbi->rcScrollBar.bottom - psbi->rcScrollBar.top - thumbSize,
170 bottom_selected ? 0x0f0000 : PATCOPY);
171 psbi->rcScrollBar.bottom = psbi->rcScrollBar.top + thumbSize;
173 else if (nBar == SB_HORZ)
176 psbi->rcScrollBar.left,
177 psbi->rcScrollBar.top,
178 psbi->dxyLineButton - (arrowSize - SCROLL_ARROW_THUMB_OVERLAP),
179 psbi->rcScrollBar.bottom - psbi->rcScrollBar.top,
180 top_selected ? 0x0f0000 : PATCOPY);
181 psbi->rcScrollBar.left += psbi->dxyLineButton - (arrowSize - SCROLL_ARROW_THUMB_OVERLAP);
183 psbi->rcScrollBar.left + thumbSize,
184 psbi->rcScrollBar.top,
185 psbi->rcScrollBar.right - psbi->rcScrollBar.left - thumbSize,
186 psbi->rcScrollBar.bottom - psbi->rcScrollBar.top,
187 bottom_selected ? 0x0f0000 : PATCOPY);
188 psbi->rcScrollBar.right = psbi->rcScrollBar.left + thumbSize;
192 DrawEdge (hdc, &psbi->rcScrollBar, EDGE_RAISED, BF_RECT | BF_MIDDLE);
195 SelectObject (hdc, hSavePen);
196 SelectObject (hdc, hSaveBrush);
199 /* Ported from WINE20020904 */
201 SCROLL_DrawMovingThumb (HDC hdc, RECT * rect, int nBar, int arrowSize, int thumbSize, PSCROLLBARINFO psbi)
203 INT pos = SCROLL_TrackingPos;
207 max_size = psbi->rcScrollBar.bottom - psbi->rcScrollBar.top;
208 else if (nBar == SB_HORZ)
209 max_size = psbi->rcScrollBar.right - psbi->rcScrollBar.left;
211 max_size -= (arrowSize - SCROLL_ARROW_THUMB_OVERLAP) + thumbSize;
213 if (pos < (arrowSize - SCROLL_ARROW_THUMB_OVERLAP))
214 pos = (arrowSize - SCROLL_ARROW_THUMB_OVERLAP);
215 else if (pos > max_size)
218 SCROLL_DrawInterior (SCROLL_TrackingWin, hdc, SCROLL_TrackingBar, arrowSize, psbi);
220 SCROLL_MovingThumb = !SCROLL_MovingThumb;
223 /* Ported from WINE20020904 */
224 /* Draw the scroll bar arrows. */
226 SCROLL_DrawArrows (HDC hdc, PSCROLLBARINFO info,
227 RECT * rect, INT arrowSize, int nBar,
228 BOOL top_pressed, BOOL bottom_pressed)
231 int scrollDirFlag1, scrollDirFlag2;
235 scrollDirFlag1 = DFCS_SCROLLUP;
236 scrollDirFlag2 = DFCS_SCROLLDOWN;
238 else if (nBar == SB_HORZ)
240 scrollDirFlag1 = DFCS_SCROLLLEFT;
241 scrollDirFlag2 = DFCS_SCROLLRIGHT;
246 r.bottom = r.top + arrowSize;
247 else if (nBar == SB_HORZ)
248 r.right = r.left + arrowSize;
250 DrawFrameControl (hdc, &r, DFC_SCROLL,
251 scrollDirFlag1 | (top_pressed ? (DFCS_PUSHED | DFCS_FLAT) : 0)
252 /* | (info.flags&ESB_DISABLE_LTUP ? DFCS_INACTIVE : 0) */
256 r.top = r.bottom - arrowSize;
257 else if (nBar == SB_HORZ)
258 r.left = r.right - arrowSize;
259 DrawFrameControl (hdc, &r, DFC_SCROLL,
260 scrollDirFlag2 | (bottom_pressed ? (DFCS_PUSHED | DFCS_FLAT) : 0)
261 /* | (info.flags&ESB_DISABLE_RTDN ? DFCS_INACTIVE : 0) */
265 /* Ported from WINE20020904 */
266 /* Redraw the whole scrollbar. */
268 SCROLL_DrawScrollBar (HWND hwnd, HDC hdc, INT nBar,
269 BOOL arrows, BOOL interior)
274 BOOL Save_SCROLL_MovingThumb = SCROLL_MovingThumb;
276 info.cbSize = sizeof(SCROLLBARINFO);
277 GetScrollBarInfo (hwnd, nBar, &info);
279 thumbSize = info.xyThumbBottom - info.xyThumbTop;
283 arrowSize = GetSystemMetrics(SM_CYHSCROLL);
287 arrowSize = GetSystemMetrics(SM_CXVSCROLL);
290 if (IsRectEmpty (&(info.rcScrollBar))) goto END;
292 if (Save_SCROLL_MovingThumb && (SCROLL_TrackingWin == hwnd) && (SCROLL_TrackingBar == nBar))
294 SCROLL_DrawMovingThumb (hdc, &(info.rcScrollBar), nBar, arrowSize, thumbSize, &info);
297 /* Draw the arrows */
298 if (arrows && arrowSize)
300 if (SCROLL_trackVertical == TRUE /* && GetCapture () == hwnd */)
302 SCROLL_DrawArrows (hdc, &info, &(info.rcScrollBar), arrowSize, nBar,
303 (SCROLL_trackHitTest == SCROLL_TOP_ARROW),
304 (SCROLL_trackHitTest == SCROLL_BOTTOM_ARROW));
308 SCROLL_DrawArrows (hdc, &info, &(info.rcScrollBar), arrowSize, nBar, FALSE, FALSE);
314 SCROLL_DrawInterior (hwnd, hdc, nBar, arrowSize, &info);
317 if (Save_SCROLL_MovingThumb &&
318 (SCROLL_TrackingWin == hwnd) && (SCROLL_TrackingBar == nBar))
319 SCROLL_DrawMovingThumb (hdc, &info.rcScrollBar, nBar, arrowSize, thumbSize, &info);
320 /* if scroll bar has focus, reposition the caret */
322 /* if (hwnd == GetFocus () && (nBar == SB_CTL))
326 SetCaretPos (info.dxyLineButton + 1, info.rcScrollBar.top + 1);
328 else if (nBAR == SB_VERT)
330 SetCaretPos (info.rcScrollBar.top + 1, info.dxyLineButton + 1);
334 /* WIN_ReleaseWndPtr(wndPtr); */
338 GetScrollInfo (HWND hwnd, int fnBar, LPSCROLLINFO lpsi)
345 GetScrollPos (HWND hWnd, int nBar)
352 GetScrollRange (HWND hWnd, int nBar, LPINT lpMinPos, LPINT lpMaxPos)
359 SetScrollInfo (HWND hwnd, int fnBar, LPCSCROLLINFO lpsi, WINBOOL fRedraw)
366 SetScrollPos (HWND hWnd, int nBar, int nPos, WINBOOL bRedraw)
373 SetScrollRange (HWND hWnd,
374 int nBar, int nMinPos, int nMaxPos, WINBOOL bRedraw)
380 /* Ported from WINE20020904 */
382 ShowScrollBar (HWND hWnd, int wBar, WINBOOL bShow)
384 NtUserShowScrollBar (hWnd, wBar, bShow);