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);
}