您的位置:首页 > 编程语言 > C语言/C++

用C++实现半透明按钮控件(PNG,GDI+)

2012-06-28 09:45 405 查看




使用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代码.
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");
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: