]>
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 | // 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. | |
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. | |
41 | Ptr *GetPtr() { return reinterpret_cast<Ptr *>(&m_lfW); } | |
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. | |
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. | |
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: | |
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 | |
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 | |
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 | ||
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 | ||
253 | /* static */ inline wxUxThemeEngine *wxUxThemeEngine::Get() | |
254 | { | |
255 | return NULL; | |
256 | } | |
257 | ||
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: | |
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 | ||
280 | operator HTHEME() const { return m_hTheme; } | |
281 | ||
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 |