1、CListCtrl控件 :OwnerDraw Fixed = True,创建一个CListCtrl类的派生类CMyListCtrl,同时创建一个CMyListCtrl控件类型变量:CMyListCtrl m_cList;。
CListCtrl控件的自绘主要是CMyListCtrl类中重写DrawItem虚函数。
流程:
1.主对话框中CListCtrl的一些初始化操作:
BOOL CCListCtrl自绘Dlg::OnInitDialog() { CDialogEx::OnInitDialog(); SetIcon(m_hIcon, TRUE); // 设置大图标 SetIcon(m_hIcon, FALSE); // 设置小图标 m_ImgList.Create(16,16,ILC_COLOR32|ILC_MASK,3,3);//创建CImageList对象 //m_ImgList.SetBkColor(RGB(255,255,255));//设置图标的白色背景,和ILC_MASK作用相似,但不同 m_ImgList.Add(AfxGetApp()->LoadIcon(IDI_ICON1));//向CImageList对象中添加图标 m_ImgList.Add(AfxGetApp()->LoadIcon(IDI_ICON2)); m_ImgList.Add(AfxGetApp()->LoadIcon(IDI_ICON3)); m_cList.SetImageList(&m_ImgList,LVSIL_SMALL);//绑定图标列表到CListCtrl控件 m_cList.SetExtendedStyle(m_cList.GetExtendedStyle()//设置列表框属性 |LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES/*|LVS_EX_HEADERDRAGDROP*/); m_cList.InsertColumn(0,"编号",LVCFMT_CENTER,100,1); m_cList.InsertColumn(1,"姓名",LVCFMT_CENTER,100,2); m_cList.InsertColumn(2,"国籍",LVCFMT_CENTER,100,3); return TRUE; // 除非将焦点设置到控件,否则返回 TRUE }
添加数据按钮:
void CCListCtrl自绘Dlg::OnBnClickedButton() { CString strNum; int nCount = m_cList.GetItemCount(); strNum.Format("100%d",nCount); m_cList.InsertItem(nCount,strNum,nCount%3); m_cList.SetItemText(nCount,1,"张三"); m_cList.SetItemText(nCount,2,"中国"); }
2、最重要的就是派生类的封装,以下可以直接拿来使用:
.h文件:
#pragma once // CMyListCtrl class CMyListCtrl : public CListCtrl { DECLARE_DYNAMIC(CMyListCtrl) public: CMyListCtrl(); virtual ~CMyListCtrl(); protected: DECLARE_MESSAGE_MAP() public: int m_nSelColumn; virtual void DrawItem(LPDRAWITEMSTRUCT lpDIS); void DrawBKGround(CDC* pDC,CRect Rt,LPDRAWITEMSTRUCT lpDIS,BOOL bColumnSel = FALSE); void DrawImage(CDC* pDC,CPoint Pt,int nItem); afx_msg void OnLvnColumnclick(NMHDR *pNMHDR, LRESULT *pResult); };
.cpp文件:
// MyListCtrl.cpp : 实现文件 // #include "stdafx.h" #include "CListCtrl自绘.h" #include "MyListCtrl.h" // CMyListCtrl IMPLEMENT_DYNAMIC(CMyListCtrl, CListCtrl) CMyListCtrl::CMyListCtrl() { m_nSelColumn = -1; } CMyListCtrl::~CMyListCtrl() { } BEGIN_MESSAGE_MAP(CMyListCtrl, CListCtrl) ON_NOTIFY_REFLECT(LVN_COLUMNCLICK, &CMyListCtrl::OnLvnColumnclick) END_MESSAGE_MAP() // CMyListCtrl 消息处理程序 void CMyListCtrl::DrawItem(LPDRAWITEMSTRUCT lpDIS) { CDC dc; dc.Attach(lpDIS->hDC);//获取DC int nItemIndex = lpDIS->itemID;//获取当前行的索引 CRect ListRect = lpDIS->rcItem;//获取整个一行的矩形大小 CHeaderCtrl* pHead = GetHeaderCtrl();//获取标头控件指针 int nHeadCount = pHead->GetItemCount();//获取一行的列的数目 CRect TempRect; int nColumnIndex = 0; //原理:绘制每一行时,是按照一列一列从左到右进行绘制的 while (nColumnIndex < nHeadCount) { pHead->GetItemRect(nColumnIndex,TempRect);//获取当前行,第ColumnIndex列的Rect大小 TempRect.top = ListRect.top;//top和bottom不一样,所以这里要赋值? TempRect.bottom = ListRect.bottom; if (m_nSelColumn == nColumnIndex) DrawBKGround(&dc,TempRect,lpDIS,TRUE);//选中列的背景 else DrawBKGround(&dc,TempRect,lpDIS);//绘制没选中列的背景绘制背景 //对每行的第一列绘制图标 if(nColumnIndex == 0) DrawImage(&dc,TempRect.TopLeft(),nItemIndex); //绘制 nItemIndex行、ColumnIndex列的文字 CString strText = GetItemText(nItemIndex,nColumnIndex); if(nColumnIndex == 0) TempRect.left += 16 + 4; else TempRect.left += 4; dc.DrawText(strText,&TempRect,DT_VCENTER|DT_SINGLELINE); nColumnIndex++; } if (lpDIS->itemState & ODS_FOCUS) { CRect RtTemp = ListRect; RtTemp.DeflateRect(1,1); dc.DrawFocusRect(RtTemp); } dc.Detach(); } void CMyListCtrl::DrawBKGround(CDC* pDC,CRect Rt,LPDRAWITEMSTRUCT lpDIS,BOOL bColumnSel) { if (lpDIS->itemState & ODS_SELECTED)//选中行蓝底白字 { pDC->FillSolidRect(&Rt,GetSysColor(COLOR_HIGHLIGHT)); //dc.SetBkColor(GetSysColor(COLOR_HIGHLIGHT)); pDC->SetTextColor(GetSysColor(COLOR_HIGHLIGHTTEXT)); } else//非选中行彩底黑字 { //dc.SetBkColor(GetSysColor(COLOR_WINDOW)); pDC->SetTextColor(GetSysColor(COLOR_WINDOWTEXT)); if (bColumnSel)//某一列被选中,颜色加深 { if (lpDIS->itemID % 2 == 0) pDC->FillSolidRect(&Rt,RGB(145,180,222)); else pDC->FillSolidRect(&Rt,RGB(233,233,233)); } else { if (lpDIS->itemID % 2 == 0) pDC->FillSolidRect(&Rt,RGB(165,203,247)); else pDC->FillSolidRect(&Rt,RGB(210,210,210)); } } } void CMyListCtrl::DrawImage(CDC* pDC,CPoint Pt,int nItem) { LVITEM Lv = {LVIF_IMAGE};//指明获取什么类型的数据 Lv.iItem = nItem;//指明获取第几行的图标 GetItem(&Lv); CImageList* pImgList = GetImageList(LVSIL_SMALL); pImgList->Draw(pDC,Lv.iImage,Pt,ILD_TRANSPARENT); } void CMyListCtrl::OnLvnColumnclick(NMHDR *pNMHDR, LRESULT *pResult) { LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR); *pResult = 0; m_nSelColumn = pNMLV->iSubItem; Invalidate(); }