Tuesday, July 17, 2007

Application.EnableVisualStyles()


Alrighty, I just found a solution to something that's been bugging me for quite a while. When you create a standard .NET 1.1 Windows desktop application with Visual Studio .NET 2003, the user interface elements (controls) look like those on the left of the picture. They're very much Windows-like, but basically very plain - kind of old-school Windows 2000 era looking. However, when you create a standard desktop app with Visual Studio 2005 based on .NET 2.0, the controls have a much more modern look that we're all used to by now (as seen on the right picture). A little snazzier and much for Windows XP looking with the shaded button, colored slider, etc.

This is all find and dandy. But now say you have a VS 2003 (7.1) project that gets converted to VS 2005 (8.0). With all the version 2.0 assemblies linked in, I expected the converted, re-built application to look just like a standard .NET 2.0 app. It didn't. It still looked old-school. Everything looked to convert without issues, and many of the ancillary XML files were similar. I was missing any differences until I finally looked at the source code of an application written in VS 2005. By default, the main method looks like:
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}

See? Trickiness here. A normal VS 2003 application only has the single Run() method call. The key addition that changes the user interface look is the first one - EnableVisualStyles(). There's some good background information on this blog. Turns out you can add this to a .NET 1.1 application as well. Not all the elements are updated, but at least the method call is backwards compatible so you can add it to your code and still build in either .NET 1.1 or 2.0. But the key point is that in their infinite wisdom, MS decided that they'd add something to the default template for desktop applications to make your .NET apps look better on newer versions of Windows. I can't hold that against them, but it seems like a strange way to do this - adding extra lines to the Main() method. But then again, if they had done something sneakier, everyone would complain about that too.

They've also added the SetCompatibleTextRenderingDefault method call also. This is another line to basically make up for changed internal things - they fixed the text rendering engine, but if you relied on the old one for spacing, things could get messy. More info here. Instead of sneaking this in the back door and moving everyone to the new model, they added this explicit call to the template. Again, kind of messy but the best way I guess. I can just see the Main() method for Forms applications when .NET 6.0 comes out -- 28 different method calls to make sure things still work OK for .NET 1.1. I wonder why Java doesn't suffer from such problems?

There you have it. For newbs that are just seeing Windows.Forms since VS Express stuff came out, none of this matters. Unless you want to uglify your desktop apps and make them look old by removing these new method calls. But for .NET 1.1 app writers, you can beautify your apps a bit by using the OS visual styles. And for those of us that are always moving between platform versions, it's a good feeling to find out why things change sometimes. I'll admit that I should have noticed this sooner, but .NET 2.0 and VS 2005 now does the partial class thing, so the Main() method is in a source file called Program.cs instead of with all the design stuff as it is in 1.1 and 2003. Oh well, eventually I dug it out myself because searching the internet was useless here. All the search terms you would use just lead you in circles because they're too common or too many are needed. Searching for "user interface change visual studio 2005" is a good example -- lots of stuff, but nothing even close to the issue I'm trying to solve.

No comments: