Click here to Skip to main content
15,881,084 members
Articles / Programming Languages / C++
Article

Applying Windows XP Visual Styles to Applications

Rate me:
Please Sign up or sign in to vote.
3.90/5 (22 votes)
30 Sep 2003CPOL3 min read 167.5K   2.2K   51   48
Apply Windows XP visual styles to applications without a rebuild.

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.

C++
//
// 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)


Written By
Software Developer (Senior) Axis First
United Kingdom United Kingdom
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionWorks but what should be changed for Vista/7? Pin
Mr Nukealizer14-Dec-10 15:00
Mr Nukealizer14-Dec-10 15:00 
AnswerRe: Works but what should be changed for Vista/7? Pin
Steve Thresher14-Dec-10 15:12
Steve Thresher14-Dec-10 15:12 
GeneralRe: Works but what should be changed for Vista/7? Pin
Mr Nukealizer17-Dec-10 6:59
Mr Nukealizer17-Dec-10 6:59 
QuestionIs it possible to embed XP theme (style) in an application without using manifest file..........? Pin
basawaraj15-May-08 21:24
basawaraj15-May-08 21:24 
QuestionIs it possible to embed xp style in an applicatio without manifest file.............? Pin
basawaraj15-May-08 21:12
basawaraj15-May-08 21:12 
QuestionWhat is the problem in creating manifest file..? Pin
basawaraj6-May-08 0:28
basawaraj6-May-08 0:28 
AnswerRe: What is the problem in creating manifest file..? Pin
Steve Thresher6-May-08 0:32
Steve Thresher6-May-08 0:32 
GeneralOffice 2003, Visual Studio 2005 and Windows Vista Styles Pin
Hugo González Castro17-Dec-07 4:30
professionalHugo González Castro17-Dec-07 4:30 
QuestionOwner draw tab control problem on Windows Vista Pin
Ramya_Indian6922-Mar-07 22:27
Ramya_Indian6922-Mar-07 22:27 
AnswerRe: Owner draw tab control problem on Windows Vista Pin
zpTal18-Apr-07 7:19
zpTal18-Apr-07 7:19 
GeneralIE Toolbar Problem Pin
HarishDixit4-Dec-06 20:39
HarishDixit4-Dec-06 20:39 
QuestionDoesn't work for x64 applications Pin
Hugo González Castro25-Jul-06 2:59
professionalHugo González Castro25-Jul-06 2:59 
AnswerRe: Doesn't work for x64 applications Pin
Steve Thresher25-Jul-06 4:07
Steve Thresher25-Jul-06 4:07 
GeneralRe: Doesn't work for x64 applications Pin
Hugo González Castro25-Jul-06 22:39
professionalHugo González Castro25-Jul-06 22:39 
Questionvalidating a single value form database Pin
vikas84singh18-Jun-06 22:08
vikas84singh18-Jun-06 22:08 
QuestionApplying themes to my VC# applications [modified] Pin
vikas84singh18-Jun-06 22:02
vikas84singh18-Jun-06 22:02 
AnswerRe: Applying themes to my VC# applications Pin
Member 80364468-Jul-11 7:47
Member 80364468-Jul-11 7:47 
GeneralExtending this to applications running in Win 2000 Pin
Andyzyx16-Jul-05 12:26
Andyzyx16-Jul-05 12:26 
GeneralRe: Extending this to applications running in Win 2000 Pin
Steve Thresher25-Oct-05 2:31
Steve Thresher25-Oct-05 2:31 
GeneralOne question. Pin
Prakash Nadar24-Apr-04 2:37
Prakash Nadar24-Apr-04 2:37 
GeneralRe: One question. Pin
Steve Thresher25-Apr-04 23:03
Steve Thresher25-Apr-04 23:03 
GeneralRe: One question. Pin
Prakash Nadar26-Apr-04 0:16
Prakash Nadar26-Apr-04 0:16 
QuestionWhat about Wizards and Tab controls Pin
Need Style8-Apr-04 13:35
sussNeed Style8-Apr-04 13:35 
QuestionHow about dll projects? Pin
LukeV30-Jan-04 10:53
LukeV30-Jan-04 10:53 
AnswerRe: How about dll projects? Pin
Steve Thresher2-Feb-04 1:59
Steve Thresher2-Feb-04 1:59 

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

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.