欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

ListBox控件自绘

程序员文章站 2022-03-10 22:24:03
...

原理和步骤和前面控件相差无几,这里就不讲了,只贴完整代码:

主对话框类:

#pragma once
#include "MyListBox.h"


// CListBox自绘Dlg 对话框
class CListBox自绘Dlg : public CDialogEx
{
// 构造
public:
	CListBox自绘Dlg(CWnd* pParent = NULL);	// 标准构造函数

// 对话框数据
	enum { IDD = IDD_LISTBOX_DIALOG };

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV 支持


// 实现
protected:
	HICON m_hIcon;

	// 生成的消息映射函数
	virtual BOOL OnInitDialog();
	afx_msg void OnPaint();
	afx_msg HCURSOR OnQueryDragIcon();
	DECLARE_MESSAGE_MAP()
public:
	CMyListBox m_ListBox;
	CImageList m_ImgList;
	afx_msg void OnBnClickedBtn();
};

// ListBox自绘Dlg.cpp : 实现文件
//

#include "stdafx.h"
#include "ListBox自绘.h"
#include "ListBox自绘Dlg.h"
#include "afxdialogex.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

// CListBox自绘Dlg 对话框

CListBox自绘Dlg::CListBox自绘Dlg(CWnd* pParent /*=NULL*/)
	: CDialogEx(CListBox自绘Dlg::IDD, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CListBox自绘Dlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_LIST, m_ListBox);
}

BEGIN_MESSAGE_MAP(CListBox自绘Dlg, CDialogEx)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BTN, &CListBox自绘Dlg::OnBnClickedBtn)
END_MESSAGE_MAP()

BOOL CListBox自绘Dlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标

	m_ImgList.Create(32,32,ILC_COLOR32|ILC_MASK,3,3);

	m_ImgList.Add(AfxGetApp()->LoadIcon(IDI_ICON1));
	m_ImgList.Add(AfxGetApp()->LoadIcon(IDI_ICON2));
	m_ImgList.Add(AfxGetApp()->LoadIcon(IDI_ICON3));

	m_ListBox.SetImageList(&m_ImgList);

	m_ListBox.AddString("北京",0);
	m_ListBox.AddString("上海",1);
	m_ListBox.AddString("广州",2);



	return TRUE;  
}

void CListBox自绘Dlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // 用于绘制的设备上下文

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// 使图标在工作区矩形中居中
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// 绘制图标
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialogEx::OnPaint();
	}
}

HCURSOR CListBox自绘Dlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}

void CListBox自绘Dlg::OnBnClickedBtn()
{
	static int nCount = 1;

	CString strText;

	strText.Format("Item%d",nCount);

	m_ListBox.AddString(strText,nCount++ % 3);
}

CListBox的派生类:

#pragma once


// CMyListBox

class CMyListBox : public CListBox
{
	DECLARE_DYNAMIC(CMyListBox)

public:
	CMyListBox();
	virtual ~CMyListBox();

protected:
	DECLARE_MESSAGE_MAP()
public:

	struct SLBData{     //存放文本和图标索引数据
		CString strText;
		int nImgIndex;
		SLBData()
		{
			strText.Empty();
			nImgIndex = -1;
		}
	};

	CImageList* m_ImgList;//接收主对话框类传递过来的CImageList对象
	virtual void DrawItem(LPDRAWITEMSTRUCT lpDIS);//重绘函数
	CImageList* SetImageList(CImageList* pImgList);//传递CImageList对象到派生类
	int AddString(CString strText,int nImgIndex);//保存要插入的文本和图标索引
	int GetText(int nItemIndex,CString& strText);//由当前绘制项的索引获取文本
	int GetImage(int nItemIndex,int& nImageIndex);//由当前绘制项的索引获取对应图标的索引
	void ReleaseMemory();//ListBox销毁时释放申请的所有内存
	virtual void MeasureItem(LPMEASUREITEMSTRUCT lpMIS);
	afx_msg void OnDestroy();
};



// MyListBox.cpp : 实现文件
//

#include "stdafx.h"
#include "ListBox自绘.h"
#include "MyListBox.h"


// CMyListBox

IMPLEMENT_DYNAMIC(CMyListBox, CListBox)

CMyListBox::CMyListBox()
{
	m_ImgList = NULL;
}

CMyListBox::~CMyListBox()
{
	//内存的销毁不能放在析构函数中,因为此时ListBox对象已经销毁
	//在ReleaseMemory()中调用GetCount()函数等已经没有意义,会报错:

	/*ASSERT(::IsWindow(m_hWnd));*/

	//ReleaseMemory();
}


BEGIN_MESSAGE_MAP(CMyListBox, CListBox)
	ON_WM_DESTROY()
END_MESSAGE_MAP()



// CMyListBox 消息处理程序

void CMyListBox::DrawItem(LPDRAWITEMSTRUCT lpDIS)
{
	CDC dc;
	dc.Attach(lpDIS->hDC);

	CRect ListBRect = lpDIS->rcItem;

	int nCurItemIndex = lpDIS->itemID;

	if(nCurItemIndex == -1) return;  

	dc.SetBkMode(TRANSPARENT);  

	if (lpDIS->itemState & ODS_SELECTED)//选中项设置  
	{  
		dc.SetTextColor(GetSysColor(COLOR_HIGHLIGHTTEXT));  
		dc.FillSolidRect(&ListBRect,GetSysColor(COLOR_HIGHLIGHT));  

		if(lpDIS->itemAction & ODA_FOCUS) dc.DrawFocusRect(&ListBRect);  
	}   
	else//非选中项设置  
	{  
		dc.SetTextColor(GetSysColor(COLOR_WINDOWTEXT));

		if(nCurItemIndex % 2) dc.FillSolidRect(&ListBRect,RGB(0,192,192));  

		else dc.FillSolidRect(&ListBRect,RGB(192,192,0));
		
	}  

	//画文字  
	CRect TextRect = ListBRect;  

	CString strText;  

	GetText(nCurItemIndex,strText);//获取正在自绘项的文字  

	//TRACE("nItem = %d\r\n",nCurItemIndex);  

	CSize TempSize;

	ImageList_GetIconSize(m_ImgList->m_hImageList, (int*)&TempSize.cx, (int*)&TempSize.cy);

	TextRect.left = TextRect.left + TempSize.cx + 4;  

	dc.DrawText(strText,&TextRect,DT_LEFT|DT_VCENTER|DT_SINGLELINE);  

	//画图标  
	CRect IconRect = ListBRect;  

	int nImageIndex;  

	GetImage(nCurItemIndex,nImageIndex);   

	m_ImgList->Draw(&dc,nImageIndex,IconRect.TopLeft(),ILD_NORMAL); 

	dc.Detach();
}

CImageList* CMyListBox::SetImageList(CImageList* pImgList)
{
	CImageList* pOldImgList = m_ImgList;

	m_ImgList = pImgList;

	return pOldImgList;
}

int CMyListBox::AddString(CString strText,int nImgIndex)
{
	int nIndex = CListBox::AddString(strText);

	SLBData* pLBData = new SLBData;

	if(pLBData == NULL) return -1;

	pLBData->strText = strText;

	pLBData->nImgIndex = nImgIndex;

	CListBox::SetItemData(nIndex,(DWORD_PTR)pLBData);

	return nIndex;
}

int CMyListBox::GetText(int nItemIndex,CString& strText)
{
	SLBData* pData = (SLBData*)CListBox::GetItemData(nItemIndex);

	if(pData == NULL) return 0;

	strText = pData->strText;

	return 1;
}

int CMyListBox::GetImage(int nItemIndex,int& nImageIndex)
{
	SLBData* pData = (SLBData*)CListBox::GetItemData(nItemIndex);

    if(pData == NULL) return 0;

	nImageIndex = pData->nImgIndex;

	return 1;
}

void CMyListBox::ReleaseMemory()
{
	int nItemCount = CListBox::GetCount();

	for (int i = 0;i < nItemCount;i++)
	{
		SLBData* pData = (SLBData*)CListBox::GetItemData(i);

		if (pData)
		{
			delete pData;

			pData = NULL;
		}
	}

	CListBox::ResetContent();
}

void CMyListBox::MeasureItem(LPMEASUREITEMSTRUCT lpMIS)
{
	CSize TempSize;

	ImageList_GetIconSize(m_ImgList->m_hImageList, (int*)&TempSize.cx, (int*)&TempSize.cy);

	lpMIS->itemHeight = TempSize.cy;

	/*int nItem = lpMIS->itemID;

	if(nItem % 2) lpMIS->itemHeight = 100;*/

	//lpMIS->itemHeight = 20;
}


void CMyListBox::OnDestroy()
{
	CListBox::OnDestroy();

	ReleaseMemory();
}

ListBox控件自绘

相关标签: ListBox自绘