VS2019 List Control 控件自绘例程继承CListCtrl类 OnNMCustomdraw重绘

32 篇文章 2 订阅

郑重声明:

        本例程采用网上例程封装,网上历程介绍有误,错误主要是指封装类应用要将控件的自绘类型设置为True。实际应用是无需设置控件的自绘类型,如果设置为True控件必须调用DrawItem进行自绘,而

本文采用的是OnNMCustomdraw进行自绘,因此会导致程序报错,所以控件的自绘属性并不需要任何设定。其他版本的VS不知道是否需要设定,本例程使用的是VS2019因此发现List Control控件的自会属性并不需要设置自绘属性 

 封装类H头文件ListCtrlEx.h

#pragma once

class CListCtrlEx : public CListCtrl
{
	DECLARE_DYNAMIC(CListCtrlEx)
public:
	int			m_hoverIndex;			// 当前热点项目索引(热点就是鼠标停在某一行上)
	bool		m_mouseTrack;			// 是否追踪鼠标移动事件
	bool		m_if_hotLine;			// 是否改变热点行的颜色
	COLORREF	m_oddItemBkColor;		// 奇数行背景颜色
	COLORREF	m_oddItemTextColor;		// 奇数行文字颜色
	COLORREF	m_evenItemBkColor;		// 偶数行背景颜色
	COLORREF	m_evenItemTextColor;	// 偶数行文字颜色
	COLORREF	m_hoverItemBkColor;		// 热点行背景颜色
	COLORREF	m_hoverItemTextColor;	// 热点行文字颜色
	COLORREF	m_selectItemBkColor;	// 选中行背景颜色
	COLORREF	m_selectItemTextColor;	// 选中行文字颜色

public:
	void SetOddItemBkColor(COLORREF color);
	void SetOddItemTextColor(COLORREF color);
	void SetEvenItemBkColor(COLORREF color);
	void SetEvenItemTextColor(COLORREF color);
	void SetHoverItemBkColor(COLORREF color);
	void SetHoverItemTextColor(COLORREF color);
	void SetSelectItemBkColor(COLORREF color);
	void SetSelectItemTextColor(COLORREF color);

public:
	CListCtrlEx();
	virtual ~CListCtrlEx();

protected:
	DECLARE_MESSAGE_MAP()

public:
	afx_msg void OnMouseMove(UINT nFlags, CPoint point);
	afx_msg void OnMouseLeave();
	afx_msg BOOL OnEraseBkgnd(CDC* pDC);
	afx_msg void OnPaint();
	afx_msg void OnNMCustomdraw(NMHDR *pNMHDR, LRESULT *pResult);
	afx_msg void OnLvnColumnclick(NMHDR *pNMHDR, LRESULT *pResult);
	struct GetItemColumnText
	{
		CString nColumn_UserName;
		CString nColumn_UserPwd;
		CString nColumn_UserType;		 
	}m_UserDataInformation;
	//virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
};


  封装类CPP文件ListCtrlEx.CPP


#include"pch.h"
#include "ListCtrlEx.h"
#pragma warning(disable:26454)

IMPLEMENT_DYNAMIC(CListCtrlEx, CListCtrl)

/**
 * 构造函数
 */
CListCtrlEx::CListCtrlEx()
{
	m_hoverIndex			=	-1;						// 当前热点项目索引
	m_mouseTrack			=	true;					// 追踪鼠标移动事件
	m_if_hotLine			=	true;					// 默认不开启热点行更换颜色
	m_oddItemBkColor		=   RGB(240, 252, 255);		// 奇数行背景颜色(默认白色)
	m_evenItemBkColor		=   RGB(255, 251, 240);		// 偶数行背景颜色(默认白色)
	m_hoverItemBkColor		=   RGB(238, 222, 176);		// 热点行背景颜色(默认白色)
	m_selectItemBkColor		=   RGB(192, 235, 215);		// 选中行背景颜色(默认蓝色)
	m_oddItemTextColor		=   RGB(16, 18, 23);	    // 奇数行文本颜色(默认黑色)
	m_evenItemTextColor		=   RGB(16, 18, 23);		// 偶数行文本颜色(默认黑色)
	m_hoverItemTextColor	=   RGB(29,209,165);		// 热点行文本颜色(默认黑色)
	m_selectItemTextColor	=   RGB(190,0,47);		    // 选中行文本颜色(默认黑色)
}


/**
 * 析构函数
 */
CListCtrlEx::~CListCtrlEx()
{
}


BEGIN_MESSAGE_MAP(CListCtrlEx, CListCtrl)
	ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, &CListCtrlEx::OnNMCustomdraw)
	ON_WM_MOUSEMOVE()
	ON_WM_MOUSELEAVE()
	ON_WM_ERASEBKGND()
	ON_WM_PAINT()
	ON_NOTIFY_REFLECT(LVN_COLUMNCLICK, &CListCtrlEx::OnLvnColumnclick)
END_MESSAGE_MAP()


/**
 * 排序回调函数
 */
static int CALLBACK SortFunction(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
	CString &lp1 = *((CString *)lParam1);
	CString &lp2 = *((CString *)lParam2);
	int &sort = *(int *)lParamSort;

	if (sort == 0)
		return lp1.CompareNoCase(lp2);
	else
		return lp2.CompareNoCase(lp1);
}


/**
 * 鼠标在控件区域上移动时
 */
void CListCtrlEx::OnMouseMove(UINT nFlags, CPoint point)
{
	if(m_if_hotLine == true) {
		// 获取鼠标当前在哪一行上
		int	newIndex;									// 当前鼠标的一行
		int	oldIndex;									// 记录原来的一行(也就是离开前的那一行)

		newIndex = HitTest(point);
		if(newIndex != m_hoverIndex) {
			CRect rc;
			oldIndex = m_hoverIndex;
			m_hoverIndex = newIndex;

			// 刷新离开后的那一块区域
			if(oldIndex != -1) {
				GetItemRect(oldIndex, &rc, LVIR_BOUNDS);
				InvalidateRect(&rc);
			}
			// 刷新来到新的一块的区域
			if(m_hoverIndex != -1) {
				GetItemRect(m_hoverIndex, &rc, LVIR_BOUNDS);
				InvalidateRect(&rc);
			}
		}

		// 鼠标要追踪WM_MOUSELEAVE事件
		if (m_mouseTrack) {
			TRACKMOUSEEVENT csTME;
			csTME.cbSize = sizeof(csTME);
			csTME.dwFlags = TME_LEAVE;					// 指定要追踪的事件
			csTME.hwndTrack = m_hWnd;					// 指定要追踪的窗口 
			::_TrackMouseEvent(&csTME);					// 开启Windows的WM_MOUSELEAVE事件支持
			m_mouseTrack = false;						// 若已经追踪,则停止追踪 
		}
	}

	CListCtrl::OnMouseMove(nFlags, point);
}


/**
 * 鼠标离开控件区域时
 */
void CListCtrlEx::OnMouseLeave()
{
	if(m_if_hotLine == true) {
		// 开始追踪
		m_mouseTrack = true;
	
		if(m_hoverIndex != -1) {
			CRect rc;
			GetItemRect(m_hoverIndex,&rc,LVIR_BOUNDS);
			InvalidateRect(&rc);
			m_hoverIndex = -1;
			m_mouseTrack = true;
		}
	}

	CListCtrl::OnMouseLeave();
}


/**
 * 擦除背景
 */
BOOL CListCtrlEx::OnEraseBkgnd(CDC* pDC)
{
	return FALSE;
}


/**
 * 绘画
 */
void CListCtrlEx::OnPaint()
{
	CPaintDC dc(this);
	CRect rect;
    CRect headerRect;
    CDC memDC;
    CBitmap bitmap;

	GetClientRect(&rect);
	GetDlgItem(0)->GetWindowRect(&headerRect);
	memDC.CreateCompatibleDC(&dc);
	bitmap.CreateCompatibleBitmap(&dc, rect.Width(), rect.Height());
	memDC.SelectObject(&bitmap);
	memDC.FillSolidRect(&rect, RGB(240, 255, 255));
	// 调用默认的OnPaint(),把图形画在内存DC表上
	DefWindowProc(WM_PAINT, (WPARAM)memDC.m_hDC, (LPARAM)0);
	// 输出到显示设备
	dc.BitBlt(0, headerRect.Height(), rect.Width(), rect.Height(), &memDC, 0, headerRect.Height(), SRCCOPY);
	memDC.DeleteDC();
	bitmap.DeleteObject();
}

/**
 * 自绘
 */
void CListCtrlEx::OnNMCustomdraw(NMHDR *pNMHDR, LRESULT *pResult)
{
	LPNMLVCUSTOMDRAW pNMCD = reinterpret_cast<LPNMLVCUSTOMDRAW>(pNMHDR);
	int	itemIndex = pNMCD->nmcd.dwItemSpec;

	if (pNMCD->nmcd.dwDrawStage == CDDS_PREPAINT) {
		*pResult = CDRF_NOTIFYITEMDRAW;
	}
	else if (pNMCD->nmcd.dwDrawStage == CDDS_ITEMPREPAINT) 
	{
		// 选中行(鼠标选中的行)
		if(GetItemState(itemIndex,LVIS_SELECTED) == LVIS_SELECTED)
		{
			pNMCD->nmcd.uItemState = ~CDIS_SELECTED;
			pNMCD->clrTextBk = m_selectItemBkColor;
			pNMCD->clrText = pNMCD->clrFace = m_selectItemTextColor;
		}
		// CheckBox打钩行
		else if(GetCheck(itemIndex) && (GetExtendedStyle() & LVS_EX_CHECKBOXES)) {
			pNMCD->clrTextBk = m_selectItemBkColor;
			pNMCD->clrText = m_selectItemTextColor;
		}
		// 热点行(鼠标停在上方)
		else if(itemIndex==m_hoverIndex) {
			pNMCD->clrTextBk = m_hoverItemBkColor;
			pNMCD->clrText = m_hoverItemTextColor;
		}
		// 偶数行(比如 0、2、4、6)
		else if(itemIndex % 2==0){
			pNMCD->clrTextBk=m_evenItemBkColor;
			pNMCD->clrText=m_evenItemTextColor;
		}
		// 奇数行(比如 1、3、5、7)
		else{
			pNMCD->clrTextBk = m_oddItemBkColor;
			pNMCD->clrText = m_oddItemTextColor;
		}
		*pResult = CDRF_NEWFONT;
	}
}


/**
 * 点击表头(这里主要将列表中的数据进行排序)
 */
void CListCtrlEx::OnLvnColumnclick(NMHDR *pNMHDR, LRESULT *pResult)
{
	int count = 0;
	static int sort = 0;
	static int subItem = 0;
	CArray<CString,CString> itemData;
	LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);

	// 获取总共有多少行
	count = GetItemCount();
	itemData.SetSize(count);

	// 设置待排序的数据
	for (int i = 0; i < count; i++) {
		itemData[i] = GetItemText(i, pNMLV->iSubItem);
		SetItemData(i, (DWORD_PTR)&itemData[i]);		// 设置待排序的数据
	}

	// 若点击到另一列的表头中
	if (subItem != pNMLV->iSubItem) {
		sort = 0;
		subItem = pNMLV->iSubItem;
	}
	// 若点击在同一列的表头中(升序排列时,则改成降序;降序排列时,则改成升序)
	else {
		sort = (sort == 0 ? 1 : 0);
	}

	SortItems(SortFunction,(DWORD_PTR)&sort);			// 调用回调函数,进行排序
	*pResult = 0;
}


/**
 * 设置奇数行背景颜色
 *
 * @param oddItemBkColor 奇数行背景颜色
 */
void CListCtrlEx::SetOddItemBkColor(COLORREF oddItemBkColor)
{
	m_oddItemBkColor = oddItemBkColor;
}


/**
 * 设置奇数行文字颜色
 *
 * @param oddItemBkColor 奇数行文字颜色
 */
void CListCtrlEx::SetOddItemTextColor(COLORREF oddItemTextColor)
{
	m_oddItemTextColor = oddItemTextColor;
}


/**
 * 设置偶数行背景颜色
 *
 * @param evenItemBkColor 偶数行背景颜色
 */
void CListCtrlEx::SetEvenItemBkColor(COLORREF evenItemBkColor)
{
	m_evenItemBkColor = evenItemBkColor;
}


/**
 * 设置偶数行文字颜色
 *
 * @param evenItemTextColor 偶数文字颜色
 */
void CListCtrlEx::SetEvenItemTextColor(COLORREF evenItemTextColor)
{
	m_evenItemTextColor = evenItemTextColor;
}


/**
 * 设置热点行背景颜色
 *
 * @param hoverItemBkColor 热点行背景颜色
 */
void CListCtrlEx::SetHoverItemBkColor(COLORREF hoverItemBkColor)
{
	m_hoverItemBkColor = hoverItemBkColor;
	m_if_hotLine = true;
}


/**
 * 设置热点行文字颜色
 *
 * @param hoverItemTextColor 热点行文字颜色
 */
void CListCtrlEx::SetHoverItemTextColor(COLORREF hoverItemTextColor)
{
	m_hoverItemTextColor = hoverItemTextColor;
	m_if_hotLine = true;
}


/**
 * 设置选中行背景颜色
 *
 * @param selectItemBkColor 选中行背景颜色
 */
void CListCtrlEx::SetSelectItemBkColor(COLORREF selectItemBkColor)
{
	m_selectItemBkColor = selectItemBkColor;
}


/**
 * 设置选中行文字颜色
 *
 * @param selectItemTextColor 选中行文字颜色
 */
void CListCtrlEx::SetSelectItemTextColor(COLORREF selectItemTextColor)
{
	m_selectItemTextColor = selectItemTextColor;
}

 读取Access数据库例程

 

 

 

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lzc881012

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值