MFC的PNG图片按钮

pngbutton.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#pragma once
#include "afxwin.h"

/
// 工程: YF_GCM -> ButtonDemo
// 作者: **
// 描述: 自绘制位图按钮
// 主要函数:
// SetButtonUpBitmapEx()设置鼠标放置在按钮上的图片
// SetButtonDownBitmapEx()设置按钮按下的图片
// SetButtonNormalBitmapEx()设置鼠标不在按钮是的图片
// 日期: 2013.12.16
// 版本: 1.0
// 修改:
/
// CBitmapButtonEx

class CPngButton : public CBitmapButton
{
DECLARE_DYNAMIC(CPngButton)

public:
CPngButton();
virtual ~CPngButton();

protected:
DECLARE_MESSAGE_MAP()

protected:

virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);

public:
// 设置按钮抬起图片
BOOL SetButtonUpBitmapEx(const CString& szFilePath);
// 设置按钮按下图片
BOOL SetButtonDownBitmapEx(const CString& szFilePath);
// 普通按钮图片
BOOL SetButtonNormalBitmapEx(const CString& szFilePath);
protected:
virtual void PreSubclassWindow();
public:
virtual BOOL PreTranslateMessage(MSG* pMsg);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
protected:
BOOL m_lButtonDown;
// 按钮有效区域
// CRgn m_btRgn;
// 绘制按钮图片区域
// CRect m_rectDrawButton;
private:
// 图片
CImage m_imageButtonUp;
CImage m_imageButtonDown;
CImage m_imageBitmapNormal;
CDC m_bkDc; // 记录背景
bool m_first;
public:

protected:
BOOL m_bMouseOver;
BOOL m_bTrack;
public:
};

pngbutton.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
/ 
// 工程: YF_GCM -> ButtonDemo
// 作者: **
// 描述: 自绘制位图按钮
// 主要函数:
// SetButtonUpBitmapEx()设置鼠标放置在按钮上的图片
// SetButtonDownBitmapEx()设置按钮按下的图片
// SetButtonNormalBitmapEx()设置鼠标不在按钮是的图片
// 日期: 2013.12.16
// 版本: 1.0
// 修改:
/

#include "stdafx.h"
#include "pngbutton.h"
#include "TransparentPNG.h"
// #include "LogToFile.h"

// CBitmapButtonEx

IMPLEMENT_DYNAMIC(CPngButton, CBitmapButton)

CPngButton::CPngButton()
: CBitmapButton()
, m_lButtonDown(FALSE)
, m_bMouseOver(FALSE)
, m_bTrack(FALSE)
, m_first(true)
{
}

CPngButton::~CPngButton()
{
if (NULL != m_imageButtonUp)
{
::DeleteObject(m_imageButtonUp);
}
if (NULL != m_imageButtonDown)
{
::DeleteObject(m_imageButtonDown);
}
if (NULL != m_imageBitmapNormal)
{
::DeleteObject(m_imageButtonDown);
}
}


BEGIN_MESSAGE_MAP(CPngButton, CBitmapButton)
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
END_MESSAGE_MAP()



// CBitmapButtonEx 消息处理程序

BOOL CPngButton::SetButtonUpBitmapEx(const CString& szFilePath)
{
if (!m_imageButtonUp.IsNull())
{
m_imageButtonUp.Destroy();
}
m_imageButtonUp.Load(szFilePath);
if (!m_imageButtonUp.IsNull())
{
CTransparentPNG tran;
tran(&m_imageButtonUp);
}
return !m_imageButtonUp.IsNull();
}


BOOL CPngButton::SetButtonNormalBitmapEx(const CString& szFilePath)
{
if (!m_imageBitmapNormal.IsNull())
{
m_imageBitmapNormal.Destroy();
}
m_imageBitmapNormal.Load(szFilePath);
if (!m_imageBitmapNormal.IsNull())
{
CTransparentPNG tran;
tran(&m_imageBitmapNormal);
}
return !m_imageBitmapNormal.IsNull();
}

// BOOL CPngButton::SetRedPointImage(const CString& szFilePath)
// {
// if (!m_imageRedPoint.IsNull())
// {
// m_imageRedPoint.Destroy();
// }
// m_imageRedPoint.Load(szFilePath);
// if (!m_imageRedPoint.IsNull())
// {
// CTransparentPNG tran;
// tran(&m_imageRedPoint);
// }
// return !m_imageRedPoint.IsNull();
// }
BOOL CPngButton::SetButtonDownBitmapEx(const CString& szFilePath)
{
if (!m_imageButtonDown.IsNull())
{
m_imageButtonDown.Destroy();
}
m_imageButtonDown.Load(szFilePath);
if (!m_imageButtonDown.IsNull())
{
CTransparentPNG tran;
tran(&m_imageButtonDown);
}
return !m_imageButtonDown.IsNull();
}

void CPngButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
// TODO: 添加您的代码以绘制指定项
CRect rect = lpDrawItemStruct->rcItem;

if (m_first)
{// 复制背景
CDialog* pParent=(CDialog*)GetParent();
CPoint pt(0,0);
MapWindowPoints(pParent,&pt,1);
CDC * pdc = GetParent ()->GetDC ();
m_bkDc.CreateCompatibleDC (pdc);
CBitmap memBmp;
memBmp.CreateCompatibleBitmap(pdc, rect.right, rect.bottom);
m_bkDc.SelectObject(&memBmp);
m_bkDc.BitBlt (0, 0, rect.right, rect.bottom, pdc, pt.x, pt.y, SRCCOPY);
ReleaseDC (pdc);
m_first = false;
}
// CClientDC dc(this);
// dc.Rectangle (rect);
// 背景
CDC* thisdc = NULL;
thisdc = GetDC();
thisdc->BitBlt (0, 0, rect.right, rect.bottom, &m_bkDc, 0/*rect.right*/, 0/*rect.bottom*/, SRCCOPY);

if (m_lButtonDown)
{
if (m_imageButtonDown.IsNull())
{
// CString szLog;
// szLog.Format(_T("m_imageButtonDown 未加载背景图片!"));
// AppLog(szLog);
}
else
{
m_imageButtonDown.Draw(thisdc->m_hDC, rect/*m_rectDrawButton*/);
}
}
else
{
if (m_bMouseOver)
{
if (m_imageButtonUp.IsNull())
{
// CString szLog;
// szLog.Format(_T("m_imageButtonUp 未加载背景图片!"));
// AppLog(szLog);
}
else
{
m_imageButtonUp.Draw(thisdc->m_hDC, rect/*m_rectDrawButton*/);
}
}
else
{
if (m_imageBitmapNormal.IsNull())
{
// CString szLog;
// szLog.Format(_T("m_imageBitmapNormal 未加载背景图片!"));
// AppLog(szLog);
}
else
{
m_imageBitmapNormal.Draw(thisdc->m_hDC, rect/*m_rectDrawButton*/);
}
}
}
if (0 == this->ReleaseDC(thisdc))
{
// CString szLog;
// szLog.Format(_T("ReleaseDC error!"));
// AppLog(szLog);
}
}

void CPngButton::PreSubclassWindow()
{
// TODO: 在此添加专用代码和/或调用基类

ModifyStyle(0, WS_CLIPCHILDREN | BS_OWNERDRAW ); //设置按钮的有效区域

// CRect rect;
// GetClientRect(&rect);
// CDialog* pParent=(CDialog*)GetParent();
// CPoint pt(rect.left, rect.top);
// MapWindowPoints(pParent, &pt, 1);
// CDC * pdc = GetParent ()->GetDC ();
// // 复制背景
// m_bkDc.CreateCompatibleDC (pdc);
// CBitmap memBmp;
// memBmp.CreateCompatibleBitmap(pdc, rect.right, rect.bottom);
// m_bkDc.SelectObject(&memBmp);
// m_bkDc.BitBlt (0, 0, rect.right, rect.bottom, pdc, 0, 0, SRCCOPY);
// ReleaseDC (pdc);

// m_btRgn.CreateRectRgnIndirect (rc);
// SetWindowRgn(m_btRgn, TRUE);

CBitmapButton::PreSubclassWindow();
}

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

m_lButtonDown = TRUE;
CBitmapButton::OnLButtonDown(nFlags, point);
}

void CPngButton::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
m_lButtonDown = FALSE;
CBitmapButton::OnLButtonUp(nFlags, point);
}

BOOL CPngButton::PreTranslateMessage(MSG* pMsg)
{
// TODO: 在此添加专用代码和/或调用基类

if(pMsg->message==WM_MOUSELEAVE)
{
m_bTrack=FALSE;
m_bMouseOver = FALSE;
InvalidateRect(NULL);
}
else if (pMsg->message==WM_MOUSEHOVER)
{
m_bMouseOver = TRUE;
InvalidateRect(NULL);
}

return CBitmapButton::PreTranslateMessage(pMsg);
}

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

if(!m_bTrack)
{
TRACKMOUSEEVENT tme;
tme.cbSize=sizeof(TRACKMOUSEEVENT);
tme.dwFlags=TME_HOVER | TME_LEAVE;
tme.dwHoverTime=HOVER_DEFAULT;
tme.hwndTrack=m_hWnd;

m_bTrack=_TrackMouseEvent(&tme);
}

CBitmapButton::OnMouseMove(nFlags, point);
}

CTransparentPNG 地址
点击打开链接https://gitee.com/user.zt/codes/rni2jtabfxcykzu7lvo3067

因gitee.com代码段公共访问功能关闭导致上述链接失效,现将代码贴出。

CTransparentPNG

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
/
// 工程:
// 作者:
// 描述: 处理png图片,使背景变白
// 主要函数:
// 日期: 2014.11.28
// 版本: 1.0
// 修改:
/
#pragma once
class CTransparentPNG
{

public:
CTransparentPNG() {}
~CTransparentPNG() {}


bool operator()(CImage* image) {
if (!image)
return false;
if (image->GetBPP() != 32)
return false;
for (int i = 0; i < image->GetWidth(); ++i)
{
for (int j = 0; j < image->GetHeight(); ++j)
{
unsigned char* pucColor = reinterpret_cast<unsigned char*>(image->GetPixelAddress(i, j));
pucColor[0] = pucColor[0] * pucColor[3] / 255;
pucColor[1] = pucColor[1] * pucColor[3] / 255;
pucColor[2] = pucColor[2] * pucColor[3] / 255;
}
}

return true;
}

static bool TransPng(CImage* image)
{
if (!image)
return false;
if (image->GetBPP() != 32)
return false;
for (int i = 0; i < image->GetWidth(); ++i)
{
for (int j = 0; j < image->GetHeight(); ++j)
{
unsigned char* pucColor = reinterpret_cast<unsigned char*>(image->GetPixelAddress(i, j));
pucColor[0] = pucColor[0] * pucColor[3] / 255;
pucColor[1] = pucColor[1] * pucColor[3] / 255;
pucColor[2] = pucColor[2] * pucColor[3] / 255;
}
}
return true;
}

};