Click here to Skip to main content
Click here to Skip to main content

Adding XP Visual Style Support to OWNERDRAW Controls Using HTHEME Wrapper

By , 29 Jan 2002
 

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, is 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);
// the handle is closed when the variable goes out of scope.

To make your application working 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.

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

About the Author

Pål K Tønder
Web Developer
Norway Norway
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
Hint: For improved responsiveness ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralI want use xp visual style in the IE toolbarmemberAllenDog11 Dec '04 - 11:10 
GeneralTheme change kills XP look on CDialogBarmemberpixelgrease18 Sep '03 - 11:05 
I haven't investigated this much to see if it happens on regular dialogs; I have a CDialogBar that has its own share of problems and this may be one of them.
 
Simply, changing the Color Scheme kills the CColourPickerXP's ability to draw correctly. After I change the Color Scheme to "Olive Green" or "Silver" (something other than the current scheme), the button no longer draws although the text and color box do. To get the button to draw correctly I must restart my app.
 
The simple fix was to handle the WM_THEMECHANGED message. I added the following to the BEGIN_MESSAGE_MAP block:
 
ON_MESSAGE (WM_THEMECHANGED, OnThemeChanged)
 
For code, I snagged the CColourPickerXP::OnNMThemeChanged() block and changed the return value:

= 0x0501.
#ifdef _THEME_H_
    m_xpButton.Open(GetSafeHwnd(), L"BUTTON");
    m_xpEdit.Open(GetSafeHwnd(), L"EDIT");
    m_xpCombo.Open(GetSafeHwnd(), L"COMBOBOX");
#endif
    Invalidate(FALSE);
    return 0;
}

 
I haven't seen the OnNMThemeChanged section catching any messages so I'm not certain it has a job to do. Perhaps the WM_THEMECHANGED message is more reliable?
 
- Stan

Old programmers never die, they just stop responding to interrupts.
GeneralParts and StatesmemberArmen Hakobyan25 Aug '02 - 7:17 
GeneralRe: Parts and StatesmemberZorglab11 Jan '03 - 5:16 
GeneralBS_ICON + Theme in Windows XPmemberErwin Richard15 Mar '02 - 4:41 
GeneralI don't really understand...memberAnonymous28 Feb '02 - 6:51 
GeneralRe: I don't really understand...memberPaul A. Howes28 Feb '02 - 7:17 
GeneralRe: I don't really understand...memberAnonymous28 Feb '02 - 8:05 
GeneralRe: I don't really understand...memberPaul A. Howes28 Feb '02 - 10:16 
GeneralNasty Bug!memberswinefeaster8 Feb '02 - 21:21 
GeneralThanks for inputmemberPål K Tønder10 Feb '02 - 21:19 
GeneralRe: Thanks for inputmemberswinefeaster10 Feb '02 - 21:38 
GeneralRe: Thanks for inputmemberPål K Tønder11 Feb '02 - 2:17 
GeneralI Just Want To Draw A Stupid Button!memberswinefeaster7 Feb '02 - 12:37 
GeneralRe: I Just Want To Draw A Stupid Button!memberPål K Tønder7 Feb '02 - 20:47 
GeneralWP_MINBUTTONmemberswinefeaster6 Feb '02 - 22:10 
GeneralRe: WP_MINBUTTONmemberPål K Tønder6 Feb '02 - 23:27 
GeneralRe: WP_MINBUTTONsussdaymz31 Jan '03 - 7:11 
GeneralNon Owner Draw Buttons and Controlsmemberswinefeaster6 Feb '02 - 21:03 
GeneralRe: Non Owner Draw Buttons and Controlsmemberswinefeaster6 Feb '02 - 23:17 
QuestionWorks on all versions of Windows or Not?memberswinefeaster5 Feb '02 - 20:58 
AnswerRe: Works on all versions of Windows or Not?memberPål K Tønder5 Feb '02 - 21:43 
GeneralRe: Works on all versions of Windows or Not?memberswinefeaster6 Feb '02 - 9:14 
GeneralRe: Works on all versions of Windows or Not?memberPål K Tønder6 Feb '02 - 20:43 
GeneralA demo project wantedmemberyellowine31 Jan '02 - 3:29 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130516.1 | Last Updated 30 Jan 2002
Article Copyright 2002 by Pål K Tønder
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid