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


     

     
     
    使用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图片
    复制代码
    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 ");
    复制代码

    附:PNGButton类代码下载

  • 相关阅读:
    《快速开发》通过Maven创建WebService项目Hello World!
    《常见问题集》Eclipse
    《常见问题集》Maven
    Eclipse + Jersey 发布RESTful WebService(一)了解Maven和Jersey,创建一个WS项目(成功!)
    Java2WSDL 和 WSDL2Java(Axis)
    Eclipse + Apache Axis2 发布RESTful WebService(一)基础知识
    Eclipse + Apache Axis2 发布SOAP WebService(三)第一个程序Hello Axis2 SOAP!
    Eclipse + Apache Axis2 发布RESTful WebService(三)第一个程序Hello Axis2 !(未成功)
    Eclipse + Apache Axis2 发布RESTful WebService(二)配置开发环境
    学习 JSP:第三步 JSP基础(未完)
  • 原文地址:https://www.cnblogs.com/liangxiaofeng/p/7069176.html
Copyright © 2020-2023  润新知