For those who remember the Common Controls OCXs featured in Visual Basic 5 and 6, there was one peculiarity of these. In Visual Basic 5, the Common Controls were linked directly to their shell counterparts. As the shell was updated, so did the look of any VB app using these. However, for Visual Basic 6, this behaviour was changed and they didn't use the shell for drawing.
Curiously enough, history repeats itself in a limited way with Visual Studio .NET. If you use the ListView
or TreeView
controls on Windows Vista or higher, you'll find they are somewhat drawn according to the "classic" Windows style - no gradients on selection highlights, column separators (ListView
) or alternate +/- glyphs (TreeView
).
Fortunately however, it is quite simple to enable this with a single call to the SetWindowTheme
API when creating the control.
[DllImport("uxtheme.dll", CharSet = CharSet.Unicode)]
public extern static int SetWindowTheme(IntPtr hWnd, string pszSubAppName, string pszSubIdList);
In the sample application (available for download from the link above), we create two new ListView
and TreeView
classes which inherit from their System.Windows.Forms
counterparts.
In each class, override the OnHandleCreated
method, and check to see what OS is being run - if you try to call SetWindowTheme
on an unsupported OS, you'll get a crash. In this case, I'm checking for Windows Vista or higher.
If the version is fine, call SetWindowTheme
with the handle of the control, and the name of the shell style - explorer in this case.
It's as simple as that - now when you run the application, the controls will be drawn using whatever shell styles are in use.
using System;
namespace ShellControlsExample
{
class TreeView : System.Windows.Forms.TreeView
{
protected override void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated(e);
if (!this.DesignMode && Environment.OSVersion.Platform ==
PlatformID.Win32NT && Environment.OSVersion.Version.Major >= 6)
NativeMethods.SetWindowTheme(this.Handle, "explorer", null);
}
}
}
For the TreeView
control, I'd also recommend setting the ShowLines
property to false
as it will look odd otherwise.