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
, INT arrowsize
,
38 INT thumbpos
, INT thumbsize
, BOOL vertical
)
40 BOOL disabled
= !IsWindowEnabled(hwnd
);
44 theme
= bar
== SB_CTL
? GetWindowTheme(hwnd
) : OpenThemeData(NULL
, WC_SCROLLBARW
);
47 user_api
.pScrollBarDraw(hwnd
, dc
, bar
, hit_test
, tracking_info
, draw_arrows
, draw_interior
,
48 rect
, arrowsize
, thumbpos
, thumbsize
, vertical
);
52 style
= GetWindowLongW(hwnd
, GWL_STYLE
);
53 if (bar
== SB_CTL
&& (style
& SBS_SIZEBOX
|| style
& SBS_SIZEGRIP
)) {
56 if (style
& SBS_SIZEBOXTOPLEFTALIGN
)
57 state
= SZB_TOPLEFTALIGN
;
59 state
= SZB_RIGHTALIGN
;
61 if (IsThemeBackgroundPartiallyTransparent(theme
, SBP_SIZEBOX
, state
))
62 DrawThemeParentBackground(hwnd
, dc
, NULL
);
63 DrawThemeBackground(theme
, dc
, SBP_SIZEBOX
, state
, rect
, NULL
);
65 int uppertrackstate
, lowertrackstate
, thumbstate
;
70 uppertrackstate
= SCRBS_DISABLED
;
71 lowertrackstate
= SCRBS_DISABLED
;
72 thumbstate
= SCRBS_DISABLED
;
74 uppertrackstate
= SCRBS_NORMAL
;
75 lowertrackstate
= SCRBS_NORMAL
;
76 thumbstate
= SCRBS_NORMAL
;
78 if (vertical
== tracking_info
->vertical
&& hit_test
== tracking_info
->hit_test
79 && GetCapture() == hwnd
)
81 if (hit_test
== SCROLL_TOP_RECT
)
82 uppertrackstate
= SCRBS_PRESSED
;
83 else if (hit_test
== SCROLL_BOTTOM_RECT
)
84 lowertrackstate
= SCRBS_PRESSED
;
85 else if (hit_test
== SCROLL_THUMB
)
86 thumbstate
= SCRBS_PRESSED
;
90 if (hit_test
== SCROLL_TOP_RECT
)
91 uppertrackstate
= SCRBS_HOT
;
92 else if (hit_test
== SCROLL_BOTTOM_RECT
)
93 lowertrackstate
= SCRBS_HOT
;
94 else if (hit_test
== SCROLL_THUMB
)
95 thumbstate
= SCRBS_HOT
;
98 /* Thumb is also shown as pressed when tracking */
99 if (tracking_info
->win
== hwnd
&& tracking_info
->bar
== bar
)
100 thumbstate
= SCRBS_PRESSED
;
104 DrawThemeParentBackground(hwnd
, dc
, NULL
);
107 int uparrowstate
, downarrowstate
;
110 uparrowstate
= ABS_UPDISABLED
;
111 downarrowstate
= ABS_DOWNDISABLED
;
113 uparrowstate
= ABS_UPNORMAL
;
114 downarrowstate
= ABS_DOWNNORMAL
;
116 if (vertical
== tracking_info
->vertical
&& hit_test
== tracking_info
->hit_test
117 && GetCapture() == hwnd
)
119 if (hit_test
== SCROLL_TOP_ARROW
)
120 uparrowstate
= ABS_UPPRESSED
;
121 else if (hit_test
== SCROLL_BOTTOM_ARROW
)
122 downarrowstate
= ABS_DOWNPRESSED
;
126 if (hit_test
== SCROLL_TOP_ARROW
)
127 uparrowstate
= ABS_UPHOT
;
128 else if (hit_test
== SCROLL_BOTTOM_ARROW
)
129 downarrowstate
= ABS_DOWNHOT
;
134 partrect
.bottom
= partrect
.top
+ arrowsize
;
135 DrawThemeBackground(theme
, dc
, SBP_ARROWBTN
, uparrowstate
, &partrect
, NULL
);
137 partrect
.bottom
= rect
->bottom
;
138 partrect
.top
= partrect
.bottom
- arrowsize
;
139 DrawThemeBackground(theme
, dc
, SBP_ARROWBTN
, downarrowstate
, &partrect
, NULL
);
142 partrect
.top
= rect
->top
+ arrowsize
;
143 partrect
.bottom
= rect
->top
+ thumbpos
;
145 DrawThemeBackground(theme
, dc
, SBP_UPPERTRACKVERT
, uppertrackstate
, &partrect
, NULL
);
149 partrect
.top
= rect
->top
+ thumbpos
;
150 partrect
.bottom
= partrect
.top
+ thumbsize
;
152 DrawThemeBackground(theme
, dc
, SBP_THUMBBTNVERT
, thumbstate
, &partrect
, NULL
);
154 if (SUCCEEDED(GetThemePartSize(theme
, dc
, SBP_GRIPPERVERT
, thumbstate
, NULL
, TS_DRAW
, &grippersize
))) {
157 if (SUCCEEDED(GetThemeMargins(theme
, dc
, SBP_THUMBBTNVERT
, thumbstate
, TMT_CONTENTMARGINS
, &partrect
, &margins
))) {
158 if (grippersize
.cy
<= (thumbsize
- margins
.cyTopHeight
- margins
.cyBottomHeight
))
159 DrawThemeBackground(theme
, dc
, SBP_GRIPPERVERT
, thumbstate
, &partrect
, NULL
);
164 partrect
.bottom
= rect
->bottom
- arrowsize
;
166 partrect
.top
= rect
->top
+ thumbpos
+ thumbsize
;
168 partrect
.top
= rect
->top
+ arrowsize
;
169 if (partrect
.bottom
> partrect
.top
)
170 DrawThemeBackground(theme
, dc
, SBP_LOWERTRACKVERT
, lowertrackstate
, &partrect
, NULL
);
172 int leftarrowstate
, rightarrowstate
;
175 leftarrowstate
= ABS_LEFTDISABLED
;
176 rightarrowstate
= ABS_RIGHTDISABLED
;
178 leftarrowstate
= ABS_LEFTNORMAL
;
179 rightarrowstate
= ABS_RIGHTNORMAL
;
181 if (vertical
== tracking_info
->vertical
&& hit_test
== tracking_info
->hit_test
182 && GetCapture() == hwnd
)
184 if (hit_test
== SCROLL_TOP_ARROW
)
185 leftarrowstate
= ABS_LEFTPRESSED
;
186 else if (hit_test
== SCROLL_BOTTOM_ARROW
)
187 rightarrowstate
= ABS_RIGHTPRESSED
;
191 if (hit_test
== SCROLL_TOP_ARROW
)
192 leftarrowstate
= ABS_LEFTHOT
;
193 else if (hit_test
== SCROLL_BOTTOM_ARROW
)
194 rightarrowstate
= ABS_RIGHTHOT
;
199 partrect
.right
= partrect
.left
+ arrowsize
;
200 DrawThemeBackground(theme
, dc
, SBP_ARROWBTN
, leftarrowstate
, &partrect
, NULL
);
202 partrect
.right
= rect
->right
;
203 partrect
.left
= partrect
.right
- arrowsize
;
204 DrawThemeBackground(theme
, dc
, SBP_ARROWBTN
, rightarrowstate
, &partrect
, NULL
);
207 partrect
.left
= rect
->left
+ arrowsize
;
208 partrect
.right
= rect
->left
+ thumbpos
;
210 DrawThemeBackground(theme
, dc
, SBP_UPPERTRACKHORZ
, uppertrackstate
, &partrect
, NULL
);
214 partrect
.left
= rect
->left
+ thumbpos
;
215 partrect
.right
= partrect
.left
+ thumbsize
;
217 DrawThemeBackground(theme
, dc
, SBP_THUMBBTNHORZ
, thumbstate
, &partrect
, NULL
);
219 if (SUCCEEDED(GetThemePartSize(theme
, dc
, SBP_GRIPPERHORZ
, thumbstate
, NULL
, TS_DRAW
, &grippersize
))) {
222 if (SUCCEEDED(GetThemeMargins(theme
, dc
, SBP_THUMBBTNHORZ
, thumbstate
, TMT_CONTENTMARGINS
, &partrect
, &margins
))) {
223 if (grippersize
.cx
<= (thumbsize
- margins
.cxLeftWidth
- margins
.cxRightWidth
))
224 DrawThemeBackground(theme
, dc
, SBP_GRIPPERHORZ
, thumbstate
, &partrect
, NULL
);
229 partrect
.right
= rect
->right
- arrowsize
;
231 partrect
.left
= rect
->left
+ thumbpos
+ thumbsize
;
233 partrect
.left
= rect
->left
+ arrowsize
;
234 if (partrect
.right
> partrect
.left
)
235 DrawThemeBackground(theme
, dc
, SBP_LOWERTRACKHORZ
, lowertrackstate
, &partrect
, NULL
);
240 CloseThemeData(theme
);
243 LRESULT WINAPI
UXTHEME_ScrollbarWndProc(HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
,
246 const WCHAR
* themeClass
= WC_SCROLLBARW
;
250 TRACE("(%p, 0x%x, %lu, %lu, %d)\n", hwnd
, msg
, wParam
, lParam
, unicode
);
254 result
= user_api
.pScrollBarWndProc(hwnd
, msg
, wParam
, lParam
, unicode
);
255 OpenThemeData(hwnd
, themeClass
);
259 theme
= GetWindowTheme(hwnd
);
260 CloseThemeData(theme
);
261 return user_api
.pScrollBarWndProc(hwnd
, msg
, wParam
, lParam
, unicode
);
263 case WM_THEMECHANGED
:
264 theme
= GetWindowTheme(hwnd
);
265 CloseThemeData(theme
);
266 OpenThemeData(hwnd
, themeClass
);
267 InvalidateRect(hwnd
, NULL
, TRUE
);
270 case WM_SYSCOLORCHANGE
:
271 theme
= GetWindowTheme(hwnd
);
272 if (!theme
) return user_api
.pScrollBarWndProc(hwnd
, msg
, wParam
, lParam
, unicode
);
273 /* Do nothing. When themed, a WM_THEMECHANGED will be received, too,
274 * which will do the repaint. */
278 return user_api
.pScrollBarWndProc(hwnd
, msg
, wParam
, lParam
, unicode
);