OWLNext    7.0
Borland's Object Windows Library for the modern age
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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.