MFC的PNG图片按钮

pngbutton.h
#pragma once
#include "afxwin.h"

/ 
// 工程: YF_GCM -> ButtonDemo 
// 作者: **
// 描述: 自绘制位图按钮
// 主要函数:
//         SetButtonUpBitmapEx()设置鼠标放置在按钮上的图片
//         SetButtonDownBitmapEx()设置按钮按下的图片
//         SetButtonNormalBitmapEx()设置鼠标不在按钮是的图片
// 日期: 2013.12.16
// 版本: 1.0
// 修改: 
/ 
// CBitmapButtonEx

class CPngButton : public CBitmapButton
{
    DECLARE_DYNAMIC(CPngButton)

public:
    CPngButton();
    virtual ~CPngButton();

protected:
    DECLARE_MESSAGE_MAP()

protected:

    virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);

public:
    // 设置按钮抬起图片
    BOOL SetButtonUpBitmapEx(const CString& szFilePath);
    // 设置按钮按下图片
    BOOL SetButtonDownBitmapEx(const CString& szFilePath);
    // 普通按钮图片
    BOOL SetButtonNormalBitmapEx(const CString& szFilePath);
protected:
    virtual void PreSubclassWindow();
public:
    virtual BOOL PreTranslateMessage(MSG* pMsg);
    afx_msg void OnMouseMove(UINT nFlags, CPoint point);
    afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
    afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
protected:
    BOOL m_lButtonDown;
    // 按钮有效区域
//     CRgn m_btRgn;
    // 绘制按钮图片区域
//     CRect m_rectDrawButton;
private:
    // 图片
    CImage m_imageButtonUp;
    CImage m_imageButtonDown;
    CImage m_imageBitmapNormal;
    CDC m_bkDc; // 记录背景
    bool m_first;
public:

protected:
    BOOL m_bMouseOver;
    BOOL m_bTrack;
public:
};

pngbutton.cpp


/ 
// 工程: YF_GCM -> ButtonDemo 
// 作者: **
// 描述: 自绘制位图按钮
// 主要函数:
//         SetButtonUpBitmapEx()设置鼠标放置在按钮上的图片
//         SetButtonDownBitmapEx()设置按钮按下的图片
//         SetButtonNormalBitmapEx()设置鼠标不在按钮是的图片
// 日期: 2013.12.16
// 版本: 1.0
// 修改: 
/ 

#include "stdafx.h"
#include "pngbutton.h"
#include "TransparentPNG.h"
// #include "LogToFile.h"

// CBitmapButtonEx

IMPLEMENT_DYNAMIC(CPngButton, CBitmapButton)

    CPngButton::CPngButton()
    : CBitmapButton()
    , m_lButtonDown(FALSE)
    , m_bMouseOver(FALSE)
    , m_bTrack(FALSE)
    , m_first(true)
{
}

CPngButton::~CPngButton()
{
    if (NULL != m_imageButtonUp)
    {
        ::DeleteObject(m_imageButtonUp);
    }
    if (NULL != m_imageButtonDown)
    {
        ::DeleteObject(m_imageButtonDown);
    }
    if (NULL != m_imageBitmapNormal)
    {
        ::DeleteObject(m_imageButtonDown);
    }
}


BEGIN_MESSAGE_MAP(CPngButton, CBitmapButton)
    ON_WM_LBUTTONDOWN()
    ON_WM_LBUTTONUP()
    ON_WM_MOUSEMOVE()
END_MESSAGE_MAP()



// CBitmapButtonEx 消息处理程序

BOOL CPngButton::SetButtonUpBitmapEx(const CString& szFilePath)
{
    if (!m_imageButtonUp.IsNull())
    {
        m_imageButtonUp.Destroy();
    }
    m_imageButtonUp.Load(szFilePath);
    if (!m_imageButtonUp.IsNull())
    {
        CTransparentPNG tran;
        tran(&m_imageButtonUp);
    }
    return !m_imageButtonUp.IsNull();
}


BOOL CPngButton::SetButtonNormalBitmapEx(const CString& szFilePath)
{
    if (!m_imageBitmapNormal.IsNull())
    {
        m_imageBitmapNormal.Destroy();
    }
    m_imageBitmapNormal.Load(szFilePath);
    if (!m_imageBitmapNormal.IsNull())
    {
        CTransparentPNG tran;
        tran(&m_imageBitmapNormal);
    }
    return !m_imageBitmapNormal.IsNull();
}

// BOOL CPngButton::SetRedPointImage(const CString& szFilePath)
// {
//     if (!m_imageRedPoint.IsNull())
//     {
//         m_imageRedPoint.Destroy();
//     }
//     m_imageRedPoint.Load(szFilePath);
//     if (!m_imageRedPoint.IsNull())
//     {
//         CTransparentPNG tran;
//         tran(&m_imageRedPoint);
//     }
//     return !m_imageRedPoint.IsNull();
// }
BOOL CPngButton::SetButtonDownBitmapEx(const CString& szFilePath)
{
    if (!m_imageButtonDown.IsNull())
    {
        m_imageButtonDown.Destroy();
    }
    m_imageButtonDown.Load(szFilePath);
    if (!m_imageButtonDown.IsNull())
    {
        CTransparentPNG tran;
        tran(&m_imageButtonDown);
    }
    return !m_imageButtonDown.IsNull();
}

void CPngButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
    // TODO:  添加您的代码以绘制指定项
    CRect rect =  lpDrawItemStruct->rcItem;

    if (m_first)
    {// 复制背景
        CDialog* pParent=(CDialog*)GetParent();  
        CPoint pt(0,0);  
        MapWindowPoints(pParent,&pt,1);  
        CDC * pdc = GetParent ()->GetDC ();
        m_bkDc.CreateCompatibleDC (pdc);
        CBitmap memBmp;
        memBmp.CreateCompatibleBitmap(pdc, rect.right, rect.bottom);
        m_bkDc.SelectObject(&memBmp);
        m_bkDc.BitBlt (0, 0, rect.right, rect.bottom, pdc, pt.x, pt.y, SRCCOPY);
        ReleaseDC (pdc);
        m_first = false;
    }
//     CClientDC dc(this);
//     dc.Rectangle (rect);
    // 背景
    CDC* thisdc = NULL;
    thisdc = GetDC();
    thisdc->BitBlt (0, 0, rect.right, rect.bottom, &m_bkDc, 0/*rect.right*/, 0/*rect.bottom*/, SRCCOPY);
    
    if (m_lButtonDown)
    {
        if (m_imageButtonDown.IsNull())
        {
//             CString szLog;
//             szLog.Format(_T("m_imageButtonDown 未加载背景图片!"));
//             AppLog(szLog);
        }
        else
        {
            m_imageButtonDown.Draw(thisdc->m_hDC, rect/*m_rectDrawButton*/);
        }
    }
    else
    {
        if (m_bMouseOver)
        {
            if (m_imageButtonUp.IsNull())
            {
//                 CString szLog;
//                 szLog.Format(_T("m_imageButtonUp 未加载背景图片!"));
//                 AppLog(szLog);
            }
            else
            {
                m_imageButtonUp.Draw(thisdc->m_hDC, rect/*m_rectDrawButton*/);
            }
        }
        else
        {
            if (m_imageBitmapNormal.IsNull())
            {
//                 CString szLog;
//                 szLog.Format(_T("m_imageBitmapNormal 未加载背景图片!"));
//                 AppLog(szLog);
            }
            else
            {
                m_imageBitmapNormal.Draw(thisdc->m_hDC, rect/*m_rectDrawButton*/);
            }
        }
    }
    if (0 == this->ReleaseDC(thisdc))
    {
//         CString szLog;
//         szLog.Format(_T("ReleaseDC error!"));
//         AppLog(szLog);
    }
}

void CPngButton::PreSubclassWindow()
{
    // TODO: 在此添加专用代码和/或调用基类

    ModifyStyle(0, WS_CLIPCHILDREN | BS_OWNERDRAW ); //设置按钮的有效区域 

//     CRect rect;
//     GetClientRect(&rect);
//     CDialog* pParent=(CDialog*)GetParent();  
//     CPoint pt(rect.left, rect.top);  
//     MapWindowPoints(pParent, &pt, 1);  
//     CDC * pdc = GetParent ()->GetDC ();
//     // 复制背景
//     m_bkDc.CreateCompatibleDC (pdc);
//     CBitmap memBmp;
//     memBmp.CreateCompatibleBitmap(pdc, rect.right, rect.bottom);
//     m_bkDc.SelectObject(&memBmp);
//     m_bkDc.BitBlt (0, 0, rect.right, rect.bottom, pdc, 0, 0, SRCCOPY);
//     ReleaseDC (pdc); 

//     m_btRgn.CreateRectRgnIndirect (rc);
//     SetWindowRgn(m_btRgn, TRUE); 

    CBitmapButton::PreSubclassWindow();
}

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

    m_lButtonDown = TRUE;
    CBitmapButton::OnLButtonDown(nFlags, point);
}

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

BOOL CPngButton::PreTranslateMessage(MSG* pMsg)
{
    // TODO: 在此添加专用代码和/或调用基类

    if(pMsg->message==WM_MOUSELEAVE) 
    {
        m_bTrack=FALSE;
        m_bMouseOver = FALSE;
        InvalidateRect(NULL);
    }
    else if (pMsg->message==WM_MOUSEHOVER)
    {
        m_bMouseOver = TRUE;
        InvalidateRect(NULL);
    }

    return CBitmapButton::PreTranslateMessage(pMsg);
}

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

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

        m_bTrack=_TrackMouseEvent(&tme);
    }

    CBitmapButton::OnMouseMove(nFlags, point);
}
CTransparentPNG 地址

点击打开链接https://gitee.com/user.zt/codes/rni2jtabfxcykzu7lvo3067

因gitee.com代码段公共访问功能关闭导致上述链接失效,现将代码贴出。

CTransparentPNG 

/
// 工程: 
// 作者: 
// 描述: 处理png图片,使背景变白
// 主要函数:
// 日期: 2014.11.28
// 版本: 1.0
// 修改:
/
#pragma once
class CTransparentPNG
{

public:
    CTransparentPNG() {}
    ~CTransparentPNG() {}


    bool operator()(CImage* image) {
        if (!image)
            return false;
        if (image->GetBPP() != 32)
            return false;
        for (int i = 0; i < image->GetWidth(); ++i)
        {
            for (int j = 0; j < image->GetHeight(); ++j)
            {
                unsigned char* pucColor = reinterpret_cast<unsigned char*>(image->GetPixelAddress(i, j));
                pucColor[0] = pucColor[0] * pucColor[3] / 255;
                pucColor[1] = pucColor[1] * pucColor[3] / 255;
                pucColor[2] = pucColor[2] * pucColor[3] / 255;
            }
        }

        return true;
    }

    static bool TransPng(CImage* image)
    {
        if (!image)
            return false;
        if (image->GetBPP() != 32)
            return false;
        for (int i = 0; i < image->GetWidth(); ++i)
        {
            for (int j = 0; j < image->GetHeight(); ++j)
            {
                unsigned char* pucColor = reinterpret_cast<unsigned char*>(image->GetPixelAddress(i, j));
                pucColor[0] = pucColor[0] * pucColor[3] / 255;
                pucColor[1] = pucColor[1] * pucColor[3] / 255;
                pucColor[2] = pucColor[2] * pucColor[3] / 255;
            }
        }
        return true;
    }

};

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值