| // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 
 | // Use of this source code is governed by a BSD-style license that can be | 
 | // found in the LICENSE file. | 
 |  | 
 | #ifndef UI_NATIVE_THEME_NATIVE_THEME_WIN_H_ | 
 | #define UI_NATIVE_THEME_NATIVE_THEME_WIN_H_ | 
 |  | 
 | // A wrapper class for working with custom XP/Vista themes provided in | 
 | // uxtheme.dll.  This is a singleton class that can be grabbed using | 
 | // NativeThemeWin::instance(). | 
 | // For more information on visual style parts and states, see: | 
 | // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/commctls/userex/topics/partsandstates.asp | 
 |  | 
 | #include <map> | 
 |  | 
 | #include <windows.h> | 
 | #include <uxtheme.h> | 
 |  | 
 | #include "base/basictypes.h" | 
 | #include "base/compiler_specific.h" | 
 | #include "third_party/skia/include/core/SkColor.h" | 
 | #include "ui/gfx/geometry/size.h" | 
 | #include "ui/gfx/sys_color_change_listener.h" | 
 | #include "ui/native_theme/native_theme.h" | 
 |  | 
 | class SkCanvas; | 
 |  | 
 | namespace ui { | 
 |  | 
 | // Windows implementation of native theme class. | 
 | // | 
 | // At the moment, this class in in transition from an older API that consists | 
 | // of several PaintXXX methods to an API, inherited from the NativeTheme base | 
 | // class, that consists of a single Paint() method with a argument to indicate | 
 | // what kind of part to paint. | 
 | class NATIVE_THEME_EXPORT NativeThemeWin : public NativeTheme, | 
 |                                            public gfx::SysColorChangeListener { | 
 |  public: | 
 |   enum ThemeName { | 
 |     BUTTON, | 
 |     LIST, | 
 |     MENU, | 
 |     MENULIST, | 
 |     SCROLLBAR, | 
 |     STATUS, | 
 |     TAB, | 
 |     TEXTFIELD, | 
 |     TRACKBAR, | 
 |     WINDOW, | 
 |     PROGRESS, | 
 |     SPIN, | 
 |     LAST | 
 |   }; | 
 |  | 
 |   bool IsThemingActive() const; | 
 |  | 
 |   // Returns true if a high contrast theme is being used. | 
 |   bool IsUsingHighContrastTheme() const; | 
 |  | 
 |   HRESULT GetThemeColor(ThemeName theme, | 
 |                         int part_id, | 
 |                         int state_id, | 
 |                         int prop_id, | 
 |                         SkColor* color) const; | 
 |  | 
 |   // Get the theme color if theming is enabled.  If theming is unsupported | 
 |   // for this part, use Win32's GetSysColor to find the color specified | 
 |   // by default_sys_color. | 
 |   SkColor GetThemeColorWithDefault(ThemeName theme, | 
 |                                    int part_id, | 
 |                                    int state_id, | 
 |                                    int prop_id, | 
 |                                    int default_sys_color) const; | 
 |  | 
 |   // Get the thickness of the border associated with the specified theme, | 
 |   // defaulting to GetSystemMetrics edge size if themes are disabled. | 
 |   // In Classic Windows, borders are typically 2px; on XP+, they are 1px. | 
 |   gfx::Size GetThemeBorderSize(ThemeName theme) const; | 
 |  | 
 |   // Disables all theming for top-level windows in the entire process, from | 
 |   // when this method is called until the process exits.  All the other | 
 |   // methods in this class will continue to work, but their output will ignore | 
 |   // the user's theme. This is meant for use when running tests that require | 
 |   // consistent visual results. | 
 |   void DisableTheming() const; | 
 |  | 
 |   // Closes cached theme handles so we can unload the DLL or update our UI | 
 |   // for a theme change. | 
 |   void CloseHandles() const; | 
 |  | 
 |   // Returns true if classic theme is in use. | 
 |   bool IsClassicTheme(ThemeName name) const; | 
 |  | 
 |   // Gets our singleton instance. | 
 |   static NativeThemeWin* instance(); | 
 |  | 
 |   HRESULT PaintTextField(HDC hdc, | 
 |                          int part_id, | 
 |                          int state_id, | 
 |                          int classic_state, | 
 |                          RECT* rect, | 
 |                          COLORREF color, | 
 |                          bool fill_content_area, | 
 |                          bool draw_edges) const; | 
 |  | 
 |   // NativeTheme implementation: | 
 |   gfx::Size GetPartSize(Part part, | 
 |                         State state, | 
 |                         const ExtraParams& extra) const override; | 
 |   void Paint(SkCanvas* canvas, | 
 |              Part part, | 
 |              State state, | 
 |              const gfx::Rect& rect, | 
 |              const ExtraParams& extra) const override; | 
 |   SkColor GetSystemColor(ColorId color_id) const override; | 
 |  | 
 |  protected: | 
 |   NativeThemeWin(); | 
 |   ~NativeThemeWin() override; | 
 |  | 
 |  private: | 
 |   // gfx::SysColorChangeListener implementation: | 
 |   void OnSysColorChange() override; | 
 |  | 
 |   // Update the locally cached set of system colors. | 
 |   void UpdateSystemColors(); | 
 |  | 
 |   // Paint directly to canvas' HDC. | 
 |   void PaintDirect(SkCanvas* canvas, | 
 |                    Part part, | 
 |                    State state, | 
 |                    const gfx::Rect& rect, | 
 |                    const ExtraParams& extra) const; | 
 |  | 
 |   // Create a temporary HDC, paint to that, clean up the alpha values in the | 
 |   // temporary HDC, and then blit the result to canvas.  This is to work around | 
 |   // the fact that Windows XP and some classic themes give bogus alpha values. | 
 |   void PaintIndirect(SkCanvas* canvas, | 
 |                      Part part, | 
 |                      State state, | 
 |                      const gfx::Rect& rect, | 
 |                      const ExtraParams& extra) const; | 
 |  | 
 |   HRESULT GetThemePartSize(ThemeName themeName, | 
 |                            HDC hdc, | 
 |                            int part_id, | 
 |                            int state_id, | 
 |                            RECT* rect, | 
 |                            int ts, | 
 |                            SIZE* size) const; | 
 |  | 
 |   HRESULT PaintButton(HDC hdc, | 
 |                       State state, | 
 |                       const ButtonExtraParams& extra, | 
 |                       int part_id, | 
 |                       int state_id, | 
 |                       RECT* rect) const; | 
 |  | 
 |   HRESULT PaintMenuSeparator(HDC hdc, | 
 |                              const gfx::Rect& rect) const; | 
 |  | 
 |   HRESULT PaintMenuGutter(HDC hdc, const gfx::Rect& rect) const; | 
 |  | 
 |   // |arrow_direction| determines whether the arrow is pointing to the left or | 
 |   // to the right. In RTL locales, sub-menus open from right to left and | 
 |   // therefore the menu arrow should point to the left and not to the right. | 
 |   HRESULT PaintMenuArrow(HDC hdc, | 
 |                          State state, | 
 |                          const gfx::Rect& rect, | 
 |                          const MenuArrowExtraParams& extra) const; | 
 |  | 
 |   HRESULT PaintMenuBackground(HDC hdc, const gfx::Rect& rect) const; | 
 |  | 
 |   HRESULT PaintMenuCheck(HDC hdc, | 
 |                          State state, | 
 |                          const gfx::Rect& rect, | 
 |                          const MenuCheckExtraParams& extra) const; | 
 |  | 
 |   HRESULT PaintMenuCheckBackground(HDC hdc, | 
 |                                    State state, | 
 |                                    const gfx::Rect& rect) const; | 
 |  | 
 |   HRESULT PaintMenuItemBackground(HDC hdc, | 
 |                                   State state, | 
 |                                   const gfx::Rect& rect, | 
 |                                   const MenuItemExtraParams& extra) const; | 
 |  | 
 |   HRESULT PaintPushButton(HDC hdc, | 
 |                           Part part, | 
 |                           State state, | 
 |                           const gfx::Rect& rect, | 
 |                           const ButtonExtraParams& extra) const; | 
 |  | 
 |   HRESULT PaintRadioButton(HDC hdc, | 
 |                            Part part, | 
 |                            State state, | 
 |                            const gfx::Rect& rect, | 
 |                            const ButtonExtraParams& extra) const; | 
 |  | 
 |   HRESULT PaintCheckbox(HDC hdc, | 
 |                         Part part, | 
 |                         State state, | 
 |                         const gfx::Rect& rect, | 
 |                         const ButtonExtraParams& extra) const; | 
 |  | 
 |   HRESULT PaintMenuList(HDC hdc, | 
 |                         State state, | 
 |                         const gfx::Rect& rect, | 
 |                         const MenuListExtraParams& extra) const; | 
 |  | 
 |   // Paints a scrollbar arrow.  |classic_state| should have the appropriate | 
 |   // classic part number ORed in already. | 
 |   HRESULT PaintScrollbarArrow(HDC hdc, | 
 |                               Part part, | 
 |                               State state, | 
 |                               const gfx::Rect& rect, | 
 |                               const ScrollbarArrowExtraParams& extra) const; | 
 |  | 
 |   HRESULT PaintScrollbarThumb(HDC hdc, | 
 |                               Part part, | 
 |                               State state, | 
 |                               const gfx::Rect& rect, | 
 |                               const ScrollbarThumbExtraParams& extra) const; | 
 |  | 
 |   // This method is deprecated and will be removed in the near future. | 
 |   // Paints a scrollbar track section.  |align_rect| is only used in classic | 
 |   // mode, and makes sure the checkerboard pattern in |target_rect| is aligned | 
 |   // with one presumed to be in |align_rect|. | 
 |   HRESULT PaintScrollbarTrack(SkCanvas* canvas, | 
 |                               HDC hdc, | 
 |                               Part part, | 
 |                               State state, | 
 |                               const gfx::Rect& rect, | 
 |                               const ScrollbarTrackExtraParams& extra) const; | 
 |  | 
 |   HRESULT PaintSpinButton(HDC hdc, | 
 |                           Part part, | 
 |                           State state, | 
 |                           const gfx::Rect& rect, | 
 |                           const InnerSpinButtonExtraParams& extra) const; | 
 |  | 
 |   HRESULT PaintTrackbar(SkCanvas* canvas, | 
 |                         HDC hdc, | 
 |                         Part part, | 
 |                         State state, | 
 |                         const gfx::Rect& rect, | 
 |                         const TrackbarExtraParams& extra) const; | 
 |  | 
 |   HRESULT PaintProgressBar(HDC hdc, | 
 |                            const gfx::Rect& rect, | 
 |                            const ProgressBarExtraParams& extra) const; | 
 |  | 
 |   HRESULT PaintWindowResizeGripper(HDC hdc, const gfx::Rect& rect) const; | 
 |  | 
 |   HRESULT PaintTabPanelBackground(HDC hdc, const gfx::Rect& rect) const; | 
 |  | 
 |   HRESULT PaintTextField(HDC hdc, | 
 |                          Part part, | 
 |                          State state, | 
 |                          const gfx::Rect& rect, | 
 |                          const TextFieldExtraParams& extra) const; | 
 |  | 
 |   // Paints a theme part, with support for scene scaling in high-DPI mode. | 
 |   // |theme| is the theme handle. |hdc| is the handle for the device context. | 
 |   // |part_id| is the identifier for the part (e.g. thumb gripper). |state_id| | 
 |   // is the identifier for the rendering state of the part (e.g. hover). |rect| | 
 |   // is the bounds for rendering, expressed in logical coordinates. | 
 |   HRESULT PaintScaledTheme(HANDLE theme, | 
 |                            HDC hdc, | 
 |                            int part_id, | 
 |                            int state_id, | 
 |                            const gfx::Rect& rect) const; | 
 |  | 
 |   // Get the windows theme name/part/state.  These three helper functions are | 
 |   // used only by GetPartSize(), as each of the corresponding PaintXXX() | 
 |   // methods do further validation of the part and state that is required for | 
 |   // getting the size. | 
 |   static ThemeName GetThemeName(Part part); | 
 |   static int GetWindowsPart(Part part, State state, const ExtraParams& extra); | 
 |   static int GetWindowsState(Part part, State state, const ExtraParams& extra); | 
 |  | 
 |   HRESULT GetThemeInt(ThemeName theme, | 
 |                       int part_id, | 
 |                       int state_id, | 
 |                       int prop_id, | 
 |                       int *result) const; | 
 |  | 
 |   HRESULT PaintFrameControl(HDC hdc, | 
 |                             const gfx::Rect& rect, | 
 |                             UINT type, | 
 |                             UINT state, | 
 |                             bool is_selected, | 
 |                             State control_state) const; | 
 |  | 
 |   // Returns a handle to the theme data. | 
 |   HANDLE GetThemeHandle(ThemeName theme_name) const; | 
 |  | 
 |   typedef HRESULT (WINAPI* DrawThemeBackgroundPtr)(HANDLE theme, | 
 |                                                    HDC hdc, | 
 |                                                    int part_id, | 
 |                                                    int state_id, | 
 |                                                    const RECT* rect, | 
 |                                                    const RECT* clip_rect); | 
 |   typedef HRESULT (WINAPI* DrawThemeBackgroundExPtr)(HANDLE theme, | 
 |                                                      HDC hdc, | 
 |                                                      int part_id, | 
 |                                                      int state_id, | 
 |                                                      const RECT* rect, | 
 |                                                      const DTBGOPTS* opts); | 
 |   typedef HRESULT (WINAPI* GetThemeColorPtr)(HANDLE hTheme, | 
 |                                              int part_id, | 
 |                                              int state_id, | 
 |                                              int prop_id, | 
 |                                              COLORREF* color); | 
 |   typedef HRESULT (WINAPI* GetThemeContentRectPtr)(HANDLE hTheme, | 
 |                                                    HDC hdc, | 
 |                                                    int part_id, | 
 |                                                    int state_id, | 
 |                                                    const RECT* rect, | 
 |                                                    RECT* content_rect); | 
 |   typedef HRESULT (WINAPI* GetThemePartSizePtr)(HANDLE hTheme, | 
 |                                                 HDC hdc, | 
 |                                                 int part_id, | 
 |                                                 int state_id, | 
 |                                                 RECT* rect, | 
 |                                                 int ts, | 
 |                                                 SIZE* size); | 
 |   typedef HANDLE (WINAPI* OpenThemeDataPtr)(HWND window, | 
 |                                             LPCWSTR class_list); | 
 |   typedef HRESULT (WINAPI* CloseThemeDataPtr)(HANDLE theme); | 
 |  | 
 |   typedef void (WINAPI* SetThemeAppPropertiesPtr) (DWORD flags); | 
 |   typedef BOOL (WINAPI* IsThemeActivePtr)(); | 
 |   typedef HRESULT (WINAPI* GetThemeIntPtr)(HANDLE hTheme, | 
 |                                            int part_id, | 
 |                                            int state_id, | 
 |                                            int prop_id, | 
 |                                            int *value); | 
 |  | 
 |   // Function pointers into uxtheme.dll. | 
 |   DrawThemeBackgroundPtr draw_theme_; | 
 |   DrawThemeBackgroundExPtr draw_theme_ex_; | 
 |   GetThemeColorPtr get_theme_color_; | 
 |   GetThemeContentRectPtr get_theme_content_rect_; | 
 |   GetThemePartSizePtr get_theme_part_size_; | 
 |   OpenThemeDataPtr open_theme_; | 
 |   CloseThemeDataPtr close_theme_; | 
 |   SetThemeAppPropertiesPtr set_theme_properties_; | 
 |   IsThemeActivePtr is_theme_active_; | 
 |   GetThemeIntPtr get_theme_int_; | 
 |  | 
 |   // Handle to uxtheme.dll. | 
 |   HMODULE theme_dll_; | 
 |  | 
 |   // A cache of open theme handles. | 
 |   mutable HANDLE theme_handles_[LAST]; | 
 |  | 
 |   // The system color change listener and the updated cache of system colors. | 
 |   gfx::ScopedSysColorChangeListener color_change_listener_; | 
 |   mutable std::map<int, SkColor> system_colors_; | 
 |  | 
 |   // Is a high contrast theme active? | 
 |   mutable bool is_using_high_contrast_; | 
 |  | 
 |   // Is |is_using_high_contrast_| valid? | 
 |   mutable bool is_using_high_contrast_valid_; | 
 |  | 
 |   DISALLOW_COPY_AND_ASSIGN(NativeThemeWin); | 
 | }; | 
 |  | 
 | }  // namespace ui | 
 |  | 
 | #endif  // UI_NATIVE_THEME_NATIVE_THEME_WIN_H_ |