OWLNext    7.0
Borland's Object Windows Library for the modern age
Loading...
Searching...
No Matches
theme.cpp
Go to the documentation of this file.
1//----------------------------------------------------------------------------
2// OWLNext
3//
4/// \file
5/// Microsoft UxTheme Library Encapsulation
6//----------------------------------------------------------------------------
7
8#include <owl/pch.h>
9#include <owl/theme.h>
10
11#if defined(__BORLANDC__)
12# pragma option -w-inl // Disable "Function containing 'statment' is not expanded inline"
13#endif
14
15using namespace std;
16
17namespace owl {
18
21
22//
23/// Private constructor
24/// Loads the DLL and dynamically links the module functions.
25//
26TThemeModule::TThemeModule()
27 : TModule(_T("uxtheme.dll"), true, true, false), // shouldLoad, mustLoad and !addToList
28
29 // General
30 //
31 CloseThemeData(*this, "CloseThemeData"),
32 DrawThemeParentBackground(*this, "DrawThemeParentBackground"),
33 EnableThemeDialogTexture(*this, "EnableThemeDialogTexture"),
34 EnableTheming(*this, "EnableTheming"),
35 GetCurrentThemeName(*this, "GetCurrentThemeName"),
36 GetThemeAppProperties(*this, "GetThemeAppProperties"),
37 GetThemeDocumentationProperty(*this, "GetThemeDocumentationProperty"),
38 GetWindowTheme(*this, "GetWindowTheme"),
39 IsAppThemed(*this, "IsAppThemed"),
40 IsThemeActive(*this, "IsThemeActive"),
41 IsThemeDialogTextureEnabled(*this, "IsThemeDialogTextureEnabled"),
42 OpenThemeData(*this, "OpenThemeData"),
43 SetThemeAppProperties(*this, "SetThemeAppProperties"),
44 SetWindowTheme(*this, "SetWindowTheme"),
45
46 // Theme sys properties
47 //
48 GetThemeSysBool(*this, "GetThemeSysBool"),
49 GetThemeSysColor(*this, "GetThemeSysColor"),
50 GetThemeSysColorBrush(*this, "GetThemeSysColorBrush"),
51 GetThemeSysFont(*this, "GetThemeSysFont"),
52 GetThemeSysInt(*this, "GetThemeSysInt"),
53 GetThemeSysSize(*this, "GetThemeSysSize"),
54 GetThemeSysString(*this, "GetThemeSysString"),
55
56 // Theme parts
57 //
58 DrawThemeBackground(*this, "DrawThemeBackground"),
59 DrawThemeEdge(*this, "DrawThemeEdge"),
60 DrawThemeIcon(*this, "DrawThemeIcon"),
61 DrawThemeText(*this, "DrawThemeText"),
62 GetThemeBackgroundContentRect(*this, "GetThemeBackgroundContentRect"),
63 GetThemeBackgroundExtent(*this, "GetThemeBackgroundExtent"),
64 GetThemeBackgroundRegion(*this, "GetThemeBackgroundRegion"),
65 GetThemeBool(*this, "GetThemeBool"),
66 GetThemeColor(*this, "GetThemeColor"),
67 GetThemeEnumValue(*this, "GetThemeEnumValue"),
68 GetThemeFilename(*this, "GetThemeFilename"),
69 GetThemeFont(*this, "GetThemeFont"),
70 GetThemeInt(*this, "GetThemeInt"),
71 GetThemeIntList(*this, "GetThemeIntList"),
72 GetThemeMargins(*this, "GetThemeMargins"),
73 GetThemeMetric(*this, "GetThemeMetric"),
74 GetThemePartSize(*this, "GetThemePartSize"),
75 GetThemePosition(*this, "GetThemePosition"),
76 GetThemePropertyOrigin(*this, "GetThemePropertyOrigin"),
77 GetThemeRect(*this, "GetThemeRect"),
78 GetThemeString(*this, "GetThemeString"),
79 GetThemeTextExtent(*this, "GetThemeTextExtent"),
80 GetThemeTextMetrics(*this, "GetThemeTextMetrics"),
81 HitTestThemeBackground(*this, "HitTestThemeBackground"),
82 IsThemeBackgroundPartiallyTransparent(*this, "IsThemeBackgroundPartiallyTransparent"),
83 IsThemePartDefined(*this, "IsThemePartDefined")
84{
85 TRACEX(OwlTheme, 1, "Initializing " << TraceId(this));
86}
87
88//
89/// Singleton accessor
90//
91TThemeModule& TThemeModule::GetInstance()
92{
93 //
94 // Note that while this lazy initialization avoids problems with global initialization order,
95 // the initial call of this function is not thread-safe. As a work-around, we ensure this
96 // function is called during program start-up (single-thread, safe).
97 // See InitThemeModuleInstance below.
98 //
99 // The added complexity with the local flag here is needed because the construction of the
100 // singleton may fail and throw exceptions. If that happens we cannot allow construction to be
101 // retried in subsequent (possibly multi-threaded) calls, since construction of function-local
102 // static variables is not thread-safe (pre C++11). So we remember that the initial construction
103 // failed and rethrow without trying construction again on subsequent calls.
104 //
105 // All of this complexity, including InitThemeModuleInstance, can be removed and replaced by a
106 // simple Meyers Singleton (the current try-block) when C++11 compliant compilers are mandated.
107 //
108 static bool initOk = true; // safe trivial compile-time initialization
109 if (!initOk) throw TXTheme(_T("TThemeModule failed initialization"));
110 try
111 {
112 static TThemeModule instance; // initial call (construction) not thread-safe pre-C++11
113 return instance;
114 }
115 catch (...)
116 {
117 initOk = false;
118 throw;
119 }
120}
121
122namespace
123{
124 //
125 // Ensure singleton initialization at start-up (single-threaded, safe).
126 //
127 static struct TInitThemeModuleInstance
128 {
129 TInitThemeModuleInstance()
130 {
131 try {TThemeModule::GetInstance();}
132 catch (...) {}
133 }
134 }
136}
137
138//
139/// Constructs a theme handler.
140//
141TTheme::TTheme(HWND w, LPCWSTR cls)
142: m_handle(TThemeModule::GetInstance().OpenThemeData(w, cls))
143{
144 if (m_handle == nullptr)
145 TXTheme::Raise(_T("Unable to open theme")); // TODO: Load resource string.
146}
147
148//
149/// Releases the theme handle.
150//
152{
153 TThemeModule::GetInstance().CloseThemeData(m_handle);
154}
155
156//
157/// Constructs a theme part handler.
158//
160: TTheme(w, cls), m_part (part), m_state(state)
161{}
162
163//
164/// Paints the background of the themed part.
165//
167{
169 HRESULT r = m.DrawThemeBackground(GetHandle(), dc, m_part, m_state, &dest, nullptr);
170 if (FAILED(r)) TXTheme::Raise(_T("DrawThemeBackground failed"), r);
171}
172
173//
174/// Paints the background of the themed part using a clip rectangle.
175//
177{
179 HRESULT r = m.DrawThemeBackground(GetHandle(), dc, m_part, m_state, &dest, &clip);
180 if (FAILED(r)) TXTheme::Raise(_T("DrawThemeBackground failed"), r);
181}
182
183//
184/// Paints the background of the themed part, properly composited with the parent background.
185/// Assumes there is a window handle associated with the themed part, which should be passed in
186/// the `control` parameter. Combines a call to DrawThemeParentBackground and DrawBackground if
187/// the part is partially transparent. Otherwise just calls DrawBackground.
188//
190{
193 {
194 // The parent may or may not be themed so we just warn (level 1) if painting fails.
195 //
196 HRESULT r = m.DrawThemeParentBackground(control, dc, &dest); InUse(r);
197 WARNX(OwlTheme, FAILED(r), 1, _T("DrawThemeParentBackground failed"));
198 }
199 HRESULT r = m.DrawThemeBackground(GetHandle(), dc, m_part, m_state, &dest, nullptr);
200 if (FAILED(r)) TXTheme::Raise(_T("DrawThemeBackground failed"), r);
201}
202
203//
204/// Returns true if the theme-specified background for a part has
205/// transparent pieces or alpha-blended pieces.
206//
208{
210 return m.IsThemeBackgroundPartiallyTransparent(GetHandle(), m_part, m_state);
211}
212
213//
214/// Creates a theme exception.
215//
217:
218 TXOwl(name), result (r)
219{
220}
221
222//
223/// Creates a copy of the exception
224//
225TXTheme*
227{
228 return new TXTheme(*this);
229}
230
231//
232/// Throws the exception.
233//
234void
236{
237 throw *this;
238}
239
240//
241/// Throws the exception.
242//
243void
245{
246 TXTheme(name, r).Throw();
247}
248
249
250} // OWL namespace
251
#define WARNX(group, condition, level, message)
Definition checks.h:277
#define TRACEX(group, level, message)
Definition checks.h:263
#define DIAG_DEFINE_GROUP_INIT(f, g, e, l)
Definition checks.h:429
ObjectWindows dynamic-link libraries (DLLs) construct an instance of TModule, which acts as an object...
Definition module.h:75
TRect is a mathematical class derived from tagRect.
Definition geometry.h:308
Encapsulates a theme handle.
Definition theme.h:108
HTHEME GetHandle()
Definition theme.h:115
virtual ~TTheme()
Releases the theme handle.
Definition theme.cpp:151
This singleton encapsulates the "uxtheme.dll" module.
Definition theme.h:32
static TThemeModule & GetInstance()
Returns the module instance.
Definition theme.cpp:91
bool IsBackgroundPartiallyTransparent()
Returns true if the theme-specified background for a part has transparent pieces or alpha-blended pie...
Definition theme.cpp:207
void DrawBackground(HDC, const TRect &dest)
Paints the background of the themed part.
Definition theme.cpp:166
void DrawTransparentBackground(HWND control, HDC, const TRect &dest)
Paints the background of the themed part, properly composited with the parent background.
Definition theme.cpp:189
TThemePart(HWND, LPCWSTR cls, int part, int state)
Constructs a theme part handler.
Definition theme.cpp:159
TXOwl is root class of the ObjectWindows exception hierarchy.
Definition except.h:38
void Throw()
Throws the exception.
Definition theme.cpp:235
TXTheme * Clone()
Creates a copy of the exception.
Definition theme.cpp:226
static void Raise(const tstring &name=tstring(), HRESULT=0)
Throws the exception.
Definition theme.cpp:244
TXTheme(const tstring &=tstring(), HRESULT=0)
Creates a theme exception.
Definition theme.cpp:216
#define _T(x)
Definition cygwin.h:51
Object Windows Library (OWLNext Core)
Definition animctrl.h:22
void InUse(const T &arg)
Handy utility to avoid compiler warnings about unused parameters.
Definition defs.h:299
OWL_DIAGINFO
Definition animctrl.cpp:14
std::string tstring
Definition defs.h:79
#define OWL_INI
Definition defs.h:170
Microsoft UxTheme Library Encapsulation.