CListCtrl控件的自绘操作
程序员文章站
2022-03-10 22:17:08
...
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();
}
推荐阅读
-
利用Aspose.Word控件实现Word文档的操作
-
Android 自绘控件
-
利用Aspose.Word控件实现Word文档的操作
-
在ASP.NET 2.0中操作数据之三十二:数据控件的嵌套
-
在ASP.NET 2.0中操作数据之三十九:在DataList的编辑界面里添加验证控件
-
在GridControl控件上绑定图片的几种操作方式详解
-
详解ASP.NET数据绑定操作中Repeater控件的用法
-
在ASP.NET 2.0中操作数据之三十二:数据控件的嵌套
-
在ASP.NET 2.0中操作数据之三十九:在DataList的编辑界面里添加验证控件
-
在GridControl控件上绑定图片的几种操作方式详解