2 * Theming - Scrollbar control
4 * Copyright (c) 2015 Mark Harmstone
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
29 #include "uxthemedll.h"
31 #include "wine/debug.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(theme_scroll
);
35 void WINAPI
UXTHEME_ScrollBarDraw(HWND hwnd
, HDC dc
, INT bar
, enum SCROLL_HITTEST hit_test
,
36 const struct SCROLL_TRACKING_INFO
*tracking_info
,
37 BOOL draw_arrows
, BOOL draw_interior
, RECT
*rect
, UINT enable_flags
,
38 INT arrowsize
, INT thumbpos
, INT thumbsize
, BOOL vertical
)
40 BOOL disabled
= !IsWindowEnabled(hwnd
);
45 theme
= GetWindowTheme(hwnd
);
47 theme
= OpenThemeDataForDpi(NULL
, WC_SCROLLBARW
, GetDpiForWindow(hwnd
));
51 user_api
.pScrollBarDraw(hwnd
, dc
, bar
, hit_test
, tracking_info
, draw_arrows
, draw_interior
,
52 rect
, enable_flags
, arrowsize
, thumbpos
, thumbsize
, vertical
);
56 style
= GetWindowLongW(hwnd
, GWL_STYLE
);
57 if (bar
== SB_CTL
&& (style
& SBS_SIZEBOX
|| style
& SBS_SIZEGRIP
)) {
60 if (style
& SBS_SIZEBOXTOPLEFTALIGN
)
61 state
= SZB_TOPLEFTALIGN
;
63 state
= SZB_RIGHTALIGN
;
65 /* Tests show that COLOR_BTNFACE is used instead of DrawThemeParentBackground() for drawing
67 FillRect(dc
, rect
, GetSysColorBrush(COLOR_BTNFACE
));
68 DrawThemeBackground(theme
, dc
, SBP_SIZEBOX
, state
, rect
, NULL
);
70 int uppertrackstate
, lowertrackstate
, thumbstate
;
71 HBRUSH track_brush
= NULL
;
76 track_brush
= (HBRUSH
)SendMessageW(GetParent(hwnd
), WM_CTLCOLORSCROLLBAR
, (WPARAM
)dc
, (LPARAM
)hwnd
);
79 uppertrackstate
= SCRBS_DISABLED
;
80 lowertrackstate
= SCRBS_DISABLED
;
81 thumbstate
= SCRBS_DISABLED
;
83 uppertrackstate
= SCRBS_NORMAL
;
84 lowertrackstate
= SCRBS_NORMAL
;
85 thumbstate
= SCRBS_NORMAL
;
87 if (vertical
== tracking_info
->vertical
&& hit_test
== tracking_info
->hit_test
88 && GetCapture() == hwnd
)
90 if (hit_test
== SCROLL_TOP_RECT
)
91 uppertrackstate
= SCRBS_PRESSED
;
92 else if (hit_test
== SCROLL_BOTTOM_RECT
)
93 lowertrackstate
= SCRBS_PRESSED
;
94 else if (hit_test
== SCROLL_THUMB
)
95 thumbstate
= SCRBS_PRESSED
;
99 if (hit_test
== SCROLL_TOP_RECT
)
100 uppertrackstate
= SCRBS_HOT
;
101 else if (hit_test
== SCROLL_BOTTOM_RECT
)
102 lowertrackstate
= SCRBS_HOT
;
103 else if (hit_test
== SCROLL_THUMB
)
104 thumbstate
= SCRBS_HOT
;
107 /* Thumb is also shown as pressed when tracking */
108 if (tracking_info
->win
== hwnd
&& tracking_info
->bar
== bar
)
109 thumbstate
= SCRBS_PRESSED
;
113 int uparrowstate
, downarrowstate
;
116 uparrowstate
= ABS_UPDISABLED
;
117 downarrowstate
= ABS_DOWNDISABLED
;
119 uparrowstate
= ABS_UPNORMAL
;
120 downarrowstate
= ABS_DOWNNORMAL
;
122 if (vertical
== tracking_info
->vertical
&& hit_test
== tracking_info
->hit_test
123 && GetCapture() == hwnd
)
125 if (hit_test
== SCROLL_TOP_ARROW
)
126 uparrowstate
= ABS_UPPRESSED
;
127 else if (hit_test
== SCROLL_BOTTOM_ARROW
)
128 downarrowstate
= ABS_DOWNPRESSED
;
132 if (hit_test
== SCROLL_TOP_ARROW
)
133 uparrowstate
= ABS_UPHOT
;
134 else if (hit_test
== SCROLL_BOTTOM_ARROW
)
135 downarrowstate
= ABS_DOWNHOT
;
140 partrect
.bottom
= partrect
.top
+ arrowsize
;
141 DrawThemeBackground(theme
, dc
, SBP_ARROWBTN
, uparrowstate
, &partrect
, NULL
);
143 partrect
.bottom
= rect
->bottom
;
144 partrect
.top
= partrect
.bottom
- arrowsize
;
145 DrawThemeBackground(theme
, dc
, SBP_ARROWBTN
, downarrowstate
, &partrect
, NULL
);
148 partrect
.top
= rect
->top
+ arrowsize
;
149 partrect
.bottom
= rect
->top
+ thumbpos
;
151 if (bar
== SB_CTL
&& track_brush
)
152 FillRect(dc
, &partrect
, track_brush
);
154 DrawThemeBackground(theme
, dc
, SBP_UPPERTRACKVERT
, uppertrackstate
, &partrect
, NULL
);
158 partrect
.top
= rect
->top
+ thumbpos
;
159 partrect
.bottom
= partrect
.top
+ thumbsize
;
160 DrawThemeBackground(theme
, dc
, SBP_THUMBBTNVERT
, thumbstate
, &partrect
, NULL
);
162 if (SUCCEEDED(GetThemePartSize(theme
, dc
, SBP_GRIPPERVERT
, thumbstate
, NULL
, TS_DRAW
, &grippersize
))) {
165 if (SUCCEEDED(GetThemeMargins(theme
, dc
, SBP_THUMBBTNVERT
, thumbstate
, TMT_CONTENTMARGINS
, &partrect
, &margins
))) {
166 if (grippersize
.cy
<= (thumbsize
- margins
.cyTopHeight
- margins
.cyBottomHeight
))
167 DrawThemeBackground(theme
, dc
, SBP_GRIPPERVERT
, thumbstate
, &partrect
, NULL
);
172 partrect
.bottom
= rect
->bottom
- arrowsize
;
174 partrect
.top
= rect
->top
+ thumbpos
+ thumbsize
;
176 partrect
.top
= rect
->top
+ arrowsize
;
177 if (partrect
.bottom
> partrect
.top
)
179 if (bar
== SB_CTL
&& track_brush
)
180 FillRect(dc
, &partrect
, track_brush
);
182 DrawThemeBackground(theme
, dc
, SBP_LOWERTRACKVERT
, lowertrackstate
, &partrect
, NULL
);
185 int leftarrowstate
, rightarrowstate
;
188 leftarrowstate
= ABS_LEFTDISABLED
;
189 rightarrowstate
= ABS_RIGHTDISABLED
;
191 leftarrowstate
= ABS_LEFTNORMAL
;
192 rightarrowstate
= ABS_RIGHTNORMAL
;
194 if (vertical
== tracking_info
->vertical
&& hit_test
== tracking_info
->hit_test
195 && GetCapture() == hwnd
)
197 if (hit_test
== SCROLL_TOP_ARROW
)
198 leftarrowstate
= ABS_LEFTPRESSED
;
199 else if (hit_test
== SCROLL_BOTTOM_ARROW
)
200 rightarrowstate
= ABS_RIGHTPRESSED
;
204 if (hit_test
== SCROLL_TOP_ARROW
)
205 leftarrowstate
= ABS_LEFTHOT
;
206 else if (hit_test
== SCROLL_BOTTOM_ARROW
)
207 rightarrowstate
= ABS_RIGHTHOT
;
212 partrect
.right
= partrect
.left
+ arrowsize
;
213 DrawThemeBackground(theme
, dc
, SBP_ARROWBTN
, leftarrowstate
, &partrect
, NULL
);
215 partrect
.right
= rect
->right
;
216 partrect
.left
= partrect
.right
- arrowsize
;
217 DrawThemeBackground(theme
, dc
, SBP_ARROWBTN
, rightarrowstate
, &partrect
, NULL
);
220 partrect
.left
= rect
->left
+ arrowsize
;
221 partrect
.right
= rect
->left
+ thumbpos
;
223 if (bar
== SB_CTL
&& track_brush
)
224 FillRect(dc
, &partrect
, track_brush
);
226 DrawThemeBackground(theme
, dc
, SBP_UPPERTRACKHORZ
, uppertrackstate
, &partrect
, NULL
);
230 partrect
.left
= rect
->left
+ thumbpos
;
231 partrect
.right
= partrect
.left
+ thumbsize
;
232 DrawThemeBackground(theme
, dc
, SBP_THUMBBTNHORZ
, thumbstate
, &partrect
, NULL
);
234 if (SUCCEEDED(GetThemePartSize(theme
, dc
, SBP_GRIPPERHORZ
, thumbstate
, NULL
, TS_DRAW
, &grippersize
))) {
237 if (SUCCEEDED(GetThemeMargins(theme
, dc
, SBP_THUMBBTNHORZ
, thumbstate
, TMT_CONTENTMARGINS
, &partrect
, &margins
))) {
238 if (grippersize
.cx
<= (thumbsize
- margins
.cxLeftWidth
- margins
.cxRightWidth
))
239 DrawThemeBackground(theme
, dc
, SBP_GRIPPERHORZ
, thumbstate
, &partrect
, NULL
);
244 partrect
.right
= rect
->right
- arrowsize
;
246 partrect
.left
= rect
->left
+ thumbpos
+ thumbsize
;
248 partrect
.left
= rect
->left
+ arrowsize
;
249 if (partrect
.right
> partrect
.left
)
251 if (bar
== SB_CTL
&& track_brush
)
252 FillRect(dc
, &partrect
, track_brush
);
254 DrawThemeBackground(theme
, dc
, SBP_LOWERTRACKHORZ
, lowertrackstate
, &partrect
, NULL
);
260 CloseThemeData(theme
);
263 LRESULT WINAPI
UXTHEME_ScrollbarWndProc(HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
,
266 const WCHAR
* themeClass
= WC_SCROLLBARW
;
270 TRACE("(%p, 0x%x, %Iu, %Iu, %d)\n", hwnd
, msg
, wParam
, lParam
, unicode
);
274 result
= user_api
.pScrollBarWndProc(hwnd
, msg
, wParam
, lParam
, unicode
);
275 OpenThemeData(hwnd
, themeClass
);
279 theme
= GetWindowTheme(hwnd
);
280 CloseThemeData(theme
);
281 return user_api
.pScrollBarWndProc(hwnd
, msg
, wParam
, lParam
, unicode
);
283 case WM_THEMECHANGED
:
284 theme
= GetWindowTheme(hwnd
);
285 CloseThemeData(theme
);
286 OpenThemeData(hwnd
, themeClass
);
287 InvalidateRect(hwnd
, NULL
, TRUE
);
290 case WM_SYSCOLORCHANGE
:
291 theme
= GetWindowTheme(hwnd
);
292 if (!theme
) return user_api
.pScrollBarWndProc(hwnd
, msg
, wParam
, lParam
, unicode
);
293 /* Do nothing. When themed, a WM_THEMECHANGED will be received, too,
294 * which will do the repaint. */
298 return user_api
.pScrollBarWndProc(hwnd
, msg
, wParam
, lParam
, unicode
);