MFC半透明按钮,修改

MFC半透明按钮,修改 | 火苗999℃的博客

直接将类加入项目工程,并在对话框类中增加

 

CImage m_bkImage;//背景图片

// 给按钮绑定控件变量,修改类型为CButtonTranslucent

CButtonTranslucent/*CButton*/ m_btTest3;

OnInitDialog()中设置图片:

m_bkImage.Load("bkBitmap.bmp"); // bkBitmap.bmp是背景图片

加载图片,或者使用    

m_bkImage.LoadFromResource(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDB_BITMAP_BK));

加载图片
m_btTest3.SetImage(m_bkImage);// 绑定图片 m_btTest3按钮绑定的控件变量

MFC半透明按钮类

#pragma once


// CButtonBmp

class CButtonTranslucent : public CButton
{
	DECLARE_DYNAMIC(CButtonTranslucent)

public:
	CButtonTranslucent();
	virtual ~CButtonTranslucent();

protected:
	DECLARE_MESSAGE_MAP()
    virtual void PreSubclassWindow();
public:
    void SetBkColor(COLORREF color);
    void SetTextColor(COLORREF color);
    // add byzt
    // 图片路径
    void SetImage(const CString& szFilePath);
    // 生命周期与对话框相同的图片
    void SetImage(const CImage& image);

private:
    COLORREF m_bkColor;
    COLORREF m_textColor;
    BOOL m_bTrack;
    BOOL m_bOver;
    BOOL m_bDown;
    BOOL m_bDisable;  
    // add byzt
    CImage m_bkImage;
public:
    afx_msg void OnMouseMove(UINT nFlags, CPoint point);
    afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
    afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
    virtual BOOL PreTranslateMessage(MSG* pMsg);
    virtual void DrawItem(LPDRAWITEMSTRUCT /*lpDrawItemStruct*/);
};


// ButtonBmp.cpp : 实现文件
//

#include "stdafx.h"
#include "ButtonDemo.h"
#include "ButtonTranslucent.h"

#include "ButtonDemoDlg.h"

// CButtonBmp

IMPLEMENT_DYNAMIC(CButtonTranslucent, CButton)

CButtonTranslucent::CButtonTranslucent()
: m_bkColor(0)
, m_textColor(0)
, m_bTrack(FALSE)
, m_bOver(FALSE)
, m_bDown(FALSE)
, m_bDisable(FALSE)
{

}

CButtonTranslucent::~CButtonTranslucent()
{
}


BEGIN_MESSAGE_MAP(CButtonTranslucent, CButton)
    ON_WM_MOUSEMOVE()
    ON_WM_LBUTTONDOWN()
    ON_WM_LBUTTONUP()
END_MESSAGE_MAP()



// CButtonBmp 消息处理程序



void CButtonTranslucent::PreSubclassWindow()
{
    // TODO: 在此添加专用代码和/或调用基类
    m_bTrack = FALSE;  
    m_bOver = m_bDown = m_bDisable = FALSE;  
    m_bDisable = IsWindowEnabled() ? FALSE : TRUE;
    ModifyStyle(NULL,BS_OWNERDRAW); 

    CButton::PreSubclassWindow();
}

void CButtonTranslucent::SetBkColor(COLORREF color)
{
    m_bkColor = color;
}

void CButtonTranslucent::SetTextColor(COLORREF color)
{
    m_textColor = color;
}

void CButtonTranslucent::OnMouseMove(UINT nFlags, CPoint point)
{
    // TODO: 在此添加消息处理程序代码和/或调用默认值


    if (!m_bTrack)  
    {  
//         m_bOver = TRUE;  
        TRACKMOUSEEVENT tme;
        tme.cbSize=sizeof(TRACKMOUSEEVENT);
        tme.dwFlags=TME_HOVER | TME_LEAVE;
        tme.dwHoverTime=HOVER_DEFAULT;
        tme.hwndTrack=m_hWnd;

        m_bTrack=_TrackMouseEvent(&tme);
    }  

    CButton::OnMouseMove(nFlags, point);
}

void CButtonTranslucent::OnLButtonDown(UINT nFlags, CPoint point)
{
    // TODO: 在此添加消息处理程序代码和/或调用默认值
    m_bDown = TRUE;

    CButton::OnLButtonDown(nFlags, point);
}

void CButtonTranslucent::OnLButtonUp(UINT nFlags, CPoint point)
{
    // TODO: 在此添加消息处理程序代码和/或调用默认值
    m_bDown = FALSE;

    CButton::OnLButtonUp(nFlags, point);
}

BOOL CButtonTranslucent::PreTranslateMessage(MSG* pMsg)
{
    // TODO: 在此添加专用代码和/或调用基类
    
    if (WM_MOUSELEAVE == pMsg->message)
    {
        m_bOver = FALSE;  
        m_bTrack = FALSE;  
        InvalidateRect(NULL, FALSE);  
    } else if (WM_MOUSEHOVER == pMsg->message)
    {
        m_bOver = TRUE;  
        InvalidateRect(NULL);  
    }


    return CButton::PreTranslateMessage(pMsg);
}

void CButtonTranslucent::DrawItem(LPDRAWITEMSTRUCT /*lpDrawItemStruct*/)
{

    // TODO:  添加您的代码以绘制指定项
    HDC hDestDC=::GetDC(m_hWnd);  

    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);  
//  Modify BYZT  
    CDialog* pParent=(CDialog*)GetParent();  

    CPoint pt(0,0);  
    MapWindowPoints(pParent,&pt,1);  
    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 CButtonTranslucent::SetImage(const CString& szFilePath)
{
    m_bkImage.Load(szFilePath);
}
void CButtonTranslucent::SetImage(const CImage& image)
{
    m_bkImage = image;
    return;
    if (!m_bkImage.IsNull())
    {
        m_bkImage.Destroy();
    }
    m_bkImage.Create(image.GetWidth(), image.GetHeight(), image.GetBPP());
    image.BitBlt(m_bkImage.GetDC(), 0, 0);
}

效果图如下

因没有使用双缓冲技术,所以按钮图片有闪烁。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值