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

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

2011-11-02 20:58 295 查看




使用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代码.

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


附:PNGButton类代码下载
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: