使用MFC实现上面的按钮半透明效果能看到父窗口中的内容,上面是效果图(一个是带背景图片的、另一个是不带的)。
控件继承自CWnd类(彩色的部分是窗口的背景图片、按钮是PNG图片,第二个图标是鼠标指向时的效果)。
图标的绘制使用GDI+绘制PNG图片,在此不多说了(处理WM_PAINT消息):
1
void
PNGButton::OnPaint()
2
{
3
CPaintDC dc(
this
);
4
Graphics g(dc.m_hDC);
5
if
(DrawBorder){
6
g.DrawImage(hoverBg,
0
,
0
);
//
画鼠标指向时的亮色背景
7
}
8
g.DrawImage(
this
->
bg,
0
,
0
);
//
画按钮图标
9
g.ReleaseHDC(dc.m_hDC);
10
}
透明的关键:注意后面调用此方法的代码
关键在于
InvalidateRect函数:通知父窗口重新绘制特定区域,执行此函数后按钮所在区域就被父窗口绘制的内容覆盖.在父窗口绘制完成后,
按钮也会收到WM_PAINT消息,执行上面的一段OnPaint代码.
按钮也会收到WM_PAINT消息,执行上面的一段OnPaint代码.
1
void
PNGButton::PaintParent()
2
{
3
CRect rect;
4
GetWindowRect(
&
rect);
5
GetParent()
->
ScreenToClient(
&
rect);
6
GetParent()
->
InvalidateRect(
&
rect);
7
}
捕获鼠标指向或移出事件(处理WM_MOUSEMOVE,WM_MOUSEOVER,WM_MOUSELEAVE消息):
1
void
PNGButton::OnMouseHover(UINT nFlags, CPoint point)
2
{
3
DrawBorder
=
true
;
4
PaintParent();//通知父窗口重绘特定区域,会引发控件自身的重绘
5
}
6
7
8
void
PNGButton::OnMouseLeave()
9
{
10
m_is_mouse_over
=
false
;
11
m_is_tracked
=
false
;
12
DrawBorder
=
false
;
13
PaintParent(); //通知父窗口重绘特定区域,会引发控件自身的重绘
14
CWnd::OnMouseLeave();
15
}
16
17
18
void
PNGButton::OnMouseMove(UINT nFlags, CPoint point)
19
{
20
m_is_mouse_over
=
true
;
21
if
(
!
m_is_tracked)
22
{
23
TRACKMOUSEEVENT tme;
24
tme.cbSize
=
sizeof
(TRACKMOUSEEVENT);
25
tme.dwFlags
=
TME_LEAVE
|
TME_HOVER;
26
tme.hwndTrack
=
GetSafeHwnd();
27
tme.dwHoverTime
=
80
;
28
_TrackMouseEvent(
&
tme);
29
m_is_tracked
=
true
;
30
}
31
CWnd::OnMouseMove(nFlags, point);
32
}
附:
从资源加载PNG图片
View Code
1
#pragma
once
2
#include
"
stdafx.h
"
3
using
namespace
Gdiplus;
4
5
static
bool
ImageFromIDResource(UINT nID, LPCTSTR sTR,Image
*
&
pImg)
6
{
7
HINSTANCE hInst
=
AfxGetResourceHandle();
8
HRSRC hRsrc
=
::FindResource (hInst,MAKEINTRESOURCE(nID),sTR);
//
type
9
if
(
!
hRsrc)
10
return
FALSE;
11
//
load resource into memory
12
DWORD len
=
SizeofResource(hInst, hRsrc);
13
BYTE
*
lpRsrc
=
(BYTE
*
)LoadResource(hInst, hRsrc);
14
if
(
!
lpRsrc)
15
return
FALSE;
16
//
Allocate global memory on which to create stream
17
HGLOBAL m_hMem
=
GlobalAlloc(GMEM_FIXED, len);
18
BYTE
*
pmem
=
(BYTE
*
)GlobalLock(m_hMem);
19
memcpy(pmem,lpRsrc,len);
20
IStream
*
pstm;
21
CreateStreamOnHGlobal(m_hMem,FALSE,
&
pstm);
22
//
load from stream
23
pImg
=
Gdiplus::Image::FromStream(pstm);
24
//
free/release stuff
25
GlobalUnlock(m_hMem);
26
pstm
->
Release();
27
FreeResource(lpRsrc);
28
return
TRUE;
29
}
平铺图片的代码
1
CPaintDC dc(
this
);
2
CRect rect;
3
GetClientRect(rect);
4
CBrush bs(RGB(
240
,
240
,
240
));
//
窗口背景色
5
dc.FillRect(
&
rect,
&
bs);
//
窗口着色
6
//
填充背景图片:平铺
7
Graphics g(dc.m_hDC);
8
if
(has_bg) g.DrawImage(
this
->
bg,
0
,
0
);
9
Gdiplus::TextureBrush bbs(
this
->
img);
10
g.FillRectangle(
&
bbs,
0
,
0
,rect.Width(),
this
->
img
->
GetHeight());
11
g.ReleaseHDC(dc.m_hDC);
12
//
TRACE(L"CMainFrame::OnPaint\r\n");
转http://www.cnblogs.com/Lexy/archive/2011/04/09/2010418.html
本文介绍如何使用MFC实现带有半透明效果的按钮,并能显示父窗口背景内容。通过继承CWnd类并利用GDI+绘制PNG图片,结合WM_PAINT消息处理,实现了按钮在鼠标悬停状态下的视觉变化。
777

被折叠的 条评论
为什么被折叠?



