VC++ 图标集显示控件

1、效果图:

2、素材准备:

3、头文件声明:

#pragma once
#include <afxwin.h>

class TIconCtrl :
    public CWnd
{
public:
	CSize m_szIcon;	// 图标大小
	int m_nMargin;	// 图标在显示框中内测边距
	int m_nColumn;	// 每列显示图标个数
	int m_nSelIndex; // 所选择的图标序号

private:
	CToolTipCtrl m_tooltip; // 图标提示
    CImageList m_imgList;   // 图标列表集
	int m_nStayIndex;		// 鼠标停留时的图标序号
	
	void DrawGrid(CDC* pDC);// 绘制图标显示格
	void DrawIcons(CDC* pDC);// 绘制图标

public:
    virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
	afx_msg void OnDestroy();
	afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
	afx_msg void OnMouseMove(UINT nFlags, CPoint point);
	afx_msg void OnPaint();
	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
	virtual BOOL PreTranslateMessage(MSG* pMsg);
    DECLARE_MESSAGE_MAP()
};

4、源代码定义:

#include "stdafx.h"
#include "TIconCtrl.h"


BOOL TIconCtrl::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: 在此添加专用代码和/或调用基类
	WNDCLASS wndcls;
	if (!::GetClassInfo(AfxGetInstanceHandle(), _T("TIconCtrl"), &wndcls))
	{
		memset(&wndcls, 0, sizeof(WNDCLASS));
		wndcls.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
		wndcls.lpfnWndProc = ::DefWindowProc;
		wndcls.hInstance = AfxGetInstanceHandle();
		wndcls.hIcon = NULL;
		wndcls.hCursor = NULL;
		wndcls.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
		wndcls.lpszMenuName = NULL;
		::GetClassInfo(AfxGetInstanceHandle(), cs.lpszClass, &wndcls);
		wndcls.lpszClassName = _T("TIconCtrl");
		if (::RegisterClass(&wndcls))
			cs.lpszClass = wndcls.lpszClassName;
	}

	return CWnd::PreCreateWindow(cs);
}
BEGIN_MESSAGE_MAP(TCalcIconCtrl, CWnd)
	ON_WM_CREATE()
	ON_WM_DESTROY()
	ON_WM_LBUTTONDBLCLK()
	ON_WM_MOUSEMOVE()
	ON_WM_PAINT()
	ON_WM_LBUTTONDOWN()
END_MESSAGE_MAP()


int TIconCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CWnd::OnCreate(lpCreateStruct) == -1)
		return -1;

	// TODO:  在此添加您专用的创建代码
	// 图标宽度
    m_szIcon.cx = 18;
	// 图标高度
	m_szIcon.cy = 18;
	CBitmap bmp;
	bmp.LoadBitmap(IDB_BITMAP_XXX);// IDB_BITMAP_XXX 图像资源ID
	m_imgList.Create(m_szIcon.cx, m_szIcon.cy, ILC_COLOR32 | ILC_MASK, 0, 4);
	m_imgList.SetBkColor(CLR_NONE);
	m_imgList.Add(&bmp, 0xFFFFFF);
	bmp.DeleteObject();

	m_tooltip.Create(this);
	m_tooltip.Activate(TRUE);// TTM_ACTIVATE
	m_tooltip.AddTool(this, _T(""), NULL, NULL);	
	m_tooltip.SetMargin(CRect(5, 5, 2, 2));
	m_tooltip.SetTipBkColor(0xE1FFFFu);
	m_tooltip.SetTipTextColor(0x000000u);
	m_tooltip.SetMaxTipWidth(200);
	m_tooltip.SetDelayTime(500);

	// 图标内部4周间距
	m_nMargin = 4;
	// 1列数据显示的图标数
	m_nColumn = 9;
	m_nSelIndex = -1;
	m_nStayIndex = -1;

	return 0;
}


void TIconCtrl::OnDestroy()
{
	CWnd::OnDestroy();

	// TODO: 在此处添加消息处理程序代码
}


void TIconCtrl::OnLButtonDblClk(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值

	CWnd::OnLButtonDblClk(nFlags, point);

	CSize sz = m_szIcon;
	sz.cx += m_nMargin * 2;
	sz.cy += m_nMargin * 2;
	int nIndex = 0;
	while (1)
	{
		int nLeft = sz.cx * (nIndex % m_nColumn);
		int nTop = sz.cy * (nIndex / m_nColumn);
		if (point.x > nLeft && point.x < nLeft + sz.cx && point.y > nTop && point.y < nTop + sz.cy)
			break;

		++nIndex;
		if (nIndex >= m_imgList.GetImageCount())
			return ;
	}

	m_nSelIndex = nIndex;
}


void TIconCtrl::OnMouseMove(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值

	CWnd::OnMouseMove(nFlags, point);

	CSize sz = m_szIcon;
	sz.cx += m_nMargin * 2;
	sz.cy += m_nMargin * 2;
	int nIndex = 0;
	while (1)
	{
		int nLeft = sz.cx * (nIndex % m_nColumn);
		int nTop = sz.cy * (nIndex / m_nColumn);
		if (point.x > nLeft && point.x < nLeft + sz.cx && point.y > nTop && point.y < nTop + sz.cy)
			break;

		++nIndex;
		if (nIndex >= m_imgList.GetImageCount())
		{
			m_nStayIndex = -1;
			return;
		}
	}

	char szInfo[20] = { 0 };
	sprintf_s(szInfo, _T("%d号图标"), nIndex + 1);
	m_tooltip.UpdateTipText(szInfo, this, NULL);
	m_nStayIndex = nIndex;
	InvalidateRect(NULL, FALSE);
}


void TIconCtrl::OnPaint()
{
	CPaintDC dc(this); // device context for painting
					   // TODO: 在此处添加消息处理程序代码
					   // 不为绘图消息调用 CWnd::OnPaint()

	CRect rcClient;
	GetClientRect(rcClient);

	CDC* pTempDC = new CDC;
	pTempDC->CreateCompatibleDC(&dc);
	
	CBitmap* m_pTempImage = new CBitmap;
	m_pTempImage->CreateCompatibleBitmap(&dc, rcClient.right - rcClient.left, rcClient.bottom - rcClient.top);
	CBitmap* m_pOldBitmap = pTempDC->SelectObject(m_pTempImage);

	pTempDC->FillSolidRect(&rcClient, GetSysColor(COLOR_3DFACE));
	DrawGrid(pTempDC);
	DrawIcons(pTempDC);

	dc.BitBlt(
		rcClient.left,
		rcClient.top,
		rcClient.right - rcClient.left,
		rcClient.bottom - rcClient.top,
		pTempDC,
		0,
		0,
		SRCCOPY);
	pTempDC->SelectObject(m_pOldBitmap);
	m_pTempImage->DeleteObject();

	if (m_pTempImage)
	{
		delete m_pTempImage;
		m_pTempImage = NULL;
	}
	pTempDC->DeleteDC();
	delete pTempDC;
	pTempDC = NULL;
}

void TIconCtrl::DrawGrid(CDC* pDC)
{
	CPen pen(PS_SOLID, 1, 0xAFB9BEu);
	CPen* pOldPen = pDC->SelectObject(&pen);

	CRect rcClient;
	GetClientRect(rcClient);
	CSize sz = m_szIcon;
	sz.cx += m_nMargin*2;
	sz.cy += m_nMargin*2;
	int nTop = 0;
	do
	{
		pDC->MoveTo(0, nTop);
		pDC->LineTo(rcClient.right, nTop);
		nTop += sz.cy;
	} while (nTop <= rcClient.bottom);

	int nLeft = 0;
	do
	{
		pDC->MoveTo(nLeft, 0);
		pDC->LineTo(nLeft, rcClient.bottom);
		nLeft += sz.cx;
	} while (nLeft <= rcClient.right);

	pDC->SelectObject(&pOldPen);
}

void TIconCtrl::DrawIcons(CDC* pDC)
{
	CPen pen(PS_SOLID, 1, 0xD9A04Cu);
	CPen* pOldPen = pDC->SelectObject(&pen);

	CSize sz = m_szIcon;
	sz.cx += m_nMargin * 2;
	sz.cy += m_nMargin * 2;
	int nIndex = 0;
	do
	{
		int nLeft = sz.cx * (nIndex % m_nColumn);
		int nTop = sz.cy * (nIndex / m_nColumn);
		int icon_x = nLeft + 5;
		int icon_y = nTop + 5;

		if (m_nSelIndex == nIndex)
		{
			pDC->MoveTo(nLeft, nTop);
			pDC->LineTo(nLeft, nTop + sz.cy);
			pDC->MoveTo(nLeft, nTop);
			pDC->LineTo(nLeft + sz.cx, nTop);
			pDC->MoveTo(nLeft + sz.cx, nTop);
			pDC->LineTo(nLeft + sz.cx, nTop + sz.cy);
			pDC->MoveTo(nLeft, nTop + sz.cy);
			pDC->LineTo(nLeft + sz.cx + 1, nTop + sz.cy);
			icon_x = nLeft + 5;
			icon_y = nTop + 5;
		}

		if (m_nStayIndex == nIndex)
		{
			icon_x = icon_x + 2;
			icon_y = icon_y - 2;
		}

		m_imgList.Draw(pDC, nIndex, CPoint(icon_x, icon_y), ILD_NORMAL | ILD_TRANSPARENT);
		++nIndex;
	} while (nIndex < m_imgList.GetImageCount());

	pDC->SelectObject(pOldPen);
}

void TIconCtrl::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值

	CWnd::OnLButtonDown(nFlags, point);

	CSize sz = m_szIcon;
	sz.cx += m_nMargin * 2;
	sz.cy += m_nMargin * 2;
	int nIndex = 0;
	while (1)
	{
		int nLeft = sz.cx * (nIndex % m_nColumn);
		int nTop = sz.cy * (nIndex / m_nColumn);

		if (point.x > nLeft && point.x < nLeft + sz.cx && point.y > nTop && point.y < nTop + sz.cy)
			break;

		++nIndex;
		if (nIndex >= m_imgList.GetImageCount())
		{
			m_nSelIndex = -1;
			InvalidateRect(NULL, FALSE);
			return;
		}
	}

	m_nSelIndex = nIndex;
	InvalidateRect(NULL, FALSE);
}


BOOL TIconCtrl::PreTranslateMessage(MSG* pMsg)
{
	// TODO: 在此添加专用代码和/或调用基类
	if (m_tooltip.GetSafeHwnd())
		m_tooltip.RelayEvent(pMsg);

	return CWnd::PreTranslateMessage(pMsg);
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值