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; 
}