www.pudn.com > ListCtrl2014.rar > XKListCtrl.cpp, change:2014-05-09,size:10591b


// CXKListCtrl.cpp : implementation file 
// 
 
#include "stdafx.h" 
#include "XKListCtrl.h" 
#include <vector> 
#define VECTOR			std::vector 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
///////////////////////////////////////////////////////////////////////////// 
// CXKListCtrl 
IMPLEMENT_DYNAMIC(CXKListCtrl, CListCtrl) 
CXKListCtrl::CXKListCtrl() 
{ 
	m_fAsc=TRUE; 
	m_nEditRow = -1; 
	m_nEditCol = -1; 
	m_pLinkListCtrl = NULL; 
	m_bEditable = TRUE; 
 
	SetColorInfo(RGB(0, 0, 0), RGB(255, 255, 255), RGB(0, 0, 0),  
		RGB(50,150,250), RGB(0, 0, 0), RGB(204, 232, 207)); 
 
	m_fnCanEditFilter = DefCanEditFilter; 
	m_fnDataFilter = DefDataFilter; 
} 
 
CXKListCtrl::~CXKListCtrl() 
{ 
} 
 
void CXKListCtrl::SetCanEditFilter(FunCanEditFilter fnComp)	 
{ 
	m_fnCanEditFilter = fnComp; 
} 
 
BOOL CXKListCtrl::DefCanEditFilter(int nRow, int nCol) 
{ 
	return TRUE; 
} 
 
BOOL CXKListCtrl::DefDataFilter(CString &strData) 
{ //单元格编辑后数据是否更新到单元格的默认过滤器 
	return TRUE; 
} 
 
void CXKListCtrl::EnableEdiable(BOOL bEditable) 
{ 
	m_bEditable = bEditable; 
} 
 
DWORD CXKListCtrl::SetExtendedStyle(DWORD dwNewStyle) 
{ 
	return CListCtrl::SetExtendedStyle(dwNewStyle); 
} 
 
void CXKListCtrl::SetLinkListCtrl(CXKListCtrl *pListCtrl) 
{ 
	m_pLinkListCtrl = pListCtrl; 
} 
 
void CXKListCtrl::SetColorInfo(COLORREF colorText, COLORREF colorBk, COLORREF colorSelText,  
	COLORREF colorSelBk, COLORREF colorEditText, COLORREF colorEditBk) 
{ 
	COLORREF colorUnits[] = {colorText, colorBk, colorSelText, colorSelBk, colorEditText, colorEditBk}; 
	memcpy(m_colorUnits, colorUnits, sizeof(colorUnits)); 
} 
 
BEGIN_MESSAGE_MAP(CXKListCtrl, CListCtrl) 
	//{{AFX_MSG_MAP(CXKListCtrl) 
	ON_NOTIFY_REFLECT(LVN_COLUMNCLICK, OnColumnclick) 
	ON_NOTIFY_REFLECT(NM_CLICK, OnNMClickList) 
	ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnNMCustomdrawList) 
	ON_NOTIFY_REFLECT(NM_KILLFOCUS, OnNMKillfocusList) 
	ON_WM_LBUTTONDOWN() 
	ON_WM_LBUTTONDBLCLK() 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CXKListCtrl message handlers 
int CALLBACK ListCompare(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) 
{ 
	CXKListCtrl* pV=(CXKListCtrl*)lParamSort;  
	CString strItem1, strItem2;  
	LVFINDINFO info;  
	int nIndex;  
	info.flags = LVFI_PARAM;                       //设置为LVFI_PARAM,后面的FindItem才能有效,详情参考MSDN的LVFINDINFO  
	info.lParam = lParam1;                         //由item data(lParam1)得到对应的item text  
	if ( (nIndex=pV->FindItem(&info)) != -1)  
		strItem1 = pV->GetItemText(nIndex, pV->m_nSortedCol);  
	info.lParam = lParam2;                         //由item data(lParam2)得到对应的item text  
	if ( (nIndex=pV->FindItem(&info)) != -1) 
		strItem2 = pV->GetItemText(nIndex, pV->m_nSortedCol);  
	int iCompRes ; 
	iCompRes = _tcscmp(strItem1, strItem2);     //根据当前的排序方式进行调整  
	if(pV->m_fAsc)  
		return iCompRes; 
	else  
		return iCompRes * -1; 
} 
 
BOOL CXKListCtrl::DeleteColumn(int nCol) 
{ 
	if (m_pLinkListCtrl != NULL) 
	{ 
		m_pLinkListCtrl->DeleteColumn(nCol); 
	} 
 
	return CListCtrl::DeleteColumn(nCol); 
} 
 
BOOL CXKListCtrl::DeleteAllItems() 
{ 
	if (m_pLinkListCtrl != NULL) 
	{ 
		m_pLinkListCtrl->DeleteAllItems(); 
	} 
 
	return CListCtrl::DeleteAllItems(); 
} 
 
int CXKListCtrl::InsertColumn(int nCol, LPCTSTR lpszColumnHeading, int nFormat,  
	int nWidth, int nSubItem) 
{ 
	if(m_pLinkListCtrl != NULL) 
	{ 
		if (nCol == 0) 
		{ 
			return m_pLinkListCtrl->InsertColumn(0, lpszColumnHeading, nFormat, nWidth, nSubItem); 
		} 
		else 
		{ 
			return CListCtrl::InsertColumn(nCol - 1, lpszColumnHeading, nFormat, nWidth, nSubItem); 
		} 
	} 
	else 
	{ 
		return CListCtrl::InsertColumn(nCol, lpszColumnHeading, nFormat, nWidth, nSubItem); 
	} 
} 
 
int CXKListCtrl::InsertItem(int nItem, LPCTSTR lpszItem) 
{ 
	if(m_pLinkListCtrl != NULL) 
	{ 
		m_pLinkListCtrl->InsertItem(nItem, lpszItem); 
		return CListCtrl::InsertItem(nItem, _T("")); 
	} 
 
	return CListCtrl::InsertItem(nItem, lpszItem); 
} 
 
int CXKListCtrl::SetItemText(int nItem, int nSubItem, LPCTSTR lpszText) 
{ 
	if (m_pLinkListCtrl != NULL) 
	{ 
		if (nSubItem == 0) 
		{ 
			return m_pLinkListCtrl->SetItemText(nItem, 0, lpszText); 
		} 
		else 
		{ 
			return CListCtrl::SetItemText(nItem, nSubItem - 1, lpszText); 
		} 
	} 
	else 
	{ 
		return CListCtrl::SetItemText(nItem, nSubItem, lpszText); 
	} 
} 
 
CString CXKListCtrl::GetItemText(int nItem, int nSubItem) 
{ 
	if (m_pLinkListCtrl != NULL) 
	{ 
		if (nSubItem == 0) 
		{ 
			return m_pLinkListCtrl->GetItemText(nItem, nSubItem); 
		} 
		else 
		{ 
			return CListCtrl::GetItemText(nItem, nSubItem - 1); 
		} 
	} 
	else 
	{ 
		return CListCtrl::GetItemText(nItem, nSubItem); 
	} 
} 
 
void CXKListCtrl::SetRadioSelect(int nSelItem) 
{ //设置单选 
	POSITION pos = GetFirstSelectedItemPosition();   
	int nCurSel = GetNextSelectedItem(pos);   
	if (nCurSel != nSelItem) 
	{ 
		SetItemState(nCurSel, 0, LVIS_SELECTED); 
		//SetItemState(nSelItem, LVIS_SELECTED, LVIS_SELECTED); 
	} 
	if (nSelItem != -1) 
	{ 
		SetItemState(nSelItem, LVIS_SELECTED, LVIS_SELECTED); 
	} 
} 
 
void CXKListCtrl::SetMultiSelect(int nSelItem)  
{  //设置多选 
	POSITION pos = GetFirstSelectedItemPosition();  
	while(pos)  
	{  
		int nIndex = GetNextSelectedItem(pos);  
		if(nIndex == nSelItem)  
		{  
			if(GetItemState(nSelItem, LVIS_SELECTED) & LVIS_SELECTED) 
			{ 
				SetItemState(nSelItem, 0, LVIS_SELECTED); 
			} 
			else 
			{ 
				SetItemState(nSelItem, LVIS_SELECTED, LVIS_SELECTED); 
			} 
			break;  
		}  
	}  
} 
 
BOOL CXKListCtrl::SetItemState(int nItem, UINT nState, UINT nMask) 
{ 
	if (m_pLinkListCtrl != NULL) 
	{ 
		m_pLinkListCtrl->SetItemState(nItem, nState, nMask); 
	} 
 
	return CListCtrl::SetItemState(nItem, nState, nMask); 
} 
 
void CXKListCtrl::OnColumnclick(NMHDR* pNMHDR, LRESULT* pResult)  
{ 
	NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; 
	// TODO: Add your control notification handler code here 
	if( pNMListView->iSubItem == m_nSortedCol ) 
		m_fAsc = !m_fAsc; 
	else 
	{ 
		m_fAsc = TRUE; 
		m_nSortedCol = pNMListView->iSubItem; 
	} 
 
	VERIFY(SortItems(ListCompare, reinterpret_cast<DWORD>( this ))); 
 
	*pResult = 0; 
} 
 
BOOL CXKListCtrl::PreTranslateMessage(MSG* pMsg) 
{ 
	if (pMsg->message == WM_KEYDOWN  
		&& (pMsg->wParam == VK_RETURN || pMsg->wParam == VK_ESCAPE)) 
	{ 
		if (m_editUnit.IsWindowVisible()) 
		{ 
			DisposeEdit(); 
		} 
		return TRUE; 
	} 
 
	return CListCtrl::PreTranslateMessage(pMsg); 
} 
 
void CXKListCtrl::PreSubclassWindow()  
{ 
	// TODO: Add your specialized code here and/or call the base class 
	ModifyStyle(LVS_EDITLABELS,0); 
	ModifyStyle(0,LVS_REPORT); 
	//ModifyStyle(0,LVS_SHOWSELALWAYS); 
	SetExtendedStyle(LVS_EX_FLATSB 
		|LVS_EX_FULLROWSELECT 
		|LVS_EX_HEADERDRAGDROP 
		|LVS_EX_ONECLICKACTIVATE 
		|LVS_EX_GRIDLINES); 
 
	m_editUnit.Create(WS_CHILD|WS_CLIPSIBLINGS|WS_EX_TOOLWINDOW|WS_BORDER, 
		CRect(0,40,10,50), this, 1001); 
 
	CListCtrl::PreSubclassWindow(); 
} 
 
void CXKListCtrl::OnLButtonDown(UINT nFlags, CPoint point)  
{ 
	// TODO: Add your message handler code here and/or call default	 
	CListCtrl::OnLButtonDown(nFlags, point); 
 
	UpdateWindow(); 
} 
 
void CXKListCtrl::ShowEdit() 
{ 
	CRect rect; 
	GetSubItemRect(m_nEditRow, m_nEditCol, LVIR_LABEL, rect); 
 
	CString strData; 
	strData = CListCtrl::GetItemText(m_nEditRow, m_nEditCol); 
 
	m_editUnit.MoveWindow(rect); 
	m_editUnit.SetWindowText(strData); 
	m_editUnit.ShowWindow(SW_SHOW); 
	m_editUnit.SetSel(0,100); 
	m_editUnit.SetFocus(); 
	UpdateWindow(); 
} 
 
BOOL CXKListCtrl::DisposeEdit() 
{ 
	CString strData; 
 
	m_editUnit.GetWindowText(strData); 
	if (m_fnDataFilter(strData)) 
	{ 
		if (m_pLinkListCtrl != NULL) 
		{ 
			this->SetItemText(m_nEditRow, m_nEditCol + 1, strData); 
		} 
		else 
		{ 
			this->SetItemText(m_nEditRow, m_nEditCol, strData); 
		} 
	} 
 
	m_editUnit.ShowWindow(SW_HIDE); 
	::SendMessage(this->GetParent()->GetSafeHwnd(), NULL, NULL, NULL); 
 
	return TRUE; 
} 
 
void CXKListCtrl::OnLButtonDblClk(UINT nFlags, CPoint point)  
{ 
	LVHITTESTINFO info; 
	info.pt = point; 
	info.flags = LVHT_ONITEMLABEL; 
	if(m_bEditable && SubItemHitTest(&info)>=0) 
	{ 
		m_nEditRow = info.iItem; 
		m_nEditCol = info.iSubItem; 
 
		if(m_fnCanEditFilter(m_nEditRow, m_nEditCol)) 
		{ 
			ShowEdit();//显示编辑 
		} 
	} 
 
	CListCtrl::OnLButtonDblClk(nFlags, point); 
} 
 
void CXKListCtrl::OnNMClickList(NMHDR *pNMHDR, LRESULT *pResult) 
{ 
	LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR); 
	// TODO: 在此添加控件通知处理程序代码 
	if (m_pLinkListCtrl != NULL) 
	{ 
		VECTOR<int> vSelIndexs; 
		POSITION pos = GetFirstSelectedItemPosition();  
		while(pos)  
		{  
			int nIndex = GetNextSelectedItem(pos);  
			vSelIndexs.push_back(nIndex); 
		}  
		int nSelCount = vSelIndexs.size(); 
		int nCount = GetItemCount(); 
		for (int i = 0, j = 0; i < nCount; i++) 
		{ 
			if (j < nSelCount && vSelIndexs[j] == i) 
			{ 
				m_pLinkListCtrl->SetItemState(vSelIndexs[j], LVIS_SELECTED, LVIS_SELECTED); 
				j++; 
			} 
			else 
			{ 
				m_pLinkListCtrl->SetItemState(i, 0, LVIS_SELECTED); 
			} 
		} 
	} 
 
	*pResult = 0; 
} 
 
void CXKListCtrl::OnNMCustomdrawList(NMHDR *pNMHDR, LRESULT *pResult) 
{ 
	NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>(pNMHDR);  
	// TODO: 在此添加控件通知处理程序代码 
 
	if ( CDDS_PREPAINT == pLVCD->nmcd.dwDrawStage )   
	{     
		*pResult = CDRF_NOTIFYITEMDRAW;   
	}   
	else if ( CDDS_ITEMPREPAINT == pLVCD->nmcd.dwDrawStage )   
	{    
		*pResult = CDRF_NOTIFYSUBITEMDRAW;   
	}   
	else if ( (CDDS_ITEMPREPAINT | CDDS_SUBITEM) == pLVCD->nmcd.dwDrawStage )   
	{   
		int nItem = static_cast<int>( pLVCD->nmcd.dwItemSpec ); 
		BOOL bSelect = FALSE; 
 
		POSITION pos = GetFirstSelectedItemPosition();  
		while(pos)  
		{  
			int index = GetNextSelectedItem(pos);  
 
			if(index == nItem)  
			{  
				bSelect = TRUE;  
				break;  
			}  
		}  
		 
		if(bSelect) 
		{ 
			pLVCD->clrText = m_colorUnits[2]; 
			pLVCD->clrTextBk = m_colorUnits[3]; 
		} 
		else 
		{ 
			if (m_bEditable && m_fnCanEditFilter(pLVCD->nmcd.dwItemSpec, pLVCD->iSubItem)) 
			{ 
				pLVCD->clrText = m_colorUnits[4]; 
				pLVCD->clrTextBk = m_colorUnits[5];  
			} 
			else 
			{ 
				pLVCD->clrText = m_colorUnits[0]; 
				pLVCD->clrTextBk = m_colorUnits[1]; 
			} 
		} 
		 
		*pResult = CDRF_DODEFAULT;   
	} 
} 
 
void CXKListCtrl::OnNMKillfocusList(NMHDR *pNMHDR, LRESULT *pResult) 
{ 
	// TODO: 在此添加控件通知处理程序代码 
	*pResult = 0; 
}