1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef UI_NATIVE_THEME_NATIVE_THEME_WIN_H_
6 #define UI_NATIVE_THEME_NATIVE_THEME_WIN_H_
8 // A wrapper class for working with custom XP/Vista themes provided in
9 // uxtheme.dll. This is a singleton class that can be grabbed using
10 // NativeThemeWin::instance().
11 // For more information on visual style parts and states, see:
12 // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/commctls/userex/topics/partsandstates.asp
19 #include "base/basictypes.h"
20 #include "base/compiler_specific.h"
21 #include "third_party/skia/include/core/SkColor.h"
22 #include "ui/gfx/geometry/size.h"
23 #include "ui/gfx/sys_color_change_listener.h"
24 #include "ui/native_theme/native_theme.h"
30 // Windows implementation of native theme class.
32 // At the moment, this class in in transition from an older API that consists
33 // of several PaintXXX methods to an API, inherited from the NativeTheme base
34 // class, that consists of a single Paint() method with a argument to indicate
35 // what kind of part to paint.
36 class NATIVE_THEME_EXPORT NativeThemeWin
: public NativeTheme
,
37 public gfx::SysColorChangeListener
{
55 bool IsThemingActive() const;
57 // Returns true if a high contrast theme is being used.
58 bool IsUsingHighContrastTheme() const;
60 HRESULT
GetThemeColor(ThemeName theme
,
64 SkColor
* color
) const;
66 // Get the theme color if theming is enabled. If theming is unsupported
67 // for this part, use Win32's GetSysColor to find the color specified
68 // by default_sys_color.
69 SkColor
GetThemeColorWithDefault(ThemeName theme
,
73 int default_sys_color
) const;
75 // Get the thickness of the border associated with the specified theme,
76 // defaulting to GetSystemMetrics edge size if themes are disabled.
77 // In Classic Windows, borders are typically 2px; on XP+, they are 1px.
78 gfx::Size
GetThemeBorderSize(ThemeName theme
) const;
80 // Disables all theming for top-level windows in the entire process, from
81 // when this method is called until the process exits. All the other
82 // methods in this class will continue to work, but their output will ignore
83 // the user's theme. This is meant for use when running tests that require
84 // consistent visual results.
85 void DisableTheming() const;
87 // Closes cached theme handles so we can unload the DLL or update our UI
88 // for a theme change.
89 void CloseHandles() const;
91 // Returns true if classic theme is in use.
92 bool IsClassicTheme(ThemeName name
) const;
94 // Gets our singleton instance.
95 static NativeThemeWin
* instance();
97 HRESULT
PaintTextField(HDC hdc
,
103 bool fill_content_area
,
104 bool draw_edges
) const;
106 // NativeTheme implementation:
107 gfx::Size
GetPartSize(Part part
,
109 const ExtraParams
& extra
) const override
;
110 void Paint(SkCanvas
* canvas
,
113 const gfx::Rect
& rect
,
114 const ExtraParams
& extra
) const override
;
115 SkColor
GetSystemColor(ColorId color_id
) const override
;
119 ~NativeThemeWin() override
;
121 // gfx::SysColorChangeListener implementation:
122 void OnSysColorChange() override
;
124 // Update the locally cached set of system colors.
125 void UpdateSystemColors();
127 // Paint directly to canvas' HDC.
128 void PaintDirect(SkCanvas
* canvas
,
131 const gfx::Rect
& rect
,
132 const ExtraParams
& extra
) const;
134 // Create a temporary HDC, paint to that, clean up the alpha values in the
135 // temporary HDC, and then blit the result to canvas. This is to work around
136 // the fact that Windows XP and some classic themes give bogus alpha values.
137 void PaintIndirect(SkCanvas
* canvas
,
140 const gfx::Rect
& rect
,
141 const ExtraParams
& extra
) const;
143 HRESULT
GetThemePartSize(ThemeName themeName
,
151 HRESULT
PaintButton(HDC hdc
,
153 const ButtonExtraParams
& extra
,
158 HRESULT
PaintMenuSeparator(HDC hdc
,
159 const gfx::Rect
& rect
) const;
161 HRESULT
PaintMenuGutter(HDC hdc
, const gfx::Rect
& rect
) const;
163 // |arrow_direction| determines whether the arrow is pointing to the left or
164 // to the right. In RTL locales, sub-menus open from right to left and
165 // therefore the menu arrow should point to the left and not to the right.
166 HRESULT
PaintMenuArrow(HDC hdc
,
168 const gfx::Rect
& rect
,
169 const MenuArrowExtraParams
& extra
) const;
171 HRESULT
PaintMenuBackground(HDC hdc
, const gfx::Rect
& rect
) const;
173 HRESULT
PaintMenuCheck(HDC hdc
,
175 const gfx::Rect
& rect
,
176 const MenuCheckExtraParams
& extra
) const;
178 HRESULT
PaintMenuCheckBackground(HDC hdc
,
180 const gfx::Rect
& rect
) const;
182 HRESULT
PaintMenuItemBackground(HDC hdc
,
184 const gfx::Rect
& rect
,
185 const MenuItemExtraParams
& extra
) const;
187 HRESULT
PaintPushButton(HDC hdc
,
190 const gfx::Rect
& rect
,
191 const ButtonExtraParams
& extra
) const;
193 HRESULT
PaintRadioButton(HDC hdc
,
196 const gfx::Rect
& rect
,
197 const ButtonExtraParams
& extra
) const;
199 HRESULT
PaintCheckbox(HDC hdc
,
202 const gfx::Rect
& rect
,
203 const ButtonExtraParams
& extra
) const;
205 HRESULT
PaintMenuList(HDC hdc
,
207 const gfx::Rect
& rect
,
208 const MenuListExtraParams
& extra
) const;
210 // Paints a scrollbar arrow. |classic_state| should have the appropriate
211 // classic part number ORed in already.
212 HRESULT
PaintScrollbarArrow(HDC hdc
,
215 const gfx::Rect
& rect
,
216 const ScrollbarArrowExtraParams
& extra
) const;
218 HRESULT
PaintScrollbarThumb(HDC hdc
,
221 const gfx::Rect
& rect
,
222 const ScrollbarThumbExtraParams
& extra
) const;
224 // This method is deprecated and will be removed in the near future.
225 // Paints a scrollbar track section. |align_rect| is only used in classic
226 // mode, and makes sure the checkerboard pattern in |target_rect| is aligned
227 // with one presumed to be in |align_rect|.
228 HRESULT
PaintScrollbarTrack(SkCanvas
* canvas
,
232 const gfx::Rect
& rect
,
233 const ScrollbarTrackExtraParams
& extra
) const;
235 HRESULT
PaintSpinButton(HDC hdc
,
238 const gfx::Rect
& rect
,
239 const InnerSpinButtonExtraParams
& extra
) const;
241 HRESULT
PaintTrackbar(SkCanvas
* canvas
,
245 const gfx::Rect
& rect
,
246 const TrackbarExtraParams
& extra
) const;
248 HRESULT
PaintProgressBar(HDC hdc
,
249 const gfx::Rect
& rect
,
250 const ProgressBarExtraParams
& extra
) const;
252 HRESULT
PaintWindowResizeGripper(HDC hdc
, const gfx::Rect
& rect
) const;
254 HRESULT
PaintTabPanelBackground(HDC hdc
, const gfx::Rect
& rect
) const;
256 HRESULT
PaintTextField(HDC hdc
,
259 const gfx::Rect
& rect
,
260 const TextFieldExtraParams
& extra
) const;
262 // Paints a theme part, with support for scene scaling in high-DPI mode.
263 // |theme| is the theme handle. |hdc| is the handle for the device context.
264 // |part_id| is the identifier for the part (e.g. thumb gripper). |state_id|
265 // is the identifier for the rendering state of the part (e.g. hover). |rect|
266 // is the bounds for rendering, expressed in logical coordinates.
267 HRESULT
PaintScaledTheme(HANDLE theme
,
271 const gfx::Rect
& rect
) const;
273 // Get the windows theme name/part/state. These three helper functions are
274 // used only by GetPartSize(), as each of the corresponding PaintXXX()
275 // methods do further validation of the part and state that is required for
277 static ThemeName
GetThemeName(Part part
);
278 static int GetWindowsPart(Part part
, State state
, const ExtraParams
& extra
);
279 static int GetWindowsState(Part part
, State state
, const ExtraParams
& extra
);
281 HRESULT
GetThemeInt(ThemeName theme
,
287 HRESULT
PaintFrameControl(HDC hdc
,
288 const gfx::Rect
& rect
,
292 State control_state
) const;
294 // Returns a handle to the theme data.
295 HANDLE
GetThemeHandle(ThemeName theme_name
) const;
297 typedef HRESULT (WINAPI
* DrawThemeBackgroundPtr
)(HANDLE theme
,
302 const RECT
* clip_rect
);
303 typedef HRESULT (WINAPI
* DrawThemeBackgroundExPtr
)(HANDLE theme
,
308 const DTBGOPTS
* opts
);
309 typedef HRESULT (WINAPI
* GetThemeColorPtr
)(HANDLE hTheme
,
314 typedef HRESULT (WINAPI
* GetThemeContentRectPtr
)(HANDLE hTheme
,
320 typedef HRESULT (WINAPI
* GetThemePartSizePtr
)(HANDLE hTheme
,
327 typedef HANDLE (WINAPI
* OpenThemeDataPtr
)(HWND window
,
329 typedef HRESULT (WINAPI
* CloseThemeDataPtr
)(HANDLE theme
);
331 typedef void (WINAPI
* SetThemeAppPropertiesPtr
) (DWORD flags
);
332 typedef BOOL (WINAPI
* IsThemeActivePtr
)();
333 typedef HRESULT (WINAPI
* GetThemeIntPtr
)(HANDLE hTheme
,
339 // Function pointers into uxtheme.dll.
340 DrawThemeBackgroundPtr draw_theme_
;
341 DrawThemeBackgroundExPtr draw_theme_ex_
;
342 GetThemeColorPtr get_theme_color_
;
343 GetThemeContentRectPtr get_theme_content_rect_
;
344 GetThemePartSizePtr get_theme_part_size_
;
345 OpenThemeDataPtr open_theme_
;
346 CloseThemeDataPtr close_theme_
;
347 SetThemeAppPropertiesPtr set_theme_properties_
;
348 IsThemeActivePtr is_theme_active_
;
349 GetThemeIntPtr get_theme_int_
;
351 // Handle to uxtheme.dll.
354 // A cache of open theme handles.
355 mutable HANDLE theme_handles_
[LAST
];
357 // The system color change listener and the updated cache of system colors.
358 gfx::ScopedSysColorChangeListener color_change_listener_
;
359 mutable std::map
<int, SkColor
> system_colors_
;
361 // Is a high contrast theme active?
362 mutable bool is_using_high_contrast_
;
364 // Is |is_using_high_contrast_| valid?
365 mutable bool is_using_high_contrast_valid_
;
367 DISALLOW_COPY_AND_ASSIGN(NativeThemeWin
);
372 #endif // UI_NATIVE_THEME_NATIVE_THEME_WIN_H_