1 ///////////////////////////////////////////////////////////////////////////////
2 // Name:        wx/msw/uxtheme.h
3 // Purpose:     wxUxThemeEngine class: support for XP themes
4 // Author:      John Platts, Vadim Zeitlin
5 // Modified by:
6 // Created:     2003
7 // Copyright:   (c) 2003 John Platts, Vadim Zeitlin
8 // Licence:     wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
10 
11 #ifndef _WX_UXTHEME_H_
12 #define _WX_UXTHEME_H_
13 
14 #include "wx/defs.h"
15 
16 #include "wx/msw/private.h"     // we use GetHwndOf()
17 #include "wx/msw/uxthemep.h"
18 
19 // Amazingly, GetThemeFont() and GetThemeSysFont() functions use LOGFONTA under
20 // XP but LOGFONTW (even in non-Unicode build) under later versions of Windows.
21 // If we declare them as taking LOGFONT below, the code would be able to
22 // silently pass LOGFONTA to them in ANSI build and would crash at run-time
23 // under Windows Vista/7 because of a buffer overrun (LOGFONTA being smaller
24 // than LOGFONTW expected by these functions). If we we declare them as taking
25 // LOGFONTW, the code wouldn't work correctly under XP. So we use a special
26 // wxUxThemeFont class to encapsulate this and intentionally change the LOGFONT
27 // output parameters of the theme functions to take it instead.
28 
29 class wxUxThemeFont
30 {
31 public:
32     // Trivial default ctor.
wxUxThemeFont()33     wxUxThemeFont() { }
34 
35     // Just some unique type.
36     struct Ptr { };
37 
38 #if wxUSE_UNICODE
39     // In Unicode build we always use LOGFONT anyhow so this class is
40     // completely trivial.
GetPtr()41     Ptr *GetPtr() { return reinterpret_cast<Ptr *>(&m_lfW); }
GetLOGFONT()42     const LOGFONTW& GetLOGFONT() { return m_lfW; }
43 #else // !wxUSE_UNICODE
44     // Return either LOGFONTA or LOGFONTW pointer as required by the current
45     // Windows version.
GetPtr()46     Ptr *GetPtr()
47     {
48         return UseLOGFONTW() ? reinterpret_cast<Ptr *>(&m_lfW)
49                              : reinterpret_cast<Ptr *>(&m_lfA);
50     }
51 
52     // This method returns LOGFONT (i.e. LOGFONTA in ANSI build and LOGFONTW in
53     // Unicode one) which can be used with other, normal, Windows or wx
54     // functions. Internally it may need to transform LOGFONTW to LOGFONTA.
GetLOGFONT()55     const LOGFONTA& GetLOGFONT()
56     {
57         if ( UseLOGFONTW() )
58         {
59             // Most of the fields are the same in LOGFONTA and LOGFONTW so just
60             // copy everything by default.
61             memcpy(&m_lfA, &m_lfW, sizeof(m_lfA));
62 
63             // But the face name must be converted from Unicode.
64             WideCharToMultiByte(CP_ACP, 0, m_lfW.lfFaceName, -1,
65                                 m_lfA.lfFaceName, sizeof(m_lfA.lfFaceName),
66                                 NULL, NULL);
67         }
68 
69         return m_lfA;
70     }
71 
72 private:
UseLOGFONTW()73     static bool UseLOGFONTW()
74     {
75         return wxGetWinVersion() >= wxWinVersion_Vista;
76     }
77 
78     LOGFONTA m_lfA;
79 #endif // wxUSE_UNICODE/!wxUSE_UNICODE
80 
81 private:
82     LOGFONTW m_lfW;
83 
84     wxDECLARE_NO_COPY_CLASS(wxUxThemeFont);
85 };
86 
87 typedef HTHEME  (__stdcall *PFNWXUOPENTHEMEDATA)(HWND, const wchar_t *);
88 typedef HRESULT (__stdcall *PFNWXUCLOSETHEMEDATA)(HTHEME);
89 typedef HRESULT (__stdcall *PFNWXUDRAWTHEMEBACKGROUND)(HTHEME, HDC, int, int, const RECT *, const RECT *);
90 typedef HRESULT (__stdcall *PFNWXUDRAWTHEMETEXT)(HTHEME, HDC, int, int, const wchar_t *, int, DWORD, DWORD, const RECT *);
91 typedef HRESULT (__stdcall *PFNWXUGETTHEMEBACKGROUNDCONTENTRECT)(HTHEME, HDC, int, int, const RECT *, RECT *);
92 typedef HRESULT (__stdcall *PFNWXUGETTHEMEBACKGROUNDEXTENT)(HTHEME, HDC, int, int, const RECT *, RECT *);
93 typedef HRESULT (__stdcall *PFNWXUGETTHEMEPARTSIZE)(HTHEME, HDC, int, int, const RECT *, /* enum */ THEMESIZE, SIZE *);
94 typedef HRESULT (__stdcall *PFNWXUGETTHEMETEXTEXTENT)(HTHEME, HDC, int, int, const wchar_t *, int, DWORD, const RECT *, RECT *);
95 typedef HRESULT (__stdcall *PFNWXUGETTHEMETEXTMETRICS)(HTHEME, HDC, int, int, TEXTMETRIC*);
96 typedef HRESULT (__stdcall *PFNWXUGETTHEMEBACKGROUNDREGION)(HTHEME, HDC, int, int, const RECT *, HRGN *);
97 typedef HRESULT (__stdcall *PFNWXUHITTESTTHEMEBACKGROUND)(HTHEME, HDC, int, int, DWORD, const RECT *, HRGN, POINT, unsigned short *);
98 typedef HRESULT (__stdcall *PFNWXUDRAWTHEMEEDGE)(HTHEME, HDC, int, int, const RECT *, unsigned int, unsigned int, RECT *);
99 typedef HRESULT (__stdcall *PFNWXUDRAWTHEMEICON)(HTHEME, HDC, int, int, const RECT *, HIMAGELIST, int);
100 typedef BOOL    (__stdcall *PFNWXUISTHEMEPARTDEFINED)(HTHEME, int, int);
101 typedef BOOL    (__stdcall *PFNWXUISTHEMEBACKGROUNDPARTIALLYTRANSPARENT)(HTHEME, int, int);
102 typedef HRESULT (__stdcall *PFNWXUGETTHEMECOLOR)(HTHEME, int, int, int, COLORREF*);
103 typedef HRESULT (__stdcall *PFNWXUGETTHEMEMETRIC)(HTHEME, HDC, int, int, int, int *);
104 typedef HRESULT (__stdcall *PFNWXUGETTHEMESTRING)(HTHEME, int, int, int, wchar_t *, int);
105 typedef HRESULT (__stdcall *PFNWXUGETTHEMEBOOL)(HTHEME, int, int, int, BOOL *);
106 typedef HRESULT (__stdcall *PFNWXUGETTHEMEINT)(HTHEME, int, int, int, int *);
107 typedef HRESULT (__stdcall *PFNWXUGETTHEMEENUMVALUE)(HTHEME, int, int, int, int *);
108 typedef HRESULT (__stdcall *PFNWXUGETTHEMEPOSITION)(HTHEME, int, int, int, POINT *);
109 typedef HRESULT (__stdcall *PFNWXUGETTHEMEFONT)(HTHEME, HDC, int, int, int, wxUxThemeFont::Ptr *);
110 typedef HRESULT (__stdcall *PFNWXUGETTHEMERECT)(HTHEME, int, int, int, RECT *);
111 typedef HRESULT (__stdcall *PFNWXUGETTHEMEMARGINS)(HTHEME, HDC, int, int, int, RECT *, MARGINS *);
112 typedef HRESULT (__stdcall *PFNWXUGETTHEMEINTLIST)(HTHEME, int, int, int, INTLIST*);
113 typedef HRESULT (__stdcall *PFNWXUGETTHEMEPROPERTYORIGIN)(HTHEME, int, int, int, /* enum */ PROPERTYORIGIN *);
114 typedef HRESULT (__stdcall *PFNWXUSETWINDOWTHEME)(HWND, const wchar_t*, const wchar_t *);
115 typedef HRESULT (__stdcall *PFNWXUGETTHEMEFILENAME)(HTHEME, int, int, int, wchar_t *, int);
116 typedef COLORREF(__stdcall *PFNWXUGETTHEMESYSCOLOR)(HTHEME, int);
117 typedef HBRUSH  (__stdcall *PFNWXUGETTHEMESYSCOLORBRUSH)(HTHEME, int);
118 typedef BOOL    (__stdcall *PFNWXUGETTHEMESYSBOOL)(HTHEME, int);
119 typedef int     (__stdcall *PFNWXUGETTHEMESYSSIZE)(HTHEME, int);
120 typedef HRESULT (__stdcall *PFNWXUGETTHEMESYSFONT)(HTHEME, int, wxUxThemeFont::Ptr *);
121 typedef HRESULT (__stdcall *PFNWXUGETTHEMESYSSTRING)(HTHEME, int, wchar_t *, int);
122 typedef HRESULT (__stdcall *PFNWXUGETTHEMESYSINT)(HTHEME, int, int *);
123 typedef BOOL    (__stdcall *PFNWXUISTHEMEACTIVE)();
124 typedef BOOL    (__stdcall *PFNWXUISAPPTHEMED)();
125 typedef HTHEME  (__stdcall *PFNWXUGETWINDOWTHEME)(HWND);
126 typedef HRESULT (__stdcall *PFNWXUENABLETHEMEDIALOGTEXTURE)(HWND, DWORD);
127 typedef BOOL    (__stdcall *PFNWXUISTHEMEDIALOGTEXTUREENABLED)(HWND);
128 typedef DWORD   (__stdcall *PFNWXUGETTHEMEAPPPROPERTIES)();
129 typedef void    (__stdcall *PFNWXUSETTHEMEAPPPROPERTIES)(DWORD);
130 typedef HRESULT (__stdcall *PFNWXUGETCURRENTTHEMENAME)(wchar_t *, int, wchar_t *, int, wchar_t *, int);
131 typedef HRESULT (__stdcall *PFNWXUGETTHEMEDOCUMENTATIONPROPERTY)(const wchar_t *, const wchar_t *, wchar_t *, int);
132 typedef HRESULT (__stdcall *PFNWXUDRAWTHEMEPARENTBACKGROUND)(HWND, HDC, RECT *);
133 typedef HRESULT (__stdcall *PFNWXUENABLETHEMING)(BOOL);
134 
135 // ----------------------------------------------------------------------------
136 // wxUxThemeEngine: provides all theme functions from uxtheme.dll
137 // ----------------------------------------------------------------------------
138 
139 // we always define this class, even if wxUSE_UXTHEME == 0, but we just make it
140 // empty in this case -- this allows to use it elsewhere without any #ifdefs
141 #if wxUSE_UXTHEME
142     #include "wx/dynlib.h"
143 
144     #define wxUX_THEME_DECLARE(type, func) type func;
145 #else
146     #define wxUX_THEME_DECLARE(type, func) type func(...) { return 0; }
147 #endif
148 
149 class WXDLLIMPEXP_CORE wxUxThemeEngine
150 {
151 public:
152     // get the theme engine or NULL if themes are not available
153     static wxUxThemeEngine *Get();
154 
155     // get the theme enging or NULL if themes are not available or not used for
156     // this application
157     static wxUxThemeEngine *GetIfActive();
158 
159     // all uxtheme.dll functions
wxUX_THEME_DECLARE(PFNWXUOPENTHEMEDATA,OpenThemeData)160     wxUX_THEME_DECLARE(PFNWXUOPENTHEMEDATA, OpenThemeData)
161     wxUX_THEME_DECLARE(PFNWXUCLOSETHEMEDATA, CloseThemeData)
162     wxUX_THEME_DECLARE(PFNWXUDRAWTHEMEBACKGROUND, DrawThemeBackground)
163     wxUX_THEME_DECLARE(PFNWXUDRAWTHEMETEXT, DrawThemeText)
164     wxUX_THEME_DECLARE(PFNWXUGETTHEMEBACKGROUNDCONTENTRECT, GetThemeBackgroundContentRect)
165     wxUX_THEME_DECLARE(PFNWXUGETTHEMEBACKGROUNDEXTENT, GetThemeBackgroundExtent)
166     wxUX_THEME_DECLARE(PFNWXUGETTHEMEPARTSIZE, GetThemePartSize)
167     wxUX_THEME_DECLARE(PFNWXUGETTHEMETEXTEXTENT, GetThemeTextExtent)
168     wxUX_THEME_DECLARE(PFNWXUGETTHEMETEXTMETRICS, GetThemeTextMetrics)
169     wxUX_THEME_DECLARE(PFNWXUGETTHEMEBACKGROUNDREGION, GetThemeBackgroundRegion)
170     wxUX_THEME_DECLARE(PFNWXUHITTESTTHEMEBACKGROUND, HitTestThemeBackground)
171     wxUX_THEME_DECLARE(PFNWXUDRAWTHEMEEDGE, DrawThemeEdge)
172     wxUX_THEME_DECLARE(PFNWXUDRAWTHEMEICON, DrawThemeIcon)
173     wxUX_THEME_DECLARE(PFNWXUISTHEMEPARTDEFINED, IsThemePartDefined)
174     wxUX_THEME_DECLARE(PFNWXUISTHEMEBACKGROUNDPARTIALLYTRANSPARENT, IsThemeBackgroundPartiallyTransparent)
175     wxUX_THEME_DECLARE(PFNWXUGETTHEMECOLOR, GetThemeColor)
176     wxUX_THEME_DECLARE(PFNWXUGETTHEMEMETRIC, GetThemeMetric)
177     wxUX_THEME_DECLARE(PFNWXUGETTHEMESTRING, GetThemeString)
178     wxUX_THEME_DECLARE(PFNWXUGETTHEMEBOOL, GetThemeBool)
179     wxUX_THEME_DECLARE(PFNWXUGETTHEMEINT, GetThemeInt)
180     wxUX_THEME_DECLARE(PFNWXUGETTHEMEENUMVALUE, GetThemeEnumValue)
181     wxUX_THEME_DECLARE(PFNWXUGETTHEMEPOSITION, GetThemePosition)
182     wxUX_THEME_DECLARE(PFNWXUGETTHEMEFONT, GetThemeFont)
183     wxUX_THEME_DECLARE(PFNWXUGETTHEMERECT, GetThemeRect)
184     wxUX_THEME_DECLARE(PFNWXUGETTHEMEMARGINS, GetThemeMargins)
185     wxUX_THEME_DECLARE(PFNWXUGETTHEMEINTLIST, GetThemeIntList)
186     wxUX_THEME_DECLARE(PFNWXUGETTHEMEPROPERTYORIGIN, GetThemePropertyOrigin)
187     wxUX_THEME_DECLARE(PFNWXUSETWINDOWTHEME, SetWindowTheme)
188     wxUX_THEME_DECLARE(PFNWXUGETTHEMEFILENAME, GetThemeFilename)
189     wxUX_THEME_DECLARE(PFNWXUGETTHEMESYSCOLOR, GetThemeSysColor)
190     wxUX_THEME_DECLARE(PFNWXUGETTHEMESYSCOLORBRUSH, GetThemeSysColorBrush)
191     wxUX_THEME_DECLARE(PFNWXUGETTHEMESYSBOOL, GetThemeSysBool)
192     wxUX_THEME_DECLARE(PFNWXUGETTHEMESYSSIZE, GetThemeSysSize)
193     wxUX_THEME_DECLARE(PFNWXUGETTHEMESYSFONT, GetThemeSysFont)
194     wxUX_THEME_DECLARE(PFNWXUGETTHEMESYSSTRING, GetThemeSysString)
195     wxUX_THEME_DECLARE(PFNWXUGETTHEMESYSINT, GetThemeSysInt)
196     wxUX_THEME_DECLARE(PFNWXUISTHEMEACTIVE, IsThemeActive)
197     wxUX_THEME_DECLARE(PFNWXUISAPPTHEMED, IsAppThemed)
198     wxUX_THEME_DECLARE(PFNWXUGETWINDOWTHEME, GetWindowTheme)
199     wxUX_THEME_DECLARE(PFNWXUENABLETHEMEDIALOGTEXTURE, EnableThemeDialogTexture)
200     wxUX_THEME_DECLARE(PFNWXUISTHEMEDIALOGTEXTUREENABLED, IsThemeDialogTextureEnabled)
201     wxUX_THEME_DECLARE(PFNWXUGETTHEMEAPPPROPERTIES, GetThemeAppProperties)
202     wxUX_THEME_DECLARE(PFNWXUSETTHEMEAPPPROPERTIES, SetThemeAppProperties)
203     wxUX_THEME_DECLARE(PFNWXUGETCURRENTTHEMENAME, GetCurrentThemeName)
204     wxUX_THEME_DECLARE(PFNWXUGETTHEMEDOCUMENTATIONPROPERTY, GetThemeDocumentationProperty)
205     wxUX_THEME_DECLARE(PFNWXUDRAWTHEMEPARENTBACKGROUND, DrawThemeParentBackground)
206     wxUX_THEME_DECLARE(PFNWXUENABLETHEMING, EnableTheming)
207 
208 private:
209     // construcor is private as only Get() can create us and is also trivial as
210     // everything really happens in Initialize()
211     wxUxThemeEngine() { }
212 
213     // destructor is private as only Get() and wxUxThemeModule delete us, it is
214     // not virtual as we're not supposed to be derived from
~wxUxThemeEngine()215     ~wxUxThemeEngine() { }
216 
217 #if wxUSE_UXTHEME
218     // initialize the theme engine: load the DLL, resolve the functions
219     //
220     // return true if we can be used, false if themes are not available
221     bool Initialize();
222 
223 
224     // uxtheme.dll
225     wxDynamicLibrary m_dllUxTheme;
226 
227 
228     // the one and only theme engine, initially NULL
229     static wxUxThemeEngine *ms_themeEngine;
230 
231     // this is a bool which initially has the value -1 meaning "unknown"
232     static int ms_isThemeEngineAvailable;
233 
234     // it must be able to delete us
235     friend class wxUxThemeModule;
236 #endif // wxUSE_UXTHEME
237 
238     wxDECLARE_NO_COPY_CLASS(wxUxThemeEngine);
239 };
240 
241 #if wxUSE_UXTHEME
242 
GetIfActive()243 /* static */ inline wxUxThemeEngine *wxUxThemeEngine::GetIfActive()
244 {
245     wxUxThemeEngine *engine = Get();
246     return engine && engine->IsAppThemed() && engine->IsThemeActive()
247                 ? engine
248                 : NULL;
249 }
250 
251 #else // !wxUSE_UXTHEME
252 
Get()253 /* static */ inline wxUxThemeEngine *wxUxThemeEngine::Get()
254 {
255     return NULL;
256 }
257 
GetIfActive()258 /* static */ inline wxUxThemeEngine *wxUxThemeEngine::GetIfActive()
259 {
260     return NULL;
261 }
262 
263 #endif // wxUSE_UXTHEME/!wxUSE_UXTHEME
264 
265 // ----------------------------------------------------------------------------
266 // wxUxThemeHandle: encapsulates ::Open/CloseThemeData()
267 // ----------------------------------------------------------------------------
268 
269 class wxUxThemeHandle
270 {
271 public:
wxUxThemeHandle(const wxWindow * win,const wchar_t * classes)272     wxUxThemeHandle(const wxWindow *win, const wchar_t *classes)
273     {
274         wxUxThemeEngine *engine = wxUxThemeEngine::Get();
275 
276         m_hTheme = engine ? (HTHEME)engine->OpenThemeData(GetHwndOf(win), classes)
277                           : NULL;
278     }
279 
HTHEME()280     operator HTHEME() const { return m_hTheme; }
281 
~wxUxThemeHandle()282     ~wxUxThemeHandle()
283     {
284         if ( m_hTheme )
285         {
286             wxUxThemeEngine::Get()->CloseThemeData(m_hTheme);
287         }
288     }
289 
290 private:
291     HTHEME m_hTheme;
292 
293     wxDECLARE_NO_COPY_CLASS(wxUxThemeHandle);
294 };
295 
296 #endif // _WX_UXTHEME_H_
297 
298