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 ******************************************************************/
17 /* GLOBAL VARIABLES **********************************************************/
19 static HBITMAP hUpArrow;
20 static HBITMAP hDnArrow;
21 static HBITMAP hLfArrow;
22 static HBITMAP hRgArrow;
23 static HBITMAP hUpArrowD;
24 static HBITMAP hDnArrowD;
25 static HBITMAP hLfArrowD;
26 static HBITMAP hRgArrowD;
27 static HBITMAP hUpArrowI;
28 static HBITMAP hDnArrowI;
29 static HBITMAP hLfArrowI;
30 static HBITMAP hRgArrowI;
32 #define TOP_ARROW(flags,pressed) \
33 (((flags)&ESB_DISABLE_UP) ? hUpArrowI : ((pressed) ? hUpArrowD:hUpArrow))
34 #define BOTTOM_ARROW(flags,pressed) \
35 (((flags)&ESB_DISABLE_DOWN) ? hDnArrowI : ((pressed) ? hDnArrowD:hDnArrow))
36 #define LEFT_ARROW(flags,pressed) \
37 (((flags)&ESB_DISABLE_LEFT) ? hLfArrowI : ((pressed) ? hLfArrowD:hLfArrow))
38 #define RIGHT_ARROW(flags,pressed) \
39 (((flags)&ESB_DISABLE_RIGHT) ? hRgArrowI : ((pressed) ? hRgArrowD:hRgArrow))
41 #define SCROLL_ARROW_THUMB_OVERLAP 0 /* Overlap between arrows and thumb */
42 #define SCROLL_MIN_THUMB 6 /* Minimum size of the thumb in pixels */
43 #define SCROLL_FIRST_DELAY 200 /* Delay (in ms) before first repetition when holding the button down */
44 #define SCROLL_REPEAT_DELAY 50 /* Delay (in ms) between scroll repetitions */
45 #define SCROLL_TIMER 0 /* Scroll timer id */
47 /* What to do after SCROLL_SetScrollInfo() */
48 #define SA_SSI_HIDE 0x0001
49 #define SA_SSI_SHOW 0x0002
50 #define SA_SSI_REFRESH 0x0004
51 #define SA_SSI_REPAINT_ARROWS 0x0008
53 /* Scroll-bar hit testing */
56 SCROLL_NOWHERE, /* Outside the scroll bar */
57 SCROLL_TOP_ARROW, /* Top or left arrow */
58 SCROLL_TOP_RECT, /* Rectangle between the top arrow and the thumb */
59 SCROLL_THUMB, /* Thumb rectangle */
60 SCROLL_BOTTOM_RECT, /* Rectangle between the thumb and the bottom arrow */
61 SCROLL_BOTTOM_ARROW /* Bottom or right arrow */
64 static BOOL SCROLL_MovingThumb = FALSE; /* Is the moving thumb being displayed? */
66 /* Thumb-tracking info */
67 static HWND SCROLL_TrackingWin = 0;
68 static INT SCROLL_TrackingBar = 0;
69 static INT SCROLL_TrackingPos = 0;
70 /* static INT SCROLL_TrackingVal = 0; */
71 static enum SCROLL_HITTEST SCROLL_trackHitTest; /* Hit test code of the last button-down event */
72 static BOOL SCROLL_trackVertical;
75 *****************************************************************/
77 HBRUSH DefWndControlColor (HDC hDC, UINT ctlType);
78 HPEN STDCALL GetSysColorPen (int nIndex);
83 GetScrollBarInfo (HWND hwnd, LONG idObject, PSCROLLBARINFO psbi)
85 int ret = NtUserGetScrollBarInfo (hwnd, idObject, psbi);
90 /* Ported from WINE20020904 */
91 /* Draw the scroll bar interior (everything except the arrows). */
93 SCROLL_DrawInterior (HWND hwnd, HDC hdc, INT nBar, BOOL vertical, INT
94 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
114 if ( nBar == SB_CTL )
116 hBrush = (HBRUSH) NtUserSendMessage (GetParent (hwnd), WM_CTLCOLORSCROLLBAR, (WPARAM) hdc, (LPARAM) hwnd);
120 /* hBrush = NtUserGetControlColor (hdc, CTLCOLOR_SCROLLBAR); FIXME
121 */ /* 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);
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;
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, BOOL vertical, int arrowSize, int thumbSize, PSCROLLBARINFO psbi)
203 INT pos = SCROLL_TrackingPos;
207 max_size = psbi->rcScrollBar.bottom - psbi->rcScrollBar.top;
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, vertical, 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, BOOL vertical,
228 BOOL top_pressed, BOOL bottom_pressed)
231 int scrollDirFlag1, scrollDirFlag2;
236 scrollDirFlag1 = DFCS_SCROLLUP;
237 scrollDirFlag2 = DFCS_SCROLLDOWN;
238 r1.bottom = r1.top + arrowSize;
239 r2.top = r2.bottom - arrowSize;
243 scrollDirFlag1 = DFCS_SCROLLLEFT;
244 scrollDirFlag2 = DFCS_SCROLLRIGHT;
245 r1.right = r1.left + arrowSize;
246 r2.left = r2.right - arrowSize;
249 DrawFrameControl (hdc, &r1, DFC_SCROLL,
250 scrollDirFlag1 | (top_pressed ? (DFCS_PUSHED | DFCS_FLAT) : 0)
251 /* | (info.flags&ESB_DISABLE_LTUP ? DFCS_INACTIVE : 0) */
253 DrawFrameControl (hdc, &r2, DFC_SCROLL,
254 scrollDirFlag2 | (bottom_pressed ? (DFCS_PUSHED | DFCS_FLAT) : 0)
255 /* | (info.flags&ESB_DISABLE_RTDN ? DFCS_INACTIVE : 0) */
259 /* Ported from WINE20020904 */
260 /* Redraw the whole scrollbar. */
262 SCROLL_DrawScrollBar (HWND hwnd, HDC hdc, INT nBar,
263 BOOL arrows, BOOL interior)
268 BOOL Save_SCROLL_MovingThumb = SCROLL_MovingThumb;
271 info.cbSize = sizeof(SCROLLBARINFO);
272 GetScrollBarInfo (hwnd, nBar, &info);
274 thumbSize = info.xyThumbBottom - info.xyThumbTop;
285 vertical = (GetWindowLong(hwnd,GWL_STYLE)&SBS_VERT) != 0;
289 DASSERT(!"SCROLL_DrawScrollBar() called with invalid nBar");
295 arrowSize = GetSystemMetrics(SM_CXVSCROLL);
297 arrowSize = GetSystemMetrics(SM_CYHSCROLL);
299 if (IsRectEmpty (&(info.rcScrollBar))) goto END;
301 if (Save_SCROLL_MovingThumb && (SCROLL_TrackingWin == hwnd) && (SCROLL_TrackingBar == nBar))
303 SCROLL_DrawMovingThumb (hdc, &(info.rcScrollBar), vertical, arrowSize, thumbSize, &info);
306 /* Draw the arrows */
307 if (arrows && arrowSize)
309 if (SCROLL_trackVertical == TRUE /* && GetCapture () == hwnd */)
311 SCROLL_DrawArrows (hdc, &info, &(info.rcScrollBar), arrowSize, vertical,
312 (SCROLL_trackHitTest == SCROLL_TOP_ARROW),
313 (SCROLL_trackHitTest == SCROLL_BOTTOM_ARROW));
317 SCROLL_DrawArrows (hdc, &info, &(info.rcScrollBar), arrowSize, vertical, FALSE, FALSE);
323 SCROLL_DrawInterior (hwnd, hdc, nBar, vertical, arrowSize, &info);
326 if (Save_SCROLL_MovingThumb &&
327 (SCROLL_TrackingWin == hwnd) && (SCROLL_TrackingBar == nBar))
328 SCROLL_DrawMovingThumb (hdc, &info.rcScrollBar, vertical, arrowSize, thumbSize, &info);
329 /* if scroll bar has focus, reposition the caret */
331 /* if (hwnd == GetFocus () && (nBar == SB_CTL))
335 SetCaretPos (info.dxyLineButton + 1, info.rcScrollBar.top + 1);
337 else if (nBAR == SB_VERT)
339 SetCaretPos (info.rcScrollBar.top + 1, info.dxyLineButton + 1);
343 /* WIN_ReleaseWndPtr(wndPtr); */
347 GetScrollInfo (HWND hwnd, int fnBar, LPSCROLLINFO lpsi)
354 GetScrollPos (HWND hWnd, int nBar)
361 GetScrollRange (HWND hWnd, int nBar, LPINT lpMinPos, LPINT lpMaxPos)
368 SetScrollInfo (HWND hwnd, int fnBar, LPCSCROLLINFO lpsi, WINBOOL fRedraw)
375 SetScrollPos (HWND hWnd, int nBar, int nPos, WINBOOL bRedraw)
382 SetScrollRange (HWND hWnd,
383 int nBar, int nMinPos, int nMaxPos, WINBOOL bRedraw)
389 /* Ported from WINE20020904 */
391 ShowScrollBar (HWND hWnd, int wBar, WINBOOL bShow)
393 NtUserShowScrollBar (hWnd, wBar, bShow);