当前位置:编程学习 > C/C++ >>

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



使用MFC实现上面的按钮半透明效果能看到父窗口中的内容,上面是效果图(一个是带背景图片的、另一个是不带的)。
控件继承自CWnd类(彩色的部分是窗口的背景图片、按钮是PNG图片,第二个图标是鼠标指向时的效果)。
图标的绘制使用GDI+绘制PNG图片,在此不多说了(处理WM_PAINT消息):
[cpp]
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代码.
[cpp] 
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消息):
[cpp]
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图片
附:
从资源加载PNG图片
 
[cpp] 
1. View Code  
2.  #pragma once 
3.  #include "stdafx.h" 
4.   using namespace Gdiplus;  
5.   
6.   static bool ImageFromIDResource(UINT nID, LPCTSTR sTR,Image * &pImg) 
7.  { 
8.       HINSTANCE hInst = AfxGetResourceHandle(); 
9.       HRSRC hRsrc = ::FindResource (hInst,MAKEINTRESOURCE(nID),sTR); // type 
10.        if (!hRsrc) 
11.        return FALSE; 
12.       // load resource into memory 
13.        DWORD len = SizeofResource(hInst, hRsrc); 
14.       BYTE* lpRsrc = (BYTE*)LoadResource(hInst, hRsrc); 
15.       if (!lpRsrc) 
16.        return FALSE; 
17.       // Allocate global memory on which to create stream 
18.        HGLOBAL m_hMem = GlobalAlloc(GMEM_FIXED, len); 
19.       BYTE* pmem = (BYTE*)GlobalLock(m_hMem); 
20.       memcpy(pmem,lpRsrc,len); 
21.       IStream* pstm; 
22.       CreateStreamOnHGlobal(m_hMem,FALSE,&pstm); 
23.       // load from stream 
24.        pImg=Gdiplus::Image::FromStream(pstm); 
25.       // free/release stuff 
26.        GlobalUnlock(m_hMem); 
27.       pstm->Release(); 
28.       FreeResource(lpRsrc); 
29.       return TRUE; 
30.  } 
平铺图片的代码
[cpp] 
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"); 

 

作者:eit520
补充:软件开发 , C++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,