Outlook 98-Style FlatHeader Control
This FlatHeader control is my contribution to the effort of mimicking all the new Microsoft flat style controls. Apart from the look and feel of the Outlook 98 Header control, it extends the functionality of the standard Header control with the following features:
- Optional size constraints,
- Optional sorting arrow (without loosing the image nor bitmap options),
- Fixes for the FULLDRAG redraw problem (images are not properly redrawn in a standard Header control).
It should be backward compatible wit the standard Header control in most cases (even for owner drawn header items), although the current implementation lacks the following features:
- Item Text callbacks
- Item Image callbacks
- Hottracking
- RTL reading
- Unicode (not properly tested).
Depending on the feedback and my needs, I'll extend the implementation with proper support for these features.
The control can be applied as a straight dropin replacement for the standard Header control by subclassing the standard Header control of a CListCtrl control, by overiding the PreSubclassWindow() in the CListCtrl:
void CFlatListCtrl::PreSubclassWindow()
{
CListCtrl::PreSubclassWindow();
VERIFY(m_wndFlatHeader.SubclassWindow(::GetDlgItem(m_hWnd,0)));
}
Or in a CListView:
int CFlatListView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CListView::OnCreate(lpCreateStruct) == -1)
return -1;
if (m_wndFlatHeader.SubclassWindow(GetListCtrl().GetDlgItem(0)->GetSafeHwnd()) == 0)
{
TRACE0("Unable to subclass header control.\n");
return -1;
}
return 0;
}
Refer to the Demo project (or various CodeGuru articles) for more information on using a subclassed header control in List controls or List views.
The control is derived from CHeaderCtrl, and supports most of the functionality of this control. Refer to the platform SDK and MFC documentation for more information on using the CHeaderCtrl.
The CHeaderCtrl is extended with the following members:
BOOL ModifyProperty(WPARAM wParam, LPARAM lParam); BOOL GetItemEx(INT iPos, HDITEMEX* phditemex) const; BOOL SetItemEx(INT iPos, HDITEMEX* phditemex); void SetSortColumn(INT iPos, BOOL bSortAscending); INT GetSortColumn(BOOL* pbSortAscending = NULL);
INT GetDropResult();
ModifyProperty allows you to modify a property of the control. wParam specifies the property, lParam the new value of that property.
| wParam (Property) | lParam (Data) |
| FH_PROPERTY_SPACING | Text/image/bitmap/arrow spacing |
| FH_PROPERTY_ARROW | size of the sorting arrow, use the MAKELPARAM macro with the arrow's cx value in wLow and the arrow's cy value in wHigh. |
| FH_PROPERTY_STATICBORDER | if lParam is other then 0, the control adjusts it's layout for CListCtrls that use the static border style. |
| FH_PROPERTY_DONTDROPCURSOR | The resource ID of the cursor to be displayed when the user drops a header item outside the header control or drop target. |
| FH_PROPERTY_DROPTARGET | The handle of the window the user can drop a header item to. |
GetItemEx/SetItemEx allow you to get or set the extended features of a Header item, much like the GetItem member of the standard control, however, the functions do not require you specify a mask. Currently the extended item structure only contains the minimum and maximum width of an item. If the maximum size is smaller then the minimum size, there will be no size constraints. These members may be used in future versions to add more per item properties.
GetSortColumn/SetSortColumn allow you to get or set the item that will display a sort arrow. iPos identifies the item that will display the sort arrow, setting iPos to -1 removes the sort arrow. bSortAscending specifies the order (and is optional in the GetSortColumn).
GetDropResult indicates whether the drop occured in the control (0), in the drop target(1) or outside the control or the drop target (-1).
Version history:
1.0.0.1 - Initial release 1.0.1.0 - Fixed FHDragWnd destroy warning (thanks Philippe Terrier) - Fixed double sent HDN_ITEMCLICK - Added a property that adjusts for ListCtrls that use a static border for flat look. - Added sample list view support. 1.0.2.0 - Fixed another destroy warning - Fixed InsertItem array exception handling - Fixed incorrect header width painting - Changed DrawItem argument passing - Changed HDITEMEX struct item names - Added handler for HDM_SETIMAGELIST (precalculate image dimensions) - Changed DrawImage to clip images - Changed InsertItem ASSERT check to position limitation - Added new-style "HotDivider" arrows - Fixed some GDI objects - Added 'don't drop cursor' support to indicate drag&drop outside control - Added drag&drop target window support - Changed CFHDragWnd to support externally created items - Removed topmost-style from CFHDropWnd - Fixed OnSetHotDivider order bug - Added extended styles - Added item width estimation function
The control uses Keith Rules MemDC class for flicker free drawing.
Environment: VC6, Windows 98, NT4 (IE4).
Enjoy!
Downloads
Download demo project - 48 KBDownload source - 11 KB

Comments
Dietary Supplementation Improve Your Flourishing Living
Posted by Ascephept on 02/07/2013 08:49pmis a wonderful diet pill as well as fat-burner which improves the entire body's rate of metabolism. It not just stops working fat, but it does not burn muscular tissue - problems frequently related to different fat burning products. Try Phen375 Vimax no Brasil, Buy Phen375, vigrx plus, Vimax
ReplyBug Fix(?): Bug in dragging header
Posted by Legacy on 02/19/2003 12:00amOriginally posted by: Jaeyoun Yi
ReplyHow to set the heder from right to left
Posted by Legacy on 01/09/2002 12:00amOriginally posted by: Oren Farber
hi
I need to create an application that use hebrew.
I want to set the ListCtrl header from right to left
Thaks,
ReplyOren
How can I get it to sort a listview?
Posted by Legacy on 10/14/2001 12:00amOriginally posted by: Tanky
I got it to show the arrow in a listview but can't get the column header click to fire.
Reply
I can't resize the column size
Posted by Legacy on 10/11/2001 12:00amOriginally posted by: loner_cn
Hi, after I subclass the class, the column size change to fixed and can't change, and also their is no comments mark before "ON_MESSAGE(HDM_INSERTITEMW, OnInsertItem)", how can I do?
And, when I click the edge of second column, and drag it, the name on the drag image is the name of first column.
By the way, I use this class by subclass it using this way:
OnInitDialog() {
CHeaderCtrl* pHeader = NULL;
pHeader = m_list.GetHeaderCtrl(); //m_list is a CListCtrl
if (pHeader != NULL){
VERIFY(m_flat_HeaderCtrl.SubclassWindow(pHeader->m_hWnd));
}
}
It works OK except I can't resize the column size.
Replybug if press alt + tab when dragging the header item
Posted by Legacy on 08/11/2001 12:00amOriginally posted by: kingbo Ruan
when i dragging the header item, i press the keys' alt + tab', when i repeat to come back, something wrong with
the dragging. i resolve this problem by adding message
'wm_capturechange'
void CFlatHeaderCtrl::OnCaptureChanged(CWnd *pWnd)
Reply{
// TODO: Add your message handler code here
if(m_bDragging && pWnd->GetSafeHwnd () != GetSafeHwnd())//simulate Onlbuttonup messae
OnLButtonUp(0, CPoint(0, 0));
CHeaderCtrl::OnCaptureChanged(pWnd);
}
Errors - Does it work in VC 5?
Posted by Legacy on 06/02/1999 12:00amOriginally posted by: b@ckflip
Hi,
I'm using your class in a VC 5 project and I was wondering if your class works with VC 5? Or does VC 6 have functions that VC 5 don't have and that your class is using... These are the errors I get:
error C2065: 'OrderToIndex' : undeclared identifier
error C2065: 'GetItemRect' : undeclared identifier
error C2065: 'GetImageList' : undeclared identifier
error C2440: 'initializing' : cannot convert from 'int' to 'class CImageList*'
Conversion from integral type to pointer type requires reinterpret_cast, C-style cast or function-style cast
error C2065: 'GetOrderArray' : undeclared identifier
error C2065: 'SetOrderArray' : undeclared identifier
Help!
Replyb@ckflip
using with a clistview?
Posted by Legacy on 02/22/1999 12:00amOriginally posted by: jonathan
How would I use this flat header control with a clistview derived clistctrl?
Reply