📄 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(nCol<m_aGridCol.GetSize());
m_aGridCol.RemoveAt(nCol);
Invalidate(NULL);
}
void CGridCtrl::OnPaint(CDC* pDC)
{
int nRowCnt=m_aGridRow.GetSize();
int nColCnt=m_aGridCol.GetSize();
int nLeft,nRight;
DWORD nRowState;
POSITION pos;
CColumn* pCol;
CRect rclClip;
GCDRAWCELLARG arg;
GetClientRect(arg.rect);
nLeft=arg.rect.left;
nRight=arg.rect.right;
if(m_nHeaderHeight>0)
{
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.nCol<nColCnt;arg.nCol++)
{
arg.nStyle=pCol->nStyle;
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.nRow<nRowCnt;arg.nRow++)
{
arg.rect.bottom=arg.rect.top+m_nRowHeight;
pDC->GetClipRect(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.nCol<nColCnt;arg.nCol++)
{
arg.nStyle=nRowState|pCol->nStyle;
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(pCol<pColEnd)
{
CString::StrFreeEx(LPCTSTR(pCol->pData));
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<nCnt;i++)
{
pos=GetDSRow(pos,1);
m_aGridRow[i]=pos;
}
for(;i<nCnt;i++)
m_aGridRow[i]=NULL;
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);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -