The Managed UxTheme assembly is a .NET wrapper around Windows XP's Theme API.
It can be used safely from C#, on any Windows platform that supports the .NET
framework. In addition to exposing the UxTheme API, it also exposes the static
data in TmSchema.h (part of the Platform SDK) that is used to define what
window classes can be themed, the parts of those classes, and the states that
each part may have a custom look for.
Windows XP uses a C-style DLL to expose its theme functionality named
UxTheme.dll (the "Ux" stands for User eXperience). At my day job, I am
working on a couple of .NET custom controls written in C#. Of course one of the
requirements for these controls is that they use Windows XP themes when
appropriate, and mirror the user's current theme settings.
The problem with UxTheme.dll is that it is only available on Windows
XP, so any P/Invoke code that tries to use it directly will fail on other
versions of Windows. Pierre
Arnaud has written a C++ wrapper
DLL that can be safely called via P/Invoke on any .NET capable version of
Windows. His implementation uses David Y. Zhao's nice little C++ wrapper class
that dynamically links to UxTheme.dll, while also providing safe
fail-thru implementations of each method, if it can't load the UxTheme
I like Pierre's solution and started out by using it. It didn't however
provide me with the level of functionality that I need from UxTheme.dll.
My next thought was to extend his work and continue using P/Invoke from C#. I
have however been looking for an excuse to do something more than the "Hello
World!" in Managed C++, and this seemed like the perfect opportunity.
This implementation also uses David's wrapper class (as do almost all of the
examples of XP theme related code on CodeProject. It really is a nice piece of
There are two discrete parts of this assembly from the outside perspective.
The first is the
UxTheme class. This class provides a managed
wrapper around an
HTHEME handle. It exposes all of the methods on
the UxTheme DLL that takes an
HTHEME as instance method. Methods
that do not take a theme handle are exposed as static. Any thing it is possible
to do using the DLL's API should be possible through this class.
Parallel to this is an object hierarchy that wraps the property table data
created by TmSchema.h and Schemadefs.h. These two files are part
of the platform SDK and define the data model for what parts of the Windows UI
can be theme-ed.
This object hierarchy starts with the
ThemeInfo class. This
class contains some simple meta-data about the current theme, but also contains
a collection of
data about the parts of a particular window class. The
class has a collection of
ThemePart represents a discrete part of a window class. The
down button for instance, is part of the
ThemePart can have 0 to n
ThemePartStates are things like
UxTheme property that can be used to get an instance of the
UxTheme class specific for the window class.
ThemePartStates also contain some instance methods so that they
can be rendered directly into a graphics context.
UxTheme class can be used without the
hierarchy, but the hierarchy does put a more OO face on the whole thing.
Using the code
Using the code is pretty straightforward. All of the classes are in the
System.Windows.Forms.Themes. The only public ally
creatable class is
ThemeInfo. To drill your way down through the
window class, their parts and states, create an instance of
ThemeInfo and start looking through its collection of
WindowThemes on down.
You can get an instance of
UxTheme, either from an instance of
WindowTheme, or by calling either of the static methods
Make sure that you look at
UxTheme::IsAppThemed in you code
before trying to use any of the other methods of
UxTheme. This will
tell you whether the current OS supports themes and if so whether it is
currently themed. And don't forget, that this can change throughout the lifetime
of your application, because the user can turn off themes at any time.
The assembly does have a strong name, so you can put it in the GAC if you
The demo project contains a re-implementation of David's Theme Explorer
application, written in C# and using the managed API. It also include a
slight re-work of the TabPage
compatible controls that Pierre has made available. They are included merely
as a demonstration of how this assembly can be used from custom control
Points of interest
Managed C++ DLLs have some interesting constraints about entry points. Since
this DLL uses the C-Runtime it is a mixed mode DLL. It is compiled with the /NOENTRY linker
flag. Assemblies linked with this flag do no have an explicit entry point,
preventing the initialization of any static data aside from simple, integral
types. It would be nice to be able to use the
as a static instance, but because the runtime does not initialize it, this isn't
Each instance of
UxTheme creates a member pointer to an instance
methods create an instance of this class locally. The result of this is a lot of
FreeLibrary. Luckily Windows
keeps a reference count on dynamically loaded DLLs, so this shouldn't pose a
significant performance hit.
Be that as may, it is something that bugs me about my implementation. If
anybody's got a good way to load and free the UxTheme DLL just once, and avoid
creating so many instances of the C++ wrapper class I'd love to hear it. MSDN
recommends implementing explicit
Deinitialize methods, but I don't like forcing that on users of
- Version 1 - Initial release
- Bug fixes
- Some reorganization in the API