native_theme_win.h 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  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.
  4. #ifndef UI_NATIVE_THEME_NATIVE_THEME_WIN_H_
  5. #define UI_NATIVE_THEME_NATIVE_THEME_WIN_H_
  6. // A wrapper class for working with custom XP/Vista themes provided in
  7. // uxtheme.dll. This is a singleton class that can be grabbed using
  8. // NativeThemeWin::instance().
  9. // For more information on visual style parts and states, see:
  10. // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/commctls/userex/topics/partsandstates.asp
  11. #include <windows.h>
  12. #include "base/no_destructor.h"
  13. #include "base/win/registry.h"
  14. #include "third_party/abseil-cpp/absl/types/optional.h"
  15. #include "third_party/skia/include/core/SkColor.h"
  16. #include "ui/gfx/geometry/size.h"
  17. #include "ui/gfx/sys_color_change_listener.h"
  18. #include "ui/native_theme/native_theme.h"
  19. class SkCanvas;
  20. namespace ui {
  21. // Windows implementation of native theme class.
  22. //
  23. // At the moment, this class in in transition from an older API that consists
  24. // of several PaintXXX methods to an API, inherited from the NativeTheme base
  25. // class, that consists of a single Paint() method with a argument to indicate
  26. // what kind of part to paint.
  27. class NATIVE_THEME_EXPORT NativeThemeWin : public NativeTheme,
  28. public gfx::SysColorChangeListener {
  29. public:
  30. enum ThemeName {
  31. BUTTON,
  32. LIST,
  33. MENU,
  34. MENULIST,
  35. SCROLLBAR,
  36. STATUS,
  37. TAB,
  38. TEXTFIELD,
  39. TRACKBAR,
  40. WINDOW,
  41. PROGRESS,
  42. SPIN,
  43. LAST
  44. };
  45. NativeThemeWin(const NativeThemeWin&) = delete;
  46. NativeThemeWin& operator=(const NativeThemeWin&) = delete;
  47. // Closes cached theme handles so we can unload the DLL or update our UI
  48. // for a theme change.
  49. static void CloseHandles();
  50. // NativeTheme implementation:
  51. gfx::Size GetPartSize(Part part,
  52. State state,
  53. const ExtraParams& extra) const override;
  54. void Paint(cc::PaintCanvas* canvas,
  55. const ui::ColorProvider* color_provider,
  56. Part part,
  57. State state,
  58. const gfx::Rect& rect,
  59. const ExtraParams& extra,
  60. ColorScheme color_scheme,
  61. const absl::optional<SkColor>& accent_color) const override;
  62. bool SupportsNinePatch(Part part) const override;
  63. gfx::Size GetNinePatchCanvasSize(Part part) const override;
  64. gfx::Rect GetNinePatchAperture(Part part) const override;
  65. bool ShouldUseDarkColors() const override;
  66. PreferredColorScheme CalculatePreferredColorScheme() const override;
  67. PreferredContrast CalculatePreferredContrast() const override;
  68. ColorScheme GetDefaultSystemColorScheme() const override;
  69. protected:
  70. friend class NativeTheme;
  71. friend class base::NoDestructor<NativeThemeWin>;
  72. // NativeTheme:
  73. void ConfigureWebInstance() override;
  74. NativeThemeWin(bool configure_web_instance, bool should_only_use_dark_colors);
  75. ~NativeThemeWin() override;
  76. private:
  77. bool IsUsingHighContrastThemeInternal() const;
  78. void CloseHandlesInternal();
  79. // gfx::SysColorChangeListener:
  80. void OnSysColorChange() override;
  81. // Update the locally cached set of system colors.
  82. void UpdateSystemColors();
  83. // Painting functions that paint to PaintCanvas.
  84. void PaintMenuSeparator(cc::PaintCanvas* canvas,
  85. const ColorProvider* color_provider,
  86. const MenuSeparatorExtraParams& params) const;
  87. void PaintMenuGutter(cc::PaintCanvas* canvas,
  88. const ColorProvider* color_provider,
  89. const gfx::Rect& rect) const;
  90. void PaintMenuBackground(cc::PaintCanvas* canvas,
  91. const ColorProvider* color_provider,
  92. const gfx::Rect& rect) const;
  93. // Paint directly to canvas' HDC.
  94. void PaintDirect(SkCanvas* destination_canvas,
  95. HDC hdc,
  96. Part part,
  97. State state,
  98. const gfx::Rect& rect,
  99. const ExtraParams& extra) const;
  100. // Create a temporary HDC, paint to that, clean up the alpha values in the
  101. // temporary HDC, and then blit the result to canvas. This is to work around
  102. // the fact that Windows XP and some classic themes give bogus alpha values.
  103. void PaintIndirect(cc::PaintCanvas* destination_canvas,
  104. Part part,
  105. State state,
  106. const gfx::Rect& rect,
  107. const ExtraParams& extra) const;
  108. // Various helpers to paint specific parts.
  109. void PaintButtonClassic(HDC hdc,
  110. Part part,
  111. State state,
  112. RECT* rect,
  113. const ButtonExtraParams& extra) const;
  114. void PaintLeftMenuArrowThemed(HDC hdc,
  115. HANDLE handle,
  116. int part_id,
  117. int state_id,
  118. const gfx::Rect& rect) const;
  119. void PaintScrollbarArrowClassic(HDC hdc,
  120. Part part,
  121. State state,
  122. RECT* rect) const;
  123. void PaintScrollbarTrackClassic(SkCanvas* canvas,
  124. HDC hdc,
  125. RECT* rect,
  126. const ScrollbarTrackExtraParams& extra) const;
  127. void PaintHorizontalTrackbarThumbClassic(
  128. SkCanvas* canvas,
  129. HDC hdc,
  130. const RECT& rect,
  131. const TrackbarExtraParams& extra) const;
  132. void PaintProgressBarOverlayThemed(HDC hdc,
  133. HANDLE handle,
  134. RECT* bar_rect,
  135. RECT* value_rect,
  136. const ProgressBarExtraParams& extra) const;
  137. void PaintTextFieldThemed(HDC hdc,
  138. HANDLE handle,
  139. HBRUSH bg_brush,
  140. int part_id,
  141. int state_id,
  142. RECT* rect,
  143. const TextFieldExtraParams& extra) const;
  144. void PaintTextFieldClassic(HDC hdc,
  145. HBRUSH bg_brush,
  146. RECT* rect,
  147. const TextFieldExtraParams& extra) const;
  148. // Paints a theme part, with support for scene scaling in high-DPI mode.
  149. // |theme| is the theme handle. |hdc| is the handle for the device context.
  150. // |part_id| is the identifier for the part (e.g. thumb gripper). |state_id|
  151. // is the identifier for the rendering state of the part (e.g. hover). |rect|
  152. // is the bounds for rendering, expressed in logical coordinates.
  153. void PaintScaledTheme(HANDLE theme,
  154. HDC hdc,
  155. int part_id,
  156. int state_id,
  157. const gfx::Rect& rect) const;
  158. // Get the windows theme name/part/state. These three helper functions are
  159. // used only by GetPartSize(), as each of the corresponding PaintXXX()
  160. // methods do further validation of the part and state that is required for
  161. // getting the size.
  162. static ThemeName GetThemeName(Part part);
  163. static int GetWindowsPart(Part part, State state, const ExtraParams& extra);
  164. static int GetWindowsState(Part part, State state, const ExtraParams& extra);
  165. HRESULT PaintFrameControl(HDC hdc,
  166. const gfx::Rect& rect,
  167. UINT type,
  168. UINT state,
  169. bool is_selected,
  170. State control_state) const;
  171. // Returns a handle to the theme data.
  172. HANDLE GetThemeHandle(ThemeName theme_name) const;
  173. void RegisterThemeRegkeyObserver();
  174. void UpdateDarkModeStatus();
  175. // True if Windows supports dark mode. This does NOT indicate whether the
  176. // system is in dark mode, only that it is supported by this version of
  177. // Windows.
  178. const bool supports_windows_dark_mode_;
  179. // Dark Mode registry key.
  180. base::win::RegKey hkcu_themes_regkey_;
  181. // A cache of open theme handles.
  182. mutable HANDLE theme_handles_[LAST];
  183. // The system color change listener and the updated cache of system colors.
  184. gfx::ScopedSysColorChangeListener color_change_listener_;
  185. // Used to notify the web native theme of changes to dark mode, high
  186. // contrast, preferred color scheme, and preferred contrast.
  187. std::unique_ptr<NativeTheme::ColorSchemeNativeThemeObserver>
  188. color_scheme_observer_;
  189. };
  190. } // namespace ui
  191. #endif // UI_NATIVE_THEME_NATIVE_THEME_WIN_H_