2014-12-07 17:27:35 -06:00
// 7 december 2014
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
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
2014-12-11 19:35:46 -06:00
// TODO make a better name for this?
// TODO move to hscroll.h?
// TODO organize this in general...
// TODO because of this function's new extended functionality only hscrollto() is allowed to call repositionHeader()
2014-12-10 09:01:16 -06:00
static void updateTableWidth ( struct table * t )
{
2014-12-10 09:07:08 -06:00
HDITEMW item ;
intptr_t i ;
2014-12-11 19:35:46 -06:00
RECT client ;
2014-12-10 09:07:08 -06:00
t - > width = 0 ;
// TODO count dividers?
2014-12-14 15:23:32 -06:00
// TODO use columnWidth()
2014-12-10 09:07:08 -06:00
for ( i = 0 ; i < t - > nColumns ; i + + ) {
ZeroMemory ( & item , sizeof ( HDITEMW ) ) ;
item . mask = HDI_WIDTH ;
if ( SendMessageW ( t - > header , HDM_GETITEM , ( WPARAM ) i , ( LPARAM ) ( & item ) ) = = FALSE )
panic ( " error getting Table column width for updateTableWidth() " ) ;
t - > width + = item . cxy ;
}
2014-12-11 19:35:46 -06:00
if ( GetClientRect ( t - > hwnd , & client ) = = 0 )
panic ( " error getting Table client rect in updateTableWidth() " ) ;
t - > hpagesize = client . right - client . left ;
// this part is critical: if we resize the columns to less than the client area width, then the following hscrollby() will make t->hscrollpos negative, which does very bad things
// note to self: do this regardless of whether the table width or the client area width was changed
if ( t - > hpagesize > t - > width )
t - > hpagesize = t - > width ;
2014-12-10 14:37:52 -06:00
// do a dummy scroll to update the horizontal scrollbar to use the new width
hscrollby ( t , 0 ) ;
2014-12-10 09:01:16 -06:00
}
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 ;
2014-12-10 09:01:16 -06:00
updateTableWidth ( t ) ;
2014-12-09 18:31:05 -06:00
// TODO make more intelligent
2014-12-08 11:57:54 -06:00
InvalidateRect ( t - > hwnd , NULL , TRUE ) ;
2014-12-09 18:31:05 -06:00
// TODO UpdateWindow()?
2014-12-08 11:57:54 -06:00
* lResult = 0 ;
return TRUE ;
}