www.pudn.com > HReportTest.rar > HReportListBase.cpp
// HReportListBase.cpp: implementation of the CHReportListBase class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "HReportListBase.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CHReportListBase::CHReportListBase()
{
m_pListCtrl = NULL;
m_nLineHeight = 18;
m_nSortedCol = -1;
m_bAscending = FALSE;
m_bAutoSave = FALSE;
m_bAutoFont = TRUE;
m_strSection = _T("ÉèÖÃ");
m_strEntry = _T("ÁÐÐÅÏ¢");
m_strDefault = _T("");
m_clrText = ::GetSysColor(COLOR_WINDOWTEXT);
m_clrTextBk = ::GetSysColor(COLOR_WINDOW);
}
CHReportListBase::~CHReportListBase()
{
}
void CHReportListBase::SaveColumnWidths()
{
}
void CHReportListBase::LoadColumnWidths()
{
}
void CHReportListBase::SetCurSel(int nRow)
{
ASSERT(m_pListCtrl != NULL);
if( (GetWindowLong(m_pListCtrl->m_hWnd, GWL_STYLE) & LVS_TYPEMASK) != LVS_REPORT ||
(GetWindowLong(m_pListCtrl->m_hWnd, GWL_STYLE) & LVS_SINGLESEL) != LVS_SINGLESEL )
{
ASSERT(0);
return;
}
if(nRow > m_pListCtrl->GetItemCount() || nRow < 0)
return;
BOOL bSet = FALSE;
int nItem = -1;
POSITION pos = m_pListCtrl->GetFirstSelectedItemPosition();
while(pos)
{
nItem = m_pListCtrl->GetNextSelectedItem(pos);
if(nItem == nRow)
{
bSet = TRUE;
continue;
}
m_pListCtrl->SetItemState(nItem, ~LVIS_SELECTED, LVIS_SELECTED);
}
if(bSet) return;
m_pListCtrl->SetItemState(nRow, LVIS_SELECTED, LVIS_SELECTED);
}
int CHReportListBase::GetCurSel()
{
ASSERT(m_pListCtrl != NULL);
if( (GetWindowLong(m_pListCtrl->m_hWnd, GWL_STYLE) & LVS_TYPEMASK) != LVS_REPORT ||
(GetWindowLong(m_pListCtrl->m_hWnd, GWL_STYLE) & LVS_SINGLESEL) != LVS_SINGLESEL )
{
ASSERT(0);
return -1;
}
POSITION pos = m_pListCtrl->GetFirstSelectedItemPosition();
if(pos == NULL)
return -1;
return m_pListCtrl->GetNextSelectedItem(pos);
}
int CHReportListBase::CalcNextSel(int nRow)
{
ASSERT(m_pListCtrl != NULL);
if( (GetWindowLong(m_pListCtrl->m_hWnd, GWL_STYLE) & LVS_TYPEMASK) != LVS_REPORT )
{
ASSERT(0);
return -1;
}
int nCount = m_pListCtrl->GetItemCount();
if(nRow < 0 || nCount == 0)
return -1;
if(nRow >= nCount)
return nCount;
return nRow;
}
void CHReportListBase::SetUsedStyle(BOOL bFullRowSelect, BOOL bShowGridLines, BOOL bSingSel)
{
ASSERT(m_pListCtrl != NULL);
DWORD dwStyle = m_pListCtrl->GetExtendedStyle();
if(bFullRowSelect)
dwStyle |= LVS_EX_FULLROWSELECT;
else
dwStyle &= ~LVS_EX_FULLROWSELECT;
if(bShowGridLines)
dwStyle |= LVS_EX_GRIDLINES;
else
dwStyle &= ~LVS_EX_GRIDLINES;
m_pListCtrl->SetExtendedStyle(dwStyle);
if(bSingSel)
m_pListCtrl->ModifyStyle(0, LVS_SINGLESEL);
else
m_pListCtrl->ModifyStyle(LVS_SINGLESEL, 0);
}
BOOL CHReportListBase::OnNotifyImpl(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
ASSERT(m_pListCtrl != NULL);
HD_NOTIFY *pHDNotify = (HD_NOTIFY*)lParam;
switch( pHDNotify->hdr.code )
{
case HDN_ITEMCLICKA:
case HDN_ITEMCLICKW:
{
if (!m_flatHeader.GetSafeHwnd())
break;
if (pHDNotify->iButton == 0)
{
if (pHDNotify->iItem == m_nSortedCol)
m_bAscending = !m_bAscending;
else
m_bAscending = TRUE;
}
else
{
break;
}
// set sort image for header.
m_nSortedCol = pHDNotify->iItem;
m_flatHeader.SetSortImage (m_nSortedCol, m_bAscending);
SortList (m_nSortedCol, m_bAscending);
}
break;
}
return m_pListCtrl->CListCtrl::OnNotify(wParam, lParam, pResult);
}
void CHReportListBase::PreSubclassWindowImpl_Post()
{
ASSERT(m_pListCtrl != NULL);
if (m_bAutoFont)
{
InitFont();
m_pListCtrl->SendMessage(WM_SETFONT, (WPARAM)(HFONT)m_font, MAKELPARAM(TRUE,0));
}
}
int CHReportListBase::OnCreateImpl_Post(LPCREATESTRUCT lpCreateStruct)
{
ASSERT(m_pListCtrl != NULL);
SetUsedStyle(TRUE, FALSE, 0);
SubclassHeader();
m_flatHeader.ShowSortArrow();
m_imageList.Create(1, m_nLineHeight, ILC_COLOR24|ILC_MASK, 2, 2);
m_pListCtrl->SetImageList(&m_imageList, LVSIL_SMALL);
if (m_bAutoFont )
{
InitFont();
m_pListCtrl->SetFont(&m_font);
}
return 0;
}
void CHReportListBase::OnCustomDrawImpl(NMHDR* pNMHDR, LRESULT* pResult)
{
LPNMLVCUSTOMDRAW pLVCD = (LPNMLVCUSTOMDRAW)pNMHDR;
*pResult = CDRF_DODEFAULT;
int nItem = -1;
switch(pLVCD->nmcd.dwDrawStage)
{
case CDDS_PREPAINT:
*pResult = CDRF_NOTIFYITEMDRAW;
break;
case CDDS_ITEMPREPAINT:
nItem = static_cast (pLVCD->nmcd.dwItemSpec);
if( OnCustomDrawItem(nItem, pLVCD->clrText, pLVCD->clrTextBk) )
*pResult = CDRF_NOTIFYSUBITEMDRAW;
else
*pResult = CDRF_DODEFAULT;
break;
case CDDS_SUBITEM | CDDS_PREPAINT | CDDS_ITEM:
nItem = static_cast (pLVCD->nmcd.dwItemSpec);
int nSubItem = pLVCD->iSubItem;
OnCustomDrawSubItem(nItem, nSubItem, pLVCD->clrText, pLVCD->clrTextBk);
break;
}
}
void CHReportListBase::OnDestroyImpl_Pre()
{
if( m_bAutoSave )
SaveColumnWidths();
}
BOOL CHReportListBase::OnEraseBkgndImpl(CDC* pDC)
{
return TRUE;
}
void CHReportListBase::OnPaintImpl()
{
ASSERT(m_pListCtrl != NULL);
if( (::GetWindowLong(m_pListCtrl->m_hWnd, GWL_STYLE) & LVS_TYPEMASK) != LVS_REPORT )
{
ASSERT(0);
return;
}
CPaintDC dc(m_pListCtrl);
CRect rectClient;
m_pListCtrl->GetClientRect(&rectClient);
CHeaderCtrl* pWndHeader = GetHeaderCtrlX();
ASSERT(pWndHeader != NULL);
CRect rcHeader;
pWndHeader->GetWindowRect(&rcHeader);
m_pListCtrl->ScreenToClient(&rcHeader);
dc.ExcludeClipRect(&rcHeader);
CHMemDC memDC(&dc, rectClient, ::GetSysColor(COLOR_WINDOW));
m_pListCtrl->CWnd::DefWindowProc( WM_PAINT, (WPARAM)memDC.m_hDC, 0 );
}
BOOL CHReportListBase::SubclassHeader()
{
if( (GetWindowLong(m_pListCtrl->m_hWnd, GWL_STYLE) & LVS_TYPEMASK) != LVS_REPORT )
{
ASSERT(0);
return FALSE;
}
if (::IsWindow(m_flatHeader.GetSafeHwnd()))
{
ASSERT(0);
return FALSE;
}
HWND hWndHeader = GetHeaderCtrlX()->GetSafeHwnd();
if (!m_flatHeader.SubclassWindow (hWndHeader))
return false;
m_flatHeader.InitializeHeader(&m_font);
return TRUE;
}
void CHReportListBase::InitFont()
{
m_font.DeleteObject();
CString strHorzFont = _T( "Tahoma" );
NONCLIENTMETRICS ncm;
ZeroMemory(&ncm, sizeof(NONCLIENTMETRICS));
ncm.cbSize = sizeof(NONCLIENTMETRICS);
SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0);
LOGFONT lfHorz;
ZeroMemory(&lfHorz, sizeof(LOGFONT));
CopyMemory((void*)&lfHorz, (const void*)&(ncm.lfMenuFont), (DWORD)sizeof(LOGFONT));
if ( FontExists( strHorzFont ) )
_tcscpy( lfHorz.lfFaceName, strHorzFont );
else
ASSERT( FALSE );
CreateSysFont( lfHorz, m_font );
}
static const TCHAR _OfficeFaceName[] = _T("Tahoma");
static int CALLBACK EnumFontFamExProc(ENUMLOGFONTEX* pelf,
NEWTEXTMETRICEX* lpntm, int FontType, LPVOID pThis)
{
UNUSED_ALWAYS(lpntm);
UNUSED_ALWAYS(FontType);
UNUSED_ALWAYS(pThis);
CString strFaceName(pelf->elfLogFont.lfFaceName);
return strFaceName.Compare(_OfficeFaceName);
}
BOOL CHReportListBase::FontExists(CString &strFaceName)
{
LOGFONT lfEnum;
lfEnum.lfFaceName[ 0 ] = 0;
lfEnum.lfCharSet = DEFAULT_CHARSET;
CWindowDC dc( NULL );
if ( ::EnumFontFamiliesEx( dc.m_hDC, &lfEnum, ( FONTENUMPROC )EnumFontFamExProc,
( LPARAM )&strFaceName, 0 ) == 0 )
{
return TRUE;
}
return FALSE;
}
BOOL CHReportListBase::CreateSysFont(LOGFONT &lf, CFont &font, long lfWeight, char lfUnderline, long lfOrientation, long lfEscapement)
{
lf.lfWeight = lfWeight;
lf.lfOrientation = lfOrientation;
lf.lfEscapement = lfEscapement;
lf.lfUnderline = lfUnderline;
if ( !font.CreateFontIndirect( &lf ) )
{
return FALSE;
}
return TRUE;
}
int CHReportListBase::HitTestEx(CPoint point, int& nCol)
{
int colnum = 0;
int row = m_pListCtrl->HitTest( point, NULL );
nCol = 0;
// Make sure that the ListView is in LVS_REPORT
if( (GetWindowLong(m_pListCtrl->m_hWnd, GWL_STYLE) & LVS_TYPEMASK) != LVS_REPORT )
return row;
// Get the top and bottom row visible
row = m_pListCtrl->GetTopIndex();
int bottom = row + m_pListCtrl->GetCountPerPage();
if( bottom > m_pListCtrl->GetItemCount() )
bottom = m_pListCtrl->GetItemCount();
// get a pointer to the header control, if NULL return error.
CHeaderCtrl* pHeaderCtrl = GetHeaderCtrlX();
if (pHeaderCtrl == NULL)
return -1;
// Get the number of columns
int nColumnCount = pHeaderCtrl->GetItemCount();
for( ;row <= bottom; ++row)
{
CRect rect;
m_pListCtrl->GetItemRect( row, &rect, LVIR_BOUNDS );
if( rect.PtInRect(point) )
{
for( colnum = 0; colnum < nColumnCount; colnum++ )
{
int colwidth = m_pListCtrl->GetColumnWidth(colnum);
if( point.x >= rect.left && point.x <= (rect.left + colwidth ) )
{
nCol = colnum;
return row;
}
rect.left += colwidth;
}
}
}
return -1;
}