zoukankan      html  css  js  c++  java
  • 用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图片
    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类代码下载

  • 相关阅读:
    POJ1201 Intervals
    POJ3169 Layout
    POJ1692 Crossed Matchings
    POJ1671 Rhyme Schemes
    POJ1742 Coins
    BZOJ2662: [BeiJing wc2012]冻结
    BZOJ 2330: [SCOI2011]糖果
    NOIP2015提高组T2 洛谷P2661 信息传递
    洛谷P1197 [JSOI2008]星球大战
    HDU3538 A sample Hamilton path
  • 原文地址:https://www.cnblogs.com/Lexy/p/2010418.html
Copyright © 2011-2022 走看看