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