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