Two CHeaders in a CListCtrl
One header at the top with the names of the columns
One header at the bottom to contain totals or average of the data in the list or just what lines are selected.
I could not even move the header to the bottom. CCS_BOTTOM does not seam to be used.
As a starting points:
PositionHeader() is used to display the header when the LVS_NOSCROLL style is used
And GetLayout() is used to determin the position and height of the header - I use a multiline header
void CView_List::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
if(IsWindow(m_MyListCtrl.m_hWnd))
{
m_MyListCtrl.MoveWindow (0, 0, cx, cy);
PositionHeader();
}
}
void CView_List::PositionHeader()
{
HWND hwndListView = m_MyListCtrl.m_hWnd;
HWND hwndHeader = ::GetWindow(hwndListView, GW_CHILD);
DWORD dwStyle = GetWindowLong(hwndListView, GWL_STYLE);
// To ensure that the first item will be visible, create the control
// without the LVS_NOSCROLL style and then add it here.
dwStyle |= LVS_NOSCROLL | WS_VSCROLL;
SetWindowLong(hwndListView, GWL_STYLE, dwStyle);
// Only do this if the ListView is in report view and you were able to
// get the header hWnd.
if(((dwStyle & LVS_TYPEMASK) == LVS_REPORT) && hwndHeader)
{
RECT rc;
HD_LAYOUT hdLayout;
WINDOWPOS wpos;
::GetClientRect(hwndListView, &rc);
hdLayout.prc = &rc;
hdLayout.pwpos = &wpos;
Header_Layout(hwndHeader, &hdLayout);
::SetWindowPos(hwndHeader,
wpos.hwndInsertAfter,
wpos.x,
wpos.y,
wpos.cx,
wpos.cy,
wpos.flags | SWP_SHOWWINDOW);
ListView_EnsureVisible(hwndListView, 0, FALSE);
}
}
ON_MESSAGE(HDM_LAYOUT, GetLayout)
LRESULT CMyHeaderCtrl::GetLayout(WPARAM /*wParam*/, LPARAM lParam)
{
HD_LAYOUT * phdLayout;
RECT * pRc;
WINDOWPOS * pWPos;
phdLayout = (HD_LAYOUT*)lParam;
pRc = phdLayout->prc;
pWPos = phdLayout->pwpos;
int nCol;
int iCount = GetItemCount();
HD_ITEM hd_item;
char Text[250];
char * pText;
int NumRowOfText = 1;
int row;
memset(&hd_item, 0, sizeof(hd_item));
hd_item.mask = HDI_TEXT;
hd_item.pszText = Text;
hd_item.cchTextMax = sizeof(Text);
for(nCol=0; nCol<iCount; nCol++)
{
GetItem(nCol, &hd_item);
pText = hd_item.pszText;// may not put it into Text[]
row = 1;
while(pText && *pText)
{
if('\n' == *pText)
row++;
pText++;
}
NumRowOfText = max(NumRowOfText, row);
}
TEXTMETRIC tm;
HDC hDC = ::GetDC(NULL);
CFont * pFont = GetFont();
HFONT hFontOld = (HFONT)SelectObject(hDC, pFont->GetSafeHandle());
GetTextMetrics(hDC, &tm);
int height = (tm.tmHeight + tm.tmExternalLeading + 1) * NumRowOfText + GetSystemMetrics(SM_CYBORDER);
SelectObject(hDC, hFontOld);
::ReleaseDC(NULL, hDC);
// DWORD dwStyle = GetWindowLong(m_hWnd, GWL_STYLE);
pWPos->hwndInsertAfter = 0;
pWPos->x = pRc->left;
pWPos->cx = pRc->right - pRc->left;
pWPos->cy = height;
pWPos->y = pRc->top;
pRc->top += height;
// HeaderControls do not have commoncontrol settings
// else//(dwStyle & CCS_BOTTOM)
// {
// pRc->bottom -= height;
// pWPos->y = pRc->bottom;
// }
pWPos->flags = SWP_NOACTIVATE | SWP_NOZORDER;
return 1;
}

