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

Applying Windows XP Visual Styles to Applications

By , 30 Sep 2003
 

Introduction

I've wanted to write an article for The Code Project as it's provided me with some very useful information in the past and it would be nice to give something back. The main problem was finding an appropriate topic for a first article, which I hope I've now found. So here goes...

Background

With Windows XP came themes, which is basically just a new look for all the common controls such as buttons and scroll bars. The following images give you an idea of what to expect.

Sample image

Classic Windows

Sample image

Windows XP Themes

This takes a bit of getting used to, especially if you've been using Windows for a long time, but if you stick with it for a while I'm sure you will learn to like it as I have. The downside to the new themes is that you need to tell Windows that your application should make use of the new style common controls. As far as I'm aware there are two ways of achieving this:

  • Create an application manifest file named MyApp.exe.manifest in the same directory as the application
  • Create an application manifest file and add it to the list of resources built into the application

Neither option was appropriate for our software package as it contains over 500 functions, each being a separate EXE file. This would have meant generating several hundred manifest files and, if the first method was selected, modifying the CD production mechanism to add the files to the installation CD and modifying the setup program to install them. This would have been a very time consuming process and also not very flexible should the manifest file format change in the future.

The solution I came up with was to dynamically add the application manifest resource outside of the build procedure which gives us the advantage of keeping the application manifest in one source module allowing changes to be made quickly should the format change. This article explains how to do it.

Using the code

The code is contained within one function, shown below, that can be simply dropped into any program as required. The only drawback is that the resource manipulation API functions are only supported under NT based operating systems. I've tried to document the code as fully as possible but if there is anything missing or unclear, please let me know and I will change it.

//
// Add the XP style manifest to a specified applcation 
// 
DWORD AddManifest(const char *szFilespec, 
   const char *szProgName,const char *szProgDesc)
{
    // This is the formatting string used to create the manifest
    static LPSTR szFormat=    
     "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"
     "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
            "<assemblyIdentity "
            "version=\"1.0.0.0\" "
            "processorArchitecture=\"x86\" "
            "name=\"%s\" "
            "type=\"win32\" />" 
        "<description>%s</description>"
        "<dependency>"
        "<dependentAssembly>"
            "<assemblyIdentity type=\"win32\" "
                "name=\"Microsoft.Windows.Common-Controls\" "
                "version=\"6.0.0.0\" " 
                "publicKeyToken=\"6595b64144ccf1df\" "
                "language="\""*\" " 
                "processorArchitecture=\"x86\"/>"
            "</dependentAssembly>"
            "</dependency>"
        "</assembly>";

    // Load the EXE so we can check if the resource already exists
    HMODULE hMod=LoadLibrary(szFilespec);
    if (NULL==hMod)
        return(GetLastError());
    
    // Attempt to find the manifest (resource type 24, id 1)
    HRSRC hRes=FindResource(hMod,MAKEINTRESOURCE(1),MAKEINTRESOURCE(24));

    // The EXE must be released before we can update the resources
    FreeLibrary(hMod);

    // If the manifest resource is not already present in the EXE
    if (NULL==hRes)
    {
        // Load the program ready for updating
        HANDLE hUpdate=BeginUpdateResource(szFilespec,FALSE);
        if (NULL==hUpdate)
            return(GetLastError());

        // Allocate a buffer to store the manifest string
        char *szManifest=new char[strlen(szFormat)+
                                  (szProgName ? strlen(szProgName) : 0)+
                                  (szProgDesc ? strlen(szProgDesc) : 0)+1];

        // Format the manifest to include the
        // specified program name and company name
        wsprintf(szManifest,szFormat,
           szProgName ? szProgName : "",szProgDesc ? szProgDesc : "");
    
        // Add the manifest resource to the list
        // of updates to be made (resource type 24, id 1)
        BOOL bUpdateSuccessful=UpdateResource( hUpdate,
                                MAKEINTRESOURCE(24),
                                MAKEINTRESOURCE(1),
                                MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_UK), 
                                szManifest,(DWORD)strlen(szManifest));
        // If the update was rejected
        if (!bUpdateSuccessful)
        {
            // Save the last error code
            DWORD dwLastError=GetLastError();

            // Release the memory allocated for the manifest string
            delete[] szManifest;

            // Abandon the resource changes and exit
            EndUpdateResource(hUpdate,TRUE);
            return(dwLastError);
        }

        // Release the memory allocated for the manifest string
        delete[] szManifest;

        // Apply the change to the specified EXE file
        if (!EndUpdateResource(hUpdate,FALSE))
            return(GetLastError());
    }

    // Resource modified successfully
    return(0);
}

Points of interest

The most annoying problem I encountered while developing this function is that the manifest resource cannot be added if the specified file is open in any way. This includes the use of LoadLibrary() to check if the resource already exists! All the functions used return success values and you will be totally unaware that the update has failed until you try to run the application.

More information

My main source of information for this article can be found on MSDN here. Alternatively there is an excellent article by Kluch on this site here.

Conclusion

Well that's it, my first article written and ready to be picked apart by the Code Project community. I'd just like to say a quick "thank you" to Kluch whose article gave me both the inspiration and information necessary to write this article. I await your comments...

History

01-10-2003 - First edition

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Steve Thresher
Software Developer (Senior) Axis First
United Kingdom United Kingdom
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

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionWorks but what should be changed for Vista/7?memberMr Nukealizer14 Dec '10 - 15:00 
The method shown worked for me (Windows 7 x64) once I took Steve Thresher's suggestion for x64 compatibility. However I see some version numbers in the manifest that seem outdated, so I was wondering what (if anything) should be changed for Windows Vista/7.
 
"Learn from the mistakes of others. You can't live long enough to make them all yourself."-Unknown
AnswerRe: Works but what should be changed for Vista/7?memberSteve Thresher14 Dec '10 - 15:12 
Our manifest hasn't changed since it was first implemented and it worked fine on Vista / Windows 2008 Server and stills works on Windows 7 / Windows 2008 Server R2. As long as you're requesting version 6 of the common controls DLL you'll be able to make use of visual styles. Is there any particular aspect of the API that concerns you?
AxisFirst For Business

GeneralRe: Works but what should be changed for Vista/7?memberMr Nukealizer17 Dec '10 - 6:59 
Steve Thresher wrote:
Our manifest hasn't changed since it was first implemented and it worked fine on Vista / Windows 2008 Server and stills works on Windows 7 / Windows 2008 Server R2. As long as you're requesting version 6 of the common controls DLL you'll be able to make use of visual styles. Is there any particular aspect of the API that concerns you?
AxisFirst For Business
 

No. Like I said it works fine I was just wondering if it would be a good idea to change anything for compatibility reasons as I see version="5.1.0.0" and type="win32" which I know are not current as of Windows 7 x64.
"Learn from the mistakes of others. You can't live long enough to make them all yourself."-Unknown

QuestionIs it possible to embed XP theme (style) in an application without using manifest file..........?memberbasawaraj15 May '08 - 21:24 
Dear Steve Thresher,
 
I need solution for enabling or embeding xp themes for an application without manifest file.
 
previously I have used compiler directive
 
#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")

It works fine in Visual Studio 2005,but I want solution work for all VS versions?
 
I need solution for all VS versions
QuestionIs it possible to embed xp style in an applicatio without manifest file.............?memberbasawaraj15 May '08 - 21:12 
Dear Steve Thresher,
 
I need solution for embeding XP style in an application without manifest file,
 
I have used compiler directive (It is compiler dependent)
 
#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
 
in VS2005 It works fine, but I need solution for all VS versions .
 
please any one explain me about this problem...!
 
Thanks,
Basavaraj.
QuestionWhat is the problem in creating manifest file..?memberbasawaraj6 May '08 - 0:28 
Hi ....
 
When I run this function ,I am getting manifest file with not copied the formatting string (xml code)completely....
AnswerRe: What is the problem in creating manifest file..?memberSteve Thresher6 May '08 - 0:32 
I don't understand the problems you're having. If you send me your test project I'll have a look and try to help.
 
Email address: steve dot thresher at gmail dot com
GeneralOffice 2003, Visual Studio 2005 and Windows Vista StylesmemberHugoGC17 Dec '07 - 4:30 
Is there a way to change my MFC 6.0 applications to have Office 2003, Visual Studio 2005 or Windows Vista Styles in a similar way as descrbed in this article? Thanks in advance,
 
Hugo
QuestionOwner draw tab control problem on Windows VistamemberRamya_Indian6922 Mar '07 - 22:27 
I am working on the UI application for a mouse driver.The UI has around 6-7 tabs in its tab control.We need to redraw two of those tabs based on the user's option.To do so,We are setting the tab control style of the tab as ownerdrawfixed and on getting the WM_DRAWITEM message,We call textout() to make the text of the tab gray in color.This application works fine on XP but on Vista,the tabs lose their theme(the controls in the tab like Check boxes and buttons still retain the Vista theme).If we donot set the tab style as ownerdrawfixed,the tabs regain their theme but I would not be able to redraw the text of the tabs.
What could be going wrong with the application?How can I get back the Vista theme to the tabs and also redraw the text of the tabs in gray?
 
Thanks,

AnswerRe: Owner draw tab control problem on Windows VistamemberzpTal18 Apr '07 - 7:19 
You need to use theme APIs, look for DrawThemeParentBackground, DrawThemeBackground, DrawThemeText etc. in uxtheme.lib
GeneralIE Toolbar ProblemmemberHarishDixit4 Dec '06 - 20:39 
Hello to all,
 
I m creating a toolbar for IE (ATL DLL). I implemented XP style using
manifest file. It works fine. But
i have a problem after XP style conversion, my buttons height has been
increased. Before XP style
button size was (height,width) ~ (22 , 81).
After XP style it become (30 , 87). But my toolbar width is same is 22.
 
due to this buttons are not fitting on toolbar and buttons bottom is
greater than toolbar bottom edge.
 

can someone plz help me how to solve it
 
Thanks in advance
 
Harish
QuestionDoesn't work for x64 applicationsmembernaflat25 Jul '06 - 2:59 
Hello, I have seen when compiling this code for 64 bits (x64 machine) this manifest doesn't work because of the tag: processorArchitecture="x86" and type="win32".
 
If I put "x64" or "amd64" or "win64" instead, it neither works...
Anyone knows how to use Visual Styles under x64?
 
Many thanks,
 
Hugo
AnswerRe: Doesn't work for x64 applicationsmemberSteve Thresher25 Jul '06 - 4:07 
Try replacing the value with an asterisk.
 
processorArchitecture="*"
 
AxisFirst For Business

GeneralRe: Doesn't work for x64 applicationsmembernaflat25 Jul '06 - 22:39 
Thank you very much, now it works perfectly!
 
Hugo
Questionvalidating a single value form databasemembervikas84singh18 Jun '06 - 22:08 
Hello, I want to create a validating form in which the user name snd its password must get evaluated from the database when ever the user enters his id and password. I am unable to make it using VC#. I am able to establish a connection to the database but just to retrive a value and eualuate it made my work more difficult.
 
Crack the core
QuestionApplying themes to my VC# applications [modified]membervikas84singh18 Jun '06 - 22:02 
I want to apply Xp themes in my application. I want the visual effects and the styles of xp to be used in my application. but I am unable to do so can you help me out. can you send the code via mail my mail id is vikas84singh@gmail.com.
 
Crack the core
 
-- modified at 4:08 Monday 19th June, 2006
AnswerRe: Applying themes to my VC# applicationsmemberMember 80364468 Jul '11 - 7:47 
Use Application.EnableVisualStyle().
GeneralExtending this to applications running in Win 2000memberAndyzyx16 Jul '05 - 12:26 
Hi,
 
It was a nice article.
I am looking at extending this to my application (in which the controls are created at runtime in the program) and run the application in Windows 2000 ( without any Win XP theming loaded by default).
Can I do this for my windows application running on Windows 2000 as well ?. Please provide me any suggestions that you may have on this to get the desired effect.
 
Thanks
Andy

GeneralRe: Extending this to applications running in Win 2000memberSteve Thresher25 Oct '05 - 2:31 
Not really sure what you're asking for. You can build a manifest file into an executable and run it on Windows 2000 with no problems as the Windows loader will not be looking for it. The only thing you need to worry about is using the theme API. The theme DLL will not exist at Windows 2000 so you will need to dynamically link to it (LoadLibrary / GetProcAddress).
 
AxisFirst For Business
GeneralOne question.memberMr.Prakash24 Apr '04 - 2:37 
Will this work for applications developed using Visual C++ ver6.
 

God is Real, unless declared Integer.
GeneralRe: One question.memberSteve Thresher25 Apr '04 - 23:03 
As long as the program calls InitCommonControls() it doesn't matter what you build it with.
 
Systems AXIS Ltd - Software for Business ...
GeneralRe: One question.memberMr.Prakash26 Apr '04 - 0:16 
yeah true, i got the problem figured it out and now its working.... Thanx for the article.
Big Grin | :-D
 

God is Real, unless declared Integer.
QuestionWhat about Wizards and Tab controlssussNeed Style8 Apr '04 - 13:35 

I am trying to get XP Visual Styles on my wizard pages. When I do what has been suggested for my wizard, the buttons (next back etc) are in the correct style, but any control on the pages them selves are not.
 
This is also the same for my tab control.
 
Any idea how to get the "children" to display the sytles as well?
QuestionHow about dll projects?memberLukeV30 Jan '04 - 10:53 
I've been trying to figure out how to apply visual styles to my dll projects for months! It's a plug-in for Outlook and since the application does not use XP styles, my plug-in won't display styles either.
 
How can I do that?
 
---------------
Tired of Spam? InboxShield for Microsoft® Outlook® 2K/2K2/2K3
http://www.inboxshield.com
AnswerRe: How about dll projects?memberSteve Thresher2 Feb '04 - 1:59 
Have you looked at the MSDN document specified at the bottom of the article?
 
I've managed to get a shell extension to work properly by adding the line "#define ISOLATION_AWARE_ENABLED 1" before including commctrl.h and setting the value of the the resource id for the manifest to ISOLATIONAWARE_MANIFEST_RESOURCE_ID which basically equates to 2.
 
What have you tried so far?
 

 
Systems AXIS Ltd - Software for Business ...

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

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130516.1 | Last Updated 1 Oct 2003
Article Copyright 2003 by Steve Thresher
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid