The new vbAccelerator Site - more VB and .NET Code and Controls
Source Code
1 VB 5 Custom Controls &nbsp

DevStudio style flat headers

Give the ListView and S-Grid control a fresh new look with this class

ListView with Flat Header

Download the Flat Header Class and Demo (16kb)

&nbsp Before you Begin &nbsp
&nbsp This project requires the SSubTmr.DLL component. Make sure you have loaded and registered this before trying the project. &nbsp

One feature I've been getting more and more requests for is a way of creating a flat header like the one in the Tasks window of DevStudio version 6.

The sample project presents a class which does this to great effect, and works with all controls using the COMCTL32.DLL header control as well as the VB6 header control implemented in MSCOMCTL.OCX.

How it Works As is usual with Microsoft, the flat header in the DevStudio task list is not actually implemented using a COMCTL32.DLL window. The DevStudio task list is actually a window of class "RTaskList" which includes the header in the same window as the rest of the grid. I guess having the source code to all controls available (and an all but unlimited development budget) makes it a bit easier to create windows like this from scratch!

Investigating the COMCTL32.DLL documentation at MSDN shows that there is no style you can turn on for a header control to get the flat effect. The same effect can be achieved, however, by intercepting the WM_PAINT message for the Header control after it has completed painting and then drawing over the existing 3D border so the control has a thinner 3D border, as shown in the diagram below:

Border painting diagram
Diagram showing borders affected by the Flat Header drawing routine
The flat header code is encapsulated into a class called cFlatHeader. The first method is a method to attach the class to the correct window handle so it can subclass the WM_PAINT message. Since most controls do not expose a hWnd property for the Header control, the class uses the FindWindowEx API method to detect whether the supplied window has a child of the correct type. The header control will have one of the following classes:

Class Name Used By
SysHeader32 COMCTL32.DLL header controls; Microsoft's VB5 ListView control (COMCTL32.OCX); vbAccelerator S-Grid and Header control. Note that this class name is valid for both ANSI and Unicode versions of the control.
msvb_lib_header Microsoft's VB6 ListView control (MSCOMCTL.OCX)

Having obtained a Window handle, intercepting the WM_PAINT message is achieved by using the Subclassing and Timer Assistant. Setting the MsgResponse property to emrPreProcess ensures that the control processes all paint messages first and then the class gets the message.

Finally, the code processes WM_PAINT messages by overdrawing the borders as shown above. This code is a bit tedious, the only important parts of the code are to note that you get the hDC of the control to draw into using the GetDC method, and to make sure that if you call GetDC you don't forget to subsequently call ReleaseDC!

Using the Class
This is the simple bit! Just reference SSubTmr.DLL from your project (choose Project->References and then pick "Subclassing and Timer Assistant (with multi-control support and timer bugfix)" ) and then add cFlatHeader to your project.

With this in place you only need two lines of code in the form containing the control you want to have a flat header:

Private m_cFH As New cFlatHeader

Private Sub Form_Load()
m_cFH.Attach lvw.hWnd
End Sub

The same code applies to the ListView in VB5 or VB6, the S-Grid control and the Header control. Subsequent releases of the S-Grid control will include this code (and also future Owner-Draw header modifications to improve the reliability of the header bitmap and icon rendering).


TopBack to top
Source Code - What We're About!Back to ActiveX Control Source Code
Source Code - What We're About!Back to Source Code


AboutContributeSend FeedbackPrivacy

Copyright 1998-1999, Steve McMahon ( All Rights Reserved.
Last updated: 15 August 1999