MFC 半透明按钮

版权声明:未经同意,不能用于商业用途,版权归本博主所有 https://blog.csdn.net/qq_16123279/article/details/82858238

效果展示
在这里插入图片描述
实现方法

  1. 给按钮加上BS_OWNERDRAW样式
  2. 重载DrawItem函数,在这里绘制按钮
  3. 关键之处就是把父窗口的背景复制到按钮上,实现视觉上的透明
  4. 最后通过AlphaBlend实现半透明.

源码下载:
http://blog.csdn.net/cometnet/article/details/8464693

实现源码

// MyButton.h 

#pragma once 

  
  
// CMyButton 

  
class CMyButton : public CButton

{ 
    DECLARE_DYNAMIC(CMyButton)

  
public:

    CMyButton();

    virtual ~CMyButton();

public:

    void SetBkColor(COLORREF color);

    void SetTextColor(COLORREF color);

private:

    bool m_bOver;

    bool m_bDown;

    bool m_bDisable;

    bool m_bTracking;

    COLORREF m_bkColor;

    COLORREF m_textColor;

protected:

    DECLARE_MESSAGE_MAP()

    virtual BOOL PreCreateWindow(CREATESTRUCT& cs);

    virtual void PreSubclassWindow();

public:

    virtual void DrawItem(LPDRAWITEMSTRUCT /*lpDrawItemStruct*/);

    afx_msg void OnMouseMove(UINT nFlags, CPoint point);

    afx_msg void OnLButtonDown(UINT nFlags, CPoint point);

    afx_msg void OnLButtonUp(UINT nFlags, CPoint point);

    afx_msg LRESULT OnMouseLeave(WPARAM wParam, LPARAM lParam);

    afx_msg LRESULT OnMouseHover(WPARAM wParam, LPARAM lParam);

    afx_msg void OnEnable(BOOL bEnable);

private:

    void ButtonInit();

    void DrawButton();

    void DrawButton(HDC hDestDC);

};
// MyButton.cpp : 实现文件

// 
  
#include "stdafx.h"

#include "AlphaButton.h"

#include "MyButton.h"

#include "MainDlg.h"

  
// CMyButton 

  
IMPLEMENT_DYNAMIC(CMyButton, CButton)

  
CMyButton::CMyButton()

{ 
    m_bkColor=0xFFFFFF;

    m_textColor=0x000000;

} 
  
CMyButton::~CMyButton()

{ 
} 
  
  
BEGIN_MESSAGE_MAP(CMyButton, CButton)

    ON_WM_MOUSEMOVE()

    ON_WM_LBUTTONDOWN()

    ON_WM_LBUTTONUP()

    ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)

    ON_MESSAGE(WM_MOUSEHOVER, OnMouseHover)

    ON_WM_ENABLE()

END_MESSAGE_MAP() 

  
  
  
// CMyButton 消息处理程序

  
void CMyButton::SetBkColor(COLORREF color)

{ 
    m_bkColor=color;

} 
void CMyButton::SetTextColor(COLORREF color)

{ 
    m_textColor=color;

} 
  
BOOL CMyButton::PreCreateWindow(CREATESTRUCT& cs)

{ 
    BOOL bRet=CButton::PreCreateWindow(cs);

    ButtonInit();

    return bRet;

} 
  
void CMyButton::PreSubclassWindow()

{ 
    CButton::PreSubclassWindow();

    ButtonInit();

} 
void CMyButton::ButtonInit()

{ 
    m_bTracking=false;

    m_bOver=m_bDown=m_bDisable=false;

    m_bDisable=IsWindowEnabled()?FALSE:TRUE;

    ModifyStyle(NULL,BS_OWNERDRAW);

} 
  
void CMyButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)

{ 
  
    DrawButton(lpDrawItemStruct->hDC);

} 
  
void CMyButton::OnMouseMove(UINT nFlags, CPoint point)

{ 
    if (!m_bTracking)

    {

        m_bOver = TRUE;

        TRACKMOUSEEVENT tme;

        tme.cbSize = sizeof(tme);

        tme.hwndTrack = m_hWnd;

        tme.dwFlags = TME_LEAVE | TME_HOVER;

        tme.dwHoverTime = 50;

        m_bTracking = (bool)_TrackMouseEvent(&tme);

    }

  
    CButton::OnMouseMove(nFlags, point);

} 
  
void CMyButton::OnLButtonDown(UINT nFlags, CPoint point)

{ 
    m_bDown=TRUE;

  
    CButton::OnLButtonDown(nFlags, point);

} 
  
void CMyButton::OnLButtonUp(UINT nFlags, CPoint point)

{ 
    m_bDown=FALSE;

    CButton::OnLButtonUp(nFlags, point);

} 
LRESULT CMyButton::OnMouseLeave(WPARAM wParam, LPARAM lParam)

{ 
    m_bOver = FALSE;

    m_bTracking = FALSE;

    m_bDown=FALSE;

    InvalidateRect(NULL, FALSE);

    return 0;

} 
  
LRESULT CMyButton::OnMouseHover(WPARAM wParam, LPARAM lParam)

{ 
    m_bOver = TRUE;

    InvalidateRect(NULL);

    return 0;

} 
void CMyButton::DrawButton()

{ 
    HDC hDC=::GetDC(m_hWnd);

    DrawButton(hDC);

    ::ReleaseDC(m_hWnd,hDC);

} 
void CMyButton::DrawButton(HDC hDestDC)

{ 
    CRect rc;

    GetClientRect(rc);

    int nWindth=rc.Width();

    int nHeight=rc.Height();

    HDC hDC=CreateCompatibleDC(hDestDC);//创建兼容DC,采用双缓冲画出

    HDC hMaskDC=CreateCompatibleDC(hDestDC);

    HBITMAP hBitmap=CreateCompatibleBitmap(hDestDC,nWindth,nHeight);

    HBITMAP hMaskBitmap=CreateCompatibleBitmap(hDestDC,nWindth,nHeight);

    HBITMAP hOldBitmap=(HBITMAP)SelectObject(hDC,hBitmap);

    HBITMAP hOldMaskBitmap=(HBITMAP)SelectObject(hMaskDC,hMaskBitmap);

    SetBkMode(hDC,TRANSPARENT);

  
    //把父窗口的背景图复制到按钮的DC上,实现视觉透明----------------

    CMainDlg* pParent=(CMainDlg*)GetParent();

    CPoint pt(0,0);

    MapWindowPoints(pParent,&pt,1);

    pParent->m_bkImage.BitBlt(hDC,rc,pt,SRCCOPY);

  
  
    //-------------------------------------------------------------

    int nAlpha=100;//0--255

    int nOffset=0;

  
    HBRUSH hbr=CreateSolidBrush(m_bkColor);

    FillRect(hMaskDC,&rc,hbr);

    DeleteObject(hbr);

  
    if(m_bDisable){

        nAlpha=100;

    }else if(m_bDown){

        nAlpha=180;

        nOffset=1;

    }else if(m_bOver){

        nAlpha=150;

    }else{

        nAlpha=100;

    }

    BLENDFUNCTION blend;

    memset( &blend, 0, sizeof( blend) );

    blend.BlendOp= AC_SRC_OVER;

    blend.SourceConstantAlpha= nAlpha; // 透明度 最大255

  
    HRGN hRgn=CreateRoundRectRgn(0,0,nWindth,nHeight,3,3);

    SelectClipRgn (hDC,hRgn);

    AlphaBlend (hDC,0,0,nWindth,nHeight,hMaskDC, 0,0,nWindth,nHeight,blend);

  
    CString strText;

    GetWindowText(strText);

    if(strText!=_T("")){

        rc.InflateRect(-2,-2);

        rc.OffsetRect(nOffset,nOffset);

        HFONT hFont=(HFONT)SendMessage(WM_GETFONT);

        if(!hFont)hFont=(HFONT)GetStockObject(DEFAULT_GUI_FONT);

        HFONT hOldFont=(HFONT)SelectObject(hDC,hFont);

        ::SetTextColor(hDC,m_textColor);

        ::DrawText(hDC,strText,-1,&rc,DT_SINGLELINE|DT_CENTER|DT_VCENTER|DT_WORD_ELLIPSIS);

        ::SelectObject(hDC,hOldFont);

    }

    SelectClipRgn (hDC,NULL);

    DeleteObject(hRgn);

    //复制到控件的DC上------------------------

    BitBlt(hDestDC,0,0,nWindth,nHeight,hDC,0,0,SRCCOPY);

    //删除资源,释放内存-----------------------

    SelectObject(hDC,hOldBitmap);

    DeleteObject(hBitmap);

    DeleteDC(hDC);

    SelectObject(hMaskDC,hOldMaskBitmap);

    DeleteObject(hMaskBitmap);

    DeleteDC(hMaskDC);

  
} 
void CMyButton::OnEnable(BOOL bEnable)

{ 
    CButton::OnEnable(bEnable);

    m_bDisable=IsWindowEnabled()?FALSE:TRUE;

    DrawButton();

}

猜你喜欢

转载自blog.csdn.net/qq_16123279/article/details/82858238