In this article, you will see a wrapper class for the HTHEME handle used in connection with the Visual Styles API available in Windows XP. The class is heavily based on the CVisualStylesXP class by David Yuheng Zhao.
Introduction
This is a wrapper class for the HTHEME
handle used in connection with the Visual Styles API available in Windows XP. This article and the code provided is heavily based on Add XP Visual Style Support in OWNERDRAW Controls by David Yuheng Zhao. To understand this article and the code provided, I strongly recommend that you read that article.
The class provided is based on the CVisualStylesXP
class described in the previously mentioned article, indeed several portions of the code are copied directly, but some major conceptual changes have been made. Instead of the handle to the uxtheme.dll being a normal member of the CVisualStylesXP
class, it has been made static
in CXPTheme
, resulting in a single load per application. Also, the function pointers returned by GetProcAddress
are cached in static
function pointers, which are then used in subsequent calls. In the situation where the DLL is not available, the addresses of special failure member methods providing reasonable responses are assigned to these static
function pointers instead. This results in a highly optimized execution.
A more significant difference for the users of this class is the fact that CXPTheme
wraps the HTHEME
handle. This provides a more object-oriented approach to using the API. Unless specifically needed, the user never interacts directly with the HTHEME
handle. Instead, the handle is kept in a member variable and internally applied where necessary. The handle is closed in the class destructor. The class provides several constructors and overloaded operators for ease of use.
The API functions not directly related to a HTHEME
are created as static
member methods, not requiring an instance of the class. In addition, the static
member method IsAvailable
has been added for a specific check on whether the current platform supports theming. In most cases, it will suffice to use the IsAppThemed
API function because the corresponding special failure method will return FALSE
on platforms which do not provide theming, signalling "old-style" drawing.
How to Use
The class is very easy to use. First, you need to include the header, preferably in stdafx.h and add the CPP file in the project.
#include "XPTheme.h"
Then you can either create a local CXPTheme
variable where needed, or add it as a class member of the control.
CXPTheme theme(GetSafeHwnd(), L"TOOLBAR");
theme.DrawBackground(pDC->GetSafeHdc(), TP_BUTTON, TS_CHECKED, &rc, 0);
To make your application work under all Windows versions, you should do something like this:
#ifdef _XPTHEME_H_
if (CXPTheme::IsAppThemed())
{
CXPTheme theme(GetSafeHwnd(), L"TOOLBAR");
theme.DrawBackground(pDC->GetSafeHdc(), TP_BUTTON, TS_CHECKED, &rc, 0);
}
else
{
#endif
pDC->DrawEdge(....);
#ifdef _XPTHEME_H_
}
#endif
The preferred way to use this class would probably be to make it a control member variable which is initialized in the control constructor. Once the control is deleted, the CXPTheme
variable will be deleted as well, and the handle closed safely. The control should handle the new WM_THEMECHANGED
message, and close and reopen the theme using the Close
and Open
member methods. Actually, the Open
method could be used alone, because an open handle is closed automatically before opening a new one.
case WM_THEMECHANGED:
m_theme.Close();
m_theme.Open(GetSafeHwnd(), L"TOOLBAR");
break;
The download includes the class itself in addition to three header files taken from the Platform SDK. These are necessary to compile the code without the latest SDK. For the same reason, a typedef
for the WM_THEMECHANGED
message has been added to the XPTheme.h file.
History
- 30th January, 2002: Initial version
License
This article has no explicit license attached to it, but may contain usage terms in the article text or the download files themselves. If in doubt, please contact the author via the discussion board below.
A list of licenses authors might use can be found here.