2014-12-07 17:27:35 -06:00
// 7 december 2014
2015-01-06 02:12:44 -06:00
// TODO verify header events (double-clicking on a divider, for example)
2014-12-07 17:27:35 -06:00
static void makeHeader ( struct table * t , HINSTANCE hInstance )
{
t - > header = CreateWindowExW ( 0 ,
WC_HEADERW , L " " ,
2014-12-07 19:16:58 -06:00
// don't set WS_VISIBLE; according to MSDN we create the header hidden as part of setting the initial position (http://msdn.microsoft.com/en-us/library/windows/desktop/ff485935%28v=vs.85%29.aspx)
2014-12-07 17:27:35 -06:00
// TODO WS_BORDER?
// TODO is HDS_HOTTRACK needed?
WS_CHILD | HDS_FULLDRAG | HDS_HORZ | HDS_HOTTRACK ,
0 , 0 , 0 , 0 , // no initial size
t - > hwnd , ( HMENU ) 100 , hInstance , NULL ) ;
if ( t - > header = = NULL )
panic ( " error creating Table header " ) ;
}
static void destroyHeader ( struct table * t )
{
if ( DestroyWindow ( t - > header ) = = 0 )
panic ( " error destroying Table header " ) ;
}
2014-12-07 17:43:05 -06:00
2015-01-08 00:45:06 -06:00
// to avoid weird bugs, the only functions allowed to call this one are the horizontal scroll functions
// when we need to reposition the header in a situation other than a user-initiated scroll, we use a dummy scroll (hscrollby(t, 0))
// see update() in update.h
2014-12-07 17:43:05 -06:00
static void repositionHeader ( struct table * t )
{
2014-12-07 19:16:58 -06:00
RECT r ;
WINDOWPOS wp ;
HDLAYOUT l ;
if ( GetClientRect ( t - > hwnd , & r ) = = 0 )
panic ( " error getting client rect for Table header repositioning " ) ;
2014-12-11 15:43:05 -06:00
// we fake horizontal scrolling here by extending the client rect to the left by the scroll position
r . left - = t - > hscrollpos ;
2014-12-07 19:16:58 -06:00
l . prc = & r ;
l . pwpos = & wp ;
if ( SendMessageW ( t - > header , HDM_LAYOUT , 0 , ( LPARAM ) ( & l ) ) = = FALSE )
panic ( " error getting new Table header position " ) ;
if ( SetWindowPos ( t - > header , wp . hwndInsertAfter ,
wp . x , wp . y , wp . cx , wp . cy ,
// see above on showing the header here instead of in the CreateWindowExW() call
wp . flags | SWP_SHOWWINDOW ) = = 0 )
panic ( " error repositioning Table header " ) ;
2014-12-10 13:07:14 -06:00
t - > headerHeight = wp . cy ;
2014-12-07 17:43:05 -06:00
}
2014-12-08 07:50:42 -06:00
static void headerAddColumn ( struct table * t , WCHAR * name )
{
HDITEMW item ;
ZeroMemory ( & item , sizeof ( HDITEMW ) ) ;
item . mask = HDI_WIDTH | HDI_TEXT | HDI_FORMAT ;
item . cxy = 200 ; // TODO
item . pszText = name ;
item . fmt = HDF_LEFT | HDF_STRING ;
// TODO replace 100 with (t->nColumns - 1)
if ( SendMessage ( t - > header , HDM_INSERTITEM , ( WPARAM ) ( 100 ) , ( LPARAM ) ( & item ) ) = = ( LRESULT ) ( - 1 ) )
panic ( " error adding column to Table header " ) ;
}
2014-12-08 11:57:54 -06:00
2015-01-08 01:05:06 -06:00
// TODO is this triggered if we programmatically move headers (for autosizing)?
2014-12-08 11:57:54 -06:00
HANDLER ( headerNotifyHandler )
{
NMHDR * nmhdr = ( NMHDR * ) lParam ;
if ( nmhdr - > hwndFrom ! = t - > header )
return FALSE ;
if ( nmhdr - > code ! = HDN_ITEMCHANGED )
return FALSE ;
2015-01-08 00:45:06 -06:00
update ( t , TRUE ) ;
2014-12-09 18:31:05 -06:00
// TODO make more intelligent
2015-01-08 01:05:06 -06:00
// to do this, we have to redraw the column to the left of the divider that was dragged and scroll everything to the right normally (leaving the hole that was scrolled invalidated as well)
// of course, this implies that dragging a divider only resizes the column of which it is the right side of and moves all others
2014-12-08 11:57:54 -06:00
InvalidateRect ( t - > hwnd , NULL , TRUE ) ;
* lResult = 0 ;
return TRUE ;
}