经常使用ClistCtrl来显示大量的数据,但是总感觉焦点行的背景颜色为蓝色,显示的效果挺难看的,参考《MFC技术内幕》这本书中的例子,自己修改了ClistCtrl的OnPaint
代码,把焦点行改为白色的背景,加了一个矩形的边框,下面实际的效果,自我感觉还不错;
实现思路:
1、 首先调用Default,让ClistCtrl自己画
2、 调用
GetDC()
函数获得
DC
3、
调用
GetFont()
获得当前字体
4、
使用
GetSubItemRect
函数获得每一个列的矩形大小,然后使用
DrawText函数把文字画出来
5、 最后使用Rectangle函数画出边框,这样就达到了图中的效果了
下面是主要的代码
void CXListCtrl::OnPaint()
{
Default();
CRect rect;
int nSel=GetCurSel();
if (nSel<0) return;
CDC *dc=GetDC(); // don't use CPaintDC
CFont * pFont=GetFont();
//
把背景刷为白色
GetItemRect(nSel,rect,LVIR_BOUNDS);
CBrush brush(RGB(255,255,255));
CBrush * pOldBrush=dc->SelectObject(&brush);
dc->Rectangle(rect.left,rect.top,rect.right,rect.bottom);
//
开始画焦点行的每一列文字
CFont * pOldFont=dc->SelectObject(pFont);
CString strTemp;
int nColumns=GetColumns();
HDITEM hditem;
UINT nFormat;
int nFmt;
for (int i=0;i<nColumns;i++)
{
strTemp=GetItemText(nSel,i);
GetSubItemRect(nSel, i, LVIR_BOUNDS, rect);
//
得到每一列文字的对齐方式
hditem.mask = HDI_FORMAT;
m_HeaderCtrl.GetItem(i, &hditem);
nFmt = hditem.fmt & HDF_JUSTIFYMASK;
nFormat= DT_VCENTER | DT_SINGLELINE;
if (nFmt == HDF_CENTER)
nFormat |= DT_CENTER;
else if (nFmt == HDF_LEFT)
nFormat |= DT_LEFT;
else
nFormat |= DT_RIGHT;
dc->DrawText(strTemp, &rect, nFormat);
}
//
画边框
CPen * pOldPen=dc->SelectObject(m_SelPen);
GetItemRect(nSel,rect,LVIR_BOUNDS);
dc->SelectStockObject(NULL_BRUSH); //
设置
NULL_BRUSH
dc->Rectangle(rect.left,rect.top,rect.right,rect.bottom);
dc->SelectObject(pOldPen);
dc->SelectObject(pOldBrush);
dc->SelectObject(pFont);
}
在实现过程中,要注意的问题:
1、 焦点行的字体要和其他行的字体一样
2、 每一列的对齐方式
3、 画完焦点行的文字以后,再画外边框
当然,这只是一个种效果,还可以画出另外自己需要的效果;