zoukankan      html  css  js  c++  java
  • MFC 重绘CButton 支持透明背景的png

    转载:https://blog.csdn.net/songyimin1208/article/details/54408296

    1.InitInstance初始化GDI

    #include <gdiplus.h>
    #pragma comment(lib,"gdiplus.lib")
    class CtestMFCButtonApp : public CWinApp
    {
    public:
        CtestMFCButtonApp();
    
    // 重写
    public:
        virtual BOOL InitInstance();
        virtual int ExitInstance();
    // 实现
    
        DECLARE_MESSAGE_MAP()
    
    private:
        Gdiplus::GdiplusStartupInput m_gdiplusStartupInput;
        ULONG_PTR m_pGdiToken;
    };
    BOOL CtestMFCButtonApp::InitInstance()
    {
        .......................
    
        CWinApp::InitInstance();
    
        GdiplusStartup(&m_pGdiToken, &m_gdiplusStartupInput, NULL);
        .......................
    }
    
    int CtestMFCButtonApp::ExitInstance()
    {
    Gdiplus::GdiplusShutdown(m_pGdiToken);
    
    return 0;
    }

    2.自定义Button类

    PicButton.h

    #pragma once
    #include "afxwin.h"
    #include <gdiplus.h>
    #pragma comment(lib,"gdiplus.lib")
    
    
    class CPicButton :public CButton
    {
        DECLARE_DYNAMIC(CPicButton)
    public:
        CPicButton();
        ~CPicButton();
    
        enum BUTTON_STATE
        {
            BUTTON_ENABLE = 0,
            BUTTON_HOVER = 1,
            BUTTON_CLICK = 2,
            BUTTON_DISABLE = 3
        };
    
    protected:
        afx_msg LRESULT OnMouseLeave(WPARAM wparam, LPARAM lparam);
        afx_msg LRESULT OnMouseHover(WPARAM wparam, LPARAM lparam);
        afx_msg BOOL OnEraseBkgnd(CDC* pDC);
        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:
        virtual LRESULT DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam);
        void CPicButton::PreSubclassWindow();
        DECLARE_MESSAGE_MAP()
    public:
        virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
        void SetButtonImage(Gdiplus::Image* img);
    
    private:
        BOOL m_bDisable; // 按钮是否禁用 
        BOOL m_bCursorOnButton; // 鼠标是否在按钮上
        BOOL m_bPress; // 按钮是否被按下
    
        int m_nWidth;       //图片宽
        int m_nHeight;     //图片高
        int m_nSliceWidth;  //每一块图片的宽
    
        Gdiplus::Image* m_btnImage;//按钮图片
        CRect m_rectButton;//按钮区域
    };

    PicButton.cpp

    #include "stdafx.h"
    #include "PicButton.h"
    
    IMPLEMENT_DYNAMIC(CPicButton, CButton)
    CPicButton::CPicButton()
    {
        m_bDisable = FALSE;
        m_bCursorOnButton = FALSE;
        m_bPress = FALSE;
    }
    
    
    CPicButton::~CPicButton()
    {
        if (m_btnImage)
        {
            delete m_btnImage;
            m_btnImage = NULL;
        }
    
    }
    
    }
    
    BEGIN_MESSAGE_MAP(CPicButton, CButton)
        ON_WM_MOUSEMOVE()
        ON_MESSAGE(WM_MOUSEHOVER, OnMouseHover)
        ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)
        ON_WM_LBUTTONDOWN()
        ON_WM_LBUTTONUP()
        ON_WM_ERASEBKGND()
    END_MESSAGE_MAP()
    
    
    
    
    void CPicButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
    {
        CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
        Gdiplus::Graphics graphics(pDC->m_hDC);
    
        if (m_bDisable == TRUE)
        {
            graphics.DrawImage(m_btnImage, Gdiplus::Rect(0, 0, m_nSliceWidth, m_nHeight),
                BUTTON_DISABLE * m_nSliceWidth, 0, m_nSliceWidth, m_nHeight, Gdiplus::UnitPixel, NULL, NULL, NULL);
        }
        else
        {
            // click state
            if (lpDrawItemStruct->itemState & ODS_SELECTED)
            {
                graphics.DrawImage(m_btnImage, Gdiplus::Rect(0, 0, m_nSliceWidth, m_nHeight),
                    BUTTON_CLICK * m_nSliceWidth, 0, m_nSliceWidth, m_nHeight, Gdiplus::UnitPixel, NULL, NULL, NULL);
            }
            // hover state
            else if (m_bPress)
            {
                graphics.DrawImage(m_btnImage, Gdiplus::Rect(0, 0, m_nSliceWidth, m_nHeight),
                    BUTTON_HOVER * m_nSliceWidth, 0, m_nSliceWidth, m_nHeight, Gdiplus::UnitPixel, NULL, NULL, NULL);
            }
            // enable state
            else
            {
                graphics.DrawImage(m_btnImage, Gdiplus::Rect(0, 0, m_nSliceWidth, m_nHeight),
                    BUTTON_ENABLE*m_nSliceWidth, 0, m_nSliceWidth, m_nHeight, Gdiplus::UnitPixel, NULL, NULL, NULL);
            }
        }
    }
    
    void CPicButton::SetButtonImage(Gdiplus::Image* img)
    {
        if (m_btnImage != NULL)
        {
            delete m_btnImage;
            m_btnImage = img;
        }
        else
        {
            m_btnImage = img;
        }
    
        if (m_btnImage)
        {
            m_nWidth = m_btnImage->GetWidth();
            m_nHeight = m_btnImage->GetHeight();
            m_nSliceWidth = m_nWidth;   //图片切成四分
    
            CWnd *pWnd = this->GetParent();
            GetWindowRect(&m_rectButton);
            pWnd->ScreenToClient(m_rectButton);
            m_rectButton.right = m_rectButton.left + m_nSliceWidth;
            m_rectButton.bottom = m_rectButton.top + m_nHeight;
            MoveWindow(m_rectButton);      //调整按钮大小以适应图片
        }
        Invalidate();
    }
    
    void CPicButton::PreSubclassWindow()
    {
        ModifyStyle(0, BS_OWNERDRAW);
        CButton::PreSubclassWindow();
    }
    
    
    LRESULT CPicButton::OnMouseLeave(WPARAM wparam, LPARAM lparam)
    {
        m_bCursorOnButton = FALSE;
        m_bPress = FALSE;
        Invalidate();
        return 0L;
    }
    
    LRESULT CPicButton::OnMouseHover(WPARAM wparam, LPARAM lparam)
    {
        m_bPress = TRUE;
        Invalidate();
        return 0L;
    }
    
    BOOL CPicButton::OnEraseBkgnd(CDC* pDC)
    {
        return TRUE;
    }
    
    void CPicButton::OnMouseMove(UINT nFlags, CPoint point)
    {
        if (m_bCursorOnButton == FALSE)
        {
            TRACKMOUSEEVENT tme;
            ZeroMemory(&tme, sizeof(TRACKMOUSEEVENT));
            tme.cbSize = sizeof(tme);
            tme.hwndTrack = m_hWnd;
            tme.dwFlags = TME_LEAVE | TME_HOVER;
            tme.dwHoverTime = 1;
            m_bCursorOnButton = _TrackMouseEvent(&tme);
        }
    }
    
    void CPicButton::OnLButtonDown(UINT nFlags, CPoint point)
    {
        Invalidate();
        CButton::OnLButtonDown(nFlags, point);
    }
    
    void CPicButton::OnLButtonUp(UINT nFlags, CPoint point)
    {
        Invalidate();
        CButton::OnLButtonUp(nFlags, point);
    }
    
    LRESULT CPicButton::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam)
    {
        if (message == WM_LBUTTONDBLCLK)
        {
            message = WM_LBUTTONDOWN;
        }
        return CButton::DefWindowProc(message, wParam, lParam);//很重要,消除双击没反应
    }

    3.修改资源文件中button的属性

     4.给控件添加变量,把CButton  改成自定义的CPicButton

     5.在OnInitDialog函数中给button设置png

    BOOL CtestMFCButtonDlg::OnInitDialog()
    {
        CDialogEx::OnInitDialog();
    
       '''''''''''''''''''''''''''''''''''''''''''''''''
        Gdiplus::Image* pImg = Gdiplus::Image::FromFile(_T("C:\Users\Administrator\Desktop\touming.png"));
    
        m_btn.SetButtonImage(pImg);
      return TRUE;
    }

    二、给对话框指定区域设置背景色

    在WM_ERASEBKGND消息函数里处理

    BOOL CtestMFCButtonDlg::OnEraseBkgnd(CDC* pDC)
    {
        // TODO: 在此添加消息处理程序代码和/或调用默认值
    
        CBrush brush(RGB(196,196,198));
    
        CBrush* pOldBrush = pDC->SelectObject(&brush);
        CRect rc;
        GetClientRect(&rc);
        pDC->PatBlt(0, 0, rc.Width() - 200, rc.Height(), PATCOPY);
    
        pDC->SelectObject(pOldBrush);
    
        return TRUE;
    }

    三、对话框背景色不是纯白色的时候,设置对话框上控件背景色透明

    在WM_CTLCOLOR消息函数里处理中

    HBRUSH CtestMFCButtonDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
    {
        HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
    
        // TODO:  在此更改 DC 的任何特性
    
        // TODO:  如果默认的不是所需画笔,则返回另一个画笔
    
        //静态文本
        if (pWnd->GetDlgCtrlID() == IDC_STATIC)
        {
            pDC->SetBkMode(TRANSPARENT);
    
            return (HBRUSH)::GetStockObject(NULL_BRUSH);
        }
        //Radio按钮背景 
        TCHAR szClassName[MAX_PATH] = { 0 };
        ::GetClassName(pWnd->m_hWnd, szClassName, sizeof(szClassName) / sizeof(TCHAR) - 2);
        if (lstrcmpi(szClassName, _T("Button")) == 0)
        {
            UINT uStyle = ((CButton*)pWnd)->GetButtonStyle();
            switch (uStyle)
            {
            case BS_AUTORADIOBUTTON:
            {
                static HBRUSH hbrSatic = ::CreateSolidBrush(RGB(196, 196, 198));
                pDC->SetBkMode(TRANSPARENT);
                pDC->SetTextColor(RGB(0, 0, 0)); //字体颜色 
                return hbrSatic;
            }
            break;
            default:
                break;
            }
        }
    
        return hbr;
    }
  • 相关阅读:
    for循环
    3.9 作业
    while循环
    深浅拷贝
    条件与判断
    可变与不可变
    与用户交互与运算符
    垃圾回收机制
    【AC自动机】文本生成器
    【AC自动机】最短母串
  • 原文地址:https://www.cnblogs.com/chechen/p/14872943.html
Copyright © 2011-2022 走看看