qt8gt0bxhw|20009F4EEE83|RyanMain|subtext_Content|Text|0xfbffc40000000000b600000001000400
When you build Windows applications in .NET, by default your application will not have support for XP Themes, or Visual Styles. It is an easy enough task to do, and I think it goes a long way in giving your application a complete and professional look & feel. When Windows Forms 2.0 comes out with Visual Studio 2005 support for XP themes will be enabled by default in your Windows applications. However, for now you have two options for enabling XP theme support. These options are not new news or anything, but I did want to point out some problems with one of these methods (see option 1).
Before we get into these options, remember what enabling visual themes is really doing. Windows XP/2003 ships with two versions of the Common Controls library (comctl32.dll). Versions 5.8 and 6.0. Version 5.8 renders controls using the standard classic look that we've seen before, such as in Windows 2000 and 9x etc. Version 6.0 renders controls with the XP themed look and feel. So enabling visual styles in your application is nothing more than just creating an activation context around the application's message loop that redirects calls to comctl32 functions to version 6.0 of the comctl32.dll. Creating activation contexts is not that easy of a task and is definitely more work than it is worth to just get a themed look. When we get into these options we'll see that these give us some easier ways to provide this redirection to the version 6.0 of comctl32.
Option 1
With .NET 1.1 there was a new static method introduced in the Application class called EnableVisualStyles. This method enables visual themes in your application if the operating system supports it. Calling EnableVisualStyles causes all controls to be drawn with visual styles, so it must be called before any controls are drawn for the application. Typically, you will call EnableVisualStyles as the first thing in your main function - before your call to Application.Run.
[STAThread]
static void main()
{
Application.EnableVisualStyles();
Application.Run(new Form1());
}
That is it. Easy enough. Basically, what EnableVisualStyles does is wrap the code to create the activation context and provide the redirection to the correct version of comctl32. However, this option does have it's problems. And some big ones too. Many .NET developers will likely already know about EnableVisualStyles, but I'll get questions all the time from developers that do not understand why it does not work at times and other problems in their application that are as a result of the call to EnableVisualStyles. First of all, since what EnableVisualStyles is doing is setting up an activation context around the message loop, any comctl32 handles created after the message loop is set up will be redirected to comctl32 version 6.0. However, there are cases when the form will be created, which calls the constructor and the call to InitializeComponent, before the message loop gets created. You can get around this by adding a call to the static DoEvents (Application.DoEvents();) inbetween the call to EnableVisualStyles and Run. This will give the application the ability to completely setup the message loop before the form is created. When this problem happens, handles created in InitializeComponent will get created as version 5.8 comctl32 handles. You'll get some problems especially with ImageLists. Having a v5.8 ImageList does not interop well with v6.0 controls, such as ListViews and TreeViews. So this will cause the images to not show up. Other controls will not appear themed. At times I'll get critical exceptions halting execution of the application due to interop inconsistencies between the v5.8 handles and v6.0 controls. I tend to stay away from this option because of these problems, but in most cases a simple call to DoEvents will solve the issue. One thing to note here is that these problems are fixed in .NET 2.0 (which is a good thing since EnableVisualStyles is called by default for Windows applications.
Option 2
Instead of calling EnableVisualStyles, you can use a manifest file. This manifest file will cause the application to redirect comctl32 calls to the version 6.0 DLL when available. The issues discussed in option #1 do not happen with this option. This way does give you a safe, problem free way to enable visual styles, but it does create the need to distribute another file (and a use could delete that file which would make your application appear un-themed). You do not need to be the author of an app to create a manifest for it. It is a separate text file that you could create for any application, whether it is one that you built or not, to give it a themed look. A manifest file looks like this:
<?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="Executable Name"
type="win32"
/>
<description>Application description</description>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="X86"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
</assembly>
Note: Blog reader Charles pointed out in the comments that some of the characters were lost in the formatting as HTML leaving the XML malformed. I've fixed the post so all should be good now. Sorry for any headaches that might have caused. Thanks Charles.
You create a text file, add this text to it (modifying the Executable Name) and then name the file the same name as your exe (including the 'exe' extension part) with an extionsion of 'manifest'. For example, if your exe is named MyApp.exe, then you'd name the manifest file MyApp.exe.manifest and put it in the same directory as your exe. That is it. This will bind the application to the version 6.0 comctl32.dll. BTW, you can also add this manifest file into the application's resources. To do this you add it into the resources and give it a type of RT_MANIFEST with an ID of 1. Easy enough to do, but you'd have to add it back into the resources every time you recompile your app. I'm fine with just distributing the manifest file separately. No big deal to me.
Either option you choose to use, you also need to set any control with a FlatStyle property to 'System'. Using a FlatStyle of system will allow the FlatStyle to be determined by the operating system. You could use a loop to iterate through any controls that have a FlatStyle property, or just set it manually at design time. This is also something you won't have to do with Windows Forms 2.0 as it will happen automatically. But for now, you have to set this for any control that derives from System.Windows.Controls.ButtonBase.
Whether you personally like visual themes or not, the fact is that many of the users of your applications do. Since XP themes are on by default for new installs, chances are that most of your users on XP will have themes on. IMO not allowing your application to support themes gives the impression that there is something missing from your application. It is an easy enough task to do, so I say take the time to do it. As I stated earlier, all of this will be built into Windows Forms 2.0, but for now don't leave your applications looking stale.