www.pudn.com > WinGOS.rar > GridCtrl.cpp


#include "gos.h" 
#include "gridctrl.h" 
#include "Array.h" 
 
CGridCtrl::CGridCtrl(void) 
{ 
 
} 
 
CGridCtrl::~CGridCtrl(void) 
{ 
} 
 
LRESULT CGridCtrl::MsgProc(UINT message, WPARAM wParam, LPARAM lParam) 
{ 
	switch(message) 
	{ 
	case gcmDrawCell: 
		OnDrawCell(PDC(wParam),PGCDRAWCELLARG(lParam)); 
		break; 
	case gcmDrawHeader: 
		OnDrawHeader(PDC(wParam),PGCDRAWCELLARG(lParam)); 
		break; 
	case WM_LBUTTONDOWN: 
		wParam=HitTest(CPoint(lParam)); 
		if(wParam!=-1 && m_aGridRow[wParam]) 
		{ 
			RemoveRowState(m_nCurGridRow,GCS_SELECTED); 
			RedrawRow(m_nCurGridRow); 
			m_nCurGridRow=wParam; 
			AddRowState(wParam,GCS_SELECTED); 
			RedrawRow(wParam); 
		} 
		break; 
	case WM_LBUTTONUP: 
		wParam=HitTest(CPoint(lParam)); 
		if(wParam==m_nCurGridRow) 
		{ 
			wParam=(WPARAM)m_aGridRow[wParam]; 
			PostMessage(WM_COMMAND,wParam,GCS_CLICKED); 
		} 
		break; 
	case WM_COMMAND: 
		GetParent()->PostMessage(WM_COMMAND,WPARAM(this),wParam); 
		break; 
	case WM_PAINT: 
		OnPaint(PDC(wParam)); 
		break; 
	case WM_MOVE: 
		OnMove(); 
		break; 
	case WM_DESTROY: 
		OnDestroy(); 
		break; 
	default: 
		wParam=CWnd::MsgProc(message,wParam,lParam); 
	}	 
	return wParam; 
} 
 
BOOL CGridCtrl::Create(DWORD nStyle,LPCRECT pRect,CPWnd* pParent) 
{ 
	m_nRowHeight=20; 
	m_nHeaderHeight=20; 
	m_nCurGridRow=0; 
	m_nCurGridCol=0; 
	return CWnd::Create(nStyle,pRect,pParent); 
} 
 
void CGridCtrl::InsertColumn(int nCol,LPCTSTR pszText,DWORD nStyle,int nWidth) 
{ 
	ASSERT(nCol>=0); 
	CColumn col; 
	col.pData=(PVOID)CString::StrAllocEx(pszText); 
	col.nStyle=nStyle; 
	col.nWidth=nWidth; 
	m_aGridCol.InsertAt(nCol,col); 
} 
 
void CGridCtrl::DeleteColumn(int nCol) 
{ 
	ASSERT(nCol>=0); 
	ASSERT(nCol0) 
	{ 
		arg.rect.bottom=arg.rect.top+m_nHeaderHeight; 
		pDC->GetClipRect(rclClip); 
		rclClip.IntersectRect(arg.rect); 
		if(!rclClip.IsRectEmpty()) 
		{ 
			arg.nRow=-1; 
			pCol=m_aGridCol.GetData(); 
			for(arg.nCol=0;arg.nColnStyle; 
				arg.pData=pCol->pData; 
				arg.rect.right=arg.rect.left+pCol->nWidth; 
				MsgProc(gcmDrawHeader,WPARAM(pDC),LPARAM(&arg)); 
				arg.rect.left=arg.rect.right; 
				pCol++; 
			} 
			arg.rect.left=nLeft; 
			arg.rect.right=nRight; 
		} 
		arg.rect.top=arg.rect.bottom; 
	} 
	for(arg.nRow=0;arg.nRowGetClipRect(rclClip); 
		rclClip.IntersectRect(arg.rect); 
		pos=m_aGridRow[arg.nRow]; 
		if(pos && !rclClip.IsRectEmpty()) 
		{ 
			nRowState=MsgProc(gcmGetRowState,WPARAM(pos),arg.nRow); 
			pCol=m_aGridCol.GetData(); 
			for(arg.nCol=0;arg.nColnStyle; 
				arg.pData=GetDSCellData(pos,arg.nCol); 
				arg.rect.right=arg.rect.left+pCol->nWidth; 
				MsgProc(gcmDrawCell,WPARAM(pDC),LPARAM(&arg)); 
				arg.rect.left=arg.rect.right; 
				pCol++; 
			} 
			arg.rect.left=nLeft; 
			arg.rect.right=nRight; 
		} 
		arg.rect.top=arg.rect.bottom; 
		arg.rect.bottom+=m_nRowHeight; 
	} 
} 
 
int CGridCtrl::ScrollRow(int nRows) 
{ 
	POSITION pos=m_aGridRow[m_nCurGridRow]; 
	pos=GetDSRow(pos,nRows); 
	m_aGridRow[m_nCurGridRow]=pos; 
	RefreshGridData(); 
	Invalidate(NULL); 
	return nRows; 
} 
 
void CGridCtrl::RedrawRow(int nRow) 
{ 
	CRect r; 
	GetRowRect(nRow,r); 
	Invalidate(r); 
} 
 
void CGridCtrl::GetRowRect(int nRow,LPRECT pRect) 
{ 
	GetClientRect(pRect); 
	pRect->top+=m_nHeaderHeight; 
	pRect->top+=nRow*m_nRowHeight; 
	pRect->bottom=pRect->top+m_nRowHeight; 
} 
 
void CGridCtrl::GetHeaderRect(LPRECT pRect) 
{ 
	GetClientRect(pRect); 
	pRect->bottom=pRect->top+m_nHeaderHeight; 
} 
 
int CGridCtrl::HitTest(CPoint pt) 
{ 
	CRect r; 
	GetClientRect(r); 
	r.top+=m_nHeaderHeight; 
	if(!r.PtInRect(pt)) 
		return -1; 
	pt.y-=r.top; 
	pt.y/=m_nRowHeight; 
	return pt.y; 
} 
 
DWORD CGridCtrl::AddRowState(int nRow,DWORD nState) 
{ 
	POSITION pos=m_aGridRow[nRow]; 
	return MsgProc(gcmAddRowState,WPARAM(pos),nState); 
} 
 
DWORD CGridCtrl::RemoveRowState(int nRow,DWORD nState) 
{ 
	POSITION pos=m_aGridRow[nRow]; 
	return MsgProc(gcmRemoveRowState,WPARAM(pos),nState); 
} 
 
DWORD CGridCtrl::GetRowState(int nRow) 
{ 
	POSITION pos=m_aGridRow[nRow]; 
	return MsgProc(gcmGetRowState,WPARAM(pos),nRow); 
} 
 
 
BOOL CGridCtrl::ActiveCell(int nRow,int nCol) 
{ 
	POSITION pos=m_aGridRow[nRow]; 
	return MsgProc(gcmActiveCell,WPARAM(pos),nCol); 
} 
 
BOOL CGridCtrl::DeactiveCell(int nRow,int nCol) 
{ 
	POSITION pos=m_aGridRow[nRow]; 
	return MsgProc(gcmDeactiveCell,WPARAM(pos),nCol); 
} 
 
void CGridCtrl::OnDestroy() 
{ 
	CColumn *pCol=m_aGridCol.GetData(); 
	CColumn *pColEnd=(CColumn*)(DWORD(pCol)+_msize(pCol)); 
	while(pColpData)); 
		pCol++; 
	} 
	m_aGridRow.RemoveAll(); 
	m_aGridCol.RemoveAll(); 
	CWnd::OnDestroy(); 
} 
 
void CGridCtrl::OnMove() 
{ 
	CWnd::OnMove(); 
 
	int nSize; 
	POSITION pos; 
	nSize=GetClientRect().Height(); 
	nSize-=m_nHeaderHeight; 
	nSize+=m_nRowHeight-1; 
	nSize/=m_nRowHeight; 
	if(nSize<1)nSize=1; 
 
	if(!m_aGridRow.GetSize()) 
	{ 
		pos=GetDSRow(NULL,0); 
		m_aGridRow.SetSize(nSize); 
		m_nCurGridRow=0; 
		m_aGridRow[0]=pos; 
		nSize=-nSize; 
	} 
	else if(m_nCurGridRow>=nSize) 
	{ 
		pos=m_aGridRow[m_nCurGridRow]; 
		m_aGridRow.SetSize(nSize); 
		m_nCurGridRow=nSize-1; 
		m_aGridRow[m_nCurGridRow]=pos; 
	} 
	else  
		m_aGridRow.SetSize(nSize); 
	RefreshGridData(); 
	if(nSize<0) 
		AddRowState(0,GCS_ROWSELECTED); 
 
} 
 
void CGridCtrl::RefreshGridData() 
{ 
	int i,nCnt=m_aGridRow.GetSize(); 
	POSITION pos; 
	 
	i=m_nCurGridRow; 
	pos=m_aGridRow[i]; 
	for(i++;pos && i=0;i--) 
	{ 
		pos=GetDSRow(pos,-1); 
		m_aGridRow[i]=pos; 
	} 
	for(;i>=0;i--) 
		m_aGridRow[i]=NULL; 
} 
 
void CGridCtrl::OnDrawHeader(CDC* pDC,PGCDRAWCELLARG pArg) 
{ 
	DWORD nStyle=pArg->nStyle; 
	LPCTSTR pszText=LPCTSTR(pArg->pData); 
	COLORREF clr,clr0; 
	CFont* pFont; 
 
	pFont=pDC->SelectObject(GetFont()); 
	clr=GetCtlColor(COLOR_WINDOWTEXT); 
	clr=pDC->SetTextColor(clr); 
	clr0=pDC->SetBkColor(CLR_NONE); 
	nStyle &= GCS_CENTER; 
	pDC->DrawText(pszText,strlen(pszText),pArg->rect,nStyle); 
	pDC->SetBkColor(clr0); 
	pDC->SetTextColor(clr); 
	pDC->SelectObject(pFont); 
} 
 
void CGridCtrl::OnDrawCell(CDC* pDC,PGCDRAWCELLARG pArg) 
{ 
	switch(pArg->nStyle&GCS_TYPEMASK) 
	{ 
	case GCS_TEXT: 
		DrawText(pDC,pArg); 
		break; 
	case GCS_BITMAP: 
		DrawBitmap(pDC,pArg); 
		break; 
	} 
} 
 
void CGridCtrl::DrawBitmap(CDC* pDC,PGCDRAWCELLARG pArg) 
{ 
	CBitmap* pBitmap=(CBitmap*)pArg->pData; 
	DWORD nStyle=pArg->nStyle; 
	if(!pBitmap || !pBitmap->GetBitmap().bmBits)return; 
 
	if(nStyle & (GCS_ROWSELECTED|GCS_ROWFOCUSED)) 
	{ 
		COLORREF clr=GetCtlColor(COLOR_HIGHLIGHT)|(128<<24); 
		clr=pDC->SetTextColor(clr); 
		nStyle&=nStyle&GCS_STYLEMASK; 
		pDC->BitBlt(pArg->rect,pBitmap,NULL,(nStyle&GCS_STYLEMASK)|R2_ALPHABLENDPEN); 
		pDC->SetTextColor(clr); 
	} 
	else 
	{ 
		nStyle&=nStyle&GCS_STYLEMASK; 
		pDC->BitBlt(pArg->rect,pBitmap,NULL,nStyle&GCS_STYLEMASK); 
	} 
} 
 
void CGridCtrl::DrawText(CDC* pDC,PGCDRAWCELLARG pArg) 
{ 
	DWORD nStyle=pArg->nStyle; 
	COLORREF clr,clr0; 
	LPCTSTR pszText=LPCTSTR(pArg->pData); 
	int nLen; 
	CFont* pFont; 
 
	pFont=pDC->SelectObject(GetFont()); 
	clr=(nStyle&(GCS_ROWSELECTED|GCS_ROWFOCUSED))? 
		COLOR_HIGHLIGHTTEXT:COLOR_WINDOWTEXT; 
	clr=GetCtlColor(clr); 
	clr=pDC->SetTextColor(clr); 
	clr0=pDC->SetBkColor(CLR_NONE); 
	nLen=(nStyle&GCS_STRLENEX)? 
		CString::StrLenEx(pszText):strlen(pszText); 
	nStyle &= BS_DTMASK; 
	pDC->DrawText(pszText,nLen,pArg->rect,nStyle); 
	pDC->SetBkColor(clr0); 
	pDC->SetTextColor(clr); 
	pDC->SelectObject(pFont); 
}