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

来源:互联网 发布:深圳软件开发年龄 编辑:程序博客网 时间:2024/05/21 10:01


使用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");


 


 

原创粉丝点击