MFC的PNG贴图按钮类(详细注释)

MFC的PNG贴图按钮类(详细注释)

(转载请注明出处)博客园链接:https://www.cnblogs.com/MJGY/p/10426936.html

作者:梦镜谷雨


萌新第二次写帖子,请多多包涵。末尾附上相应代码(PS公司繁体系统所以部分注释繁体请别介意)。

因自带控件不美观,于是网上参考学习了些代码做了个按钮类。可以载入通过资源的ID加载也可以通过外部动态加载PNG图片,可以选择半透明贴膜效果。

参考代码:https://blog.csdn.net/qq_16123279/article/details/82858238

参考代码:https://blog.csdn.net/zhongbin104/article/details/8730935


一.思路

Step1.重载DrawItem函数

Step2.保存父窗口位置被遮挡的背景

Step3.保存需要的PNG贴图和其他设置

Step4.画上父窗口位置被遮挡的背景后再按设置画上需要的其他元素

二.使用例子演示

Step1.创建控件

Step2.导入资源(Add Resoure)(可以不用导入资源,类里面也有动态加载PNG图片的接口)

原来效果

创建对象后:

protected:

    CPngButton m_BTN_Menu;

    CPngButton m_BTN_Button1;

    CPngButton m_BTN_Button3;

初始化里给Menu按钮添加白色半透明贴膜和设置文字:

#defineShowColor RGB(255,255,255)

m_BTN_Menu.SubclassDlgItem(IDC_BUTTON_Menu,this);

m_BTN_Menu.SetTitle(_T("菜单1"));//設置按鈕顯示文字m_BTN_Menu.SetColor(ShowColor,100,155);//設置按鈕顯示半透明貼膜m_BTN_Menu.SetSize(60,20);//設置按鈕大小

给最顶端按钮添加贴膜和设置文字后的效果:

1.正常显示:

2.鼠标悬浮在Menu按钮上

3.按下Menu按钮

初始化里给Button1按钮添加贴图和白色半透明贴膜

m_BTN_Button1.SubclassDlgItem(IDC_BUTTON1,this);

  m_BTN_Button1.SetImagePng(IDB_PNG_BUTTON1);

  m_BTN_Button1.SetColor(RGB(74,144,226),100,155);//設置按鈕顯示半透明貼膜

给左边按钮添加一张贴图和设置贴膜后的效果:

1.正常显示

2.鼠标悬浮在Button1按钮上

3.按下Button1按钮

初始化里给Button3按钮添加几种不同情况下贴图

m_BTN_Button3.SubclassDlgItem(IDC_BUTTON3,this);

m_BTN_Button3.SetImagePng(IDB_PNG_BUTTON1,IDB_PNG1,IDB_PNG2);

给右边按钮贴上几种不同状态的贴膜效果:

1.正常显示

2.鼠标悬浮在Button3按钮上

3.按下Button3按钮

三.相关代码

.h代码

#pragma once

#include "afxwin.h"

// CPngButton

class CPngButton : public CButton

{

//功能:加載透明PNG設置半透明的按鈕類

//注:如出現貼膜顏色為黑色情況請檢查是否有SetColor因為m_BaseColor初始化為RGB(0,0,0)

DECLARE_DYNAMIC(CPngButton)

protected:

enum ButtonState

{

    Disable = 0,Normal,On,Down

};

enum ButtonMode

{

    MaskMode = 0,PictureMode

};

public:

CPngButton();

virtual ~CPngButton();

protected:

void LoadImage(CImage &image,UINT nID);

CImage m_image[4];

void Draw(UINT nID,CDC* pDC,CRect rect);//畫PNG貼圖

protected:

DECLARE_MESSAGE_MAP()

void CancelHover(void);//修改鼠標不在懸浮于控件上的標誌

protected:

CDC m_MemDCBG;//保持的父窗口擋住的背景

COLORREF m_BaseColor;//半透明貼膜的顏色

BOOL m_bFlagIsFirst;//是否為第一次取得父窗口背景的標誌位

BOOL m_bFlagIsColorSet;//是否需要貼膜

int m_iOnTransparent;//鼠標懸浮在按鈕上時半透明貼膜的透明度

int m_iDownTransparent;//鼠標按下是半透明貼膜的透明度

BOOL m_bFlagIsTextSet;//是否需要打印出文字

BOOL m_bFlagIsImageSet;//是否需要打印圖片

CFont m_font;

LOGFONT m_lf;

int m_iTitleSize;//按鈕文字的大小

int m_iState;//按鈕的風格(0為採用半透明貼膜效果,1為使用3張以上PNG資源來區分狀態)

protected:

BOOL m_bMouseOnButton;//鼠標是否在按鈕上

BOOL m_bIsPressed;//按鍵是否按下

BOOL m_bIsFocused;//按鍵是否得到焦點

BOOL m_bFlagContinueShow;//這個為TRUE時按鈕的繪圖會一直保持在按下狀態

public:

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

//函數名SetColor

//功能:設置觸摸按鍵的半透明顏色

//參數:COLORREF color - 按鈕觸碰后的背景色

//   UINT OnTransparent = 0x0F - 鼠標懸浮時膜的透明度

//   UINT DownTransparent = 0x3F - 按鈕按下時膜的透明度

//返回值:判斷輸入值是否合理

//注:貼膜專用,OnTransparent和DownTransparent正常範圍0 - FF,值越小越透明

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

BOOL SetColor(COLORREF color,UINT OnTransparent = 0x0F,UINT DownTransparent = 0x3F);

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

//函數名:SetTitle

//功能:設置按鍵的標題

//參數:CString csTitle - 按鍵顯示的圖片信息

//    int TitleSize - 設置字體大小

//返回值:判斷是否設置成功

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

BOOL SetTitle(const CString &csTitle);

BOOL SetTitle(const CString &csTitle,int TitleSize);

BOOL SetTitle(const CString &csTitle,CFont *pFont);

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

//函數名SetImagePng

//功能:設置插入PNG背景資源

//參數:UINT nIDNormal - 一般情況背景圖片資源的ID

//   :UINT nIDOn - 鼠標懸浮情況的圖片資源的ID

//   :UINT nIDDown - 按鈕按下情況的圖片資源的ID

//   :UINT nIDDisable =0 - 按鈕失能情況的圖片資源的ID

//返回值:無

//注:SetImagePng(UINT nIDNormal,UINT nIDDisable =0);自動設置為貼膜模式

// SetImagePng(UINT nIDNormal,UINT nIDOn,UINT nIDDown,UINT nIDDisable =0);自動設置為貼圖模式

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

void SetImagePng(UINT nIDNormal,UINT nIDDisable =0);

void SetImagePng(const CString& PathNormal,const CString& PathDisable = _T(""));

void SetImagePng(UINT nIDNormal,UINT nIDOn,UINT nIDDown,UINT nIDDisable =0);

void SetImagePng(const CString& PathNormal,const CString& PathOn,const CString& PathDown,const CString& PathDisable = _T(""));

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

//函數名SaveBG

//功能:更新控件擋住是背景,改變父窗口背景后需調用一次

//參數:無

//返回值:無

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

void SaveBG(void);

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

//函數名SizeToContent

//功能:使按鈕大小和PNG資源大小一致

//參數:無

//返回值:無

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

void SizeToContent(void);

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

//函數名SetSize

//功能:自定義設置控件大小

//參數:int iWidth - 設置控件寬度

//    :int iHeight - 設置控件高度

//返回值:無

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

void SetSize(int iWidth,int iHeight);

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

//函數名SetShowState

//功能:設置按鈕風格

//參數:BOOL NeedColorSet - 設置是否顯示貼膜

//    :BOOL NeedTextSet - 設置是否打印文字

//   :BOOL NeedImageSet - 設置是否打印PNG圖片

//返回值:無

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

BOOL SetShowState(BOOL NeedColorSet, BOOL NeedTextSet,BOOL NeedImageSet);

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

//函數名SetContinueShow

//功能:設置按鈕是否需要一直顯示為按下狀態

//參數:BOOL ContinueShow - 是否顯示為按下狀態

//返回值:無

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

void SetContinueShow(BOOL ContinueShow);

//********************************************************************

protected:

virtual void PreSubclassWindow();//設置按鈕分割為重繪

virtual void DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct );//重繪按鈕圖案

//一些判斷按鈕狀態的系統函數

afx_msg BOOL OnEraseBkgnd(CDC* pDC);//防止擦灰背景

afx_msg void OnMouseMove(UINT nFlags, CPoint point);//鼠標移動到上面時判斷狀態

LRESULT OnMouseLeave(WPARAM wParam, LPARAM lParam);//鼠標離開時消息判斷狀態

afx_msg void OnKillFocus(CWnd* pNewWnd);//失去焦點時判斷狀態

};

 .c代码

// PngButton.cpp : implementation file

//

#include "stdafx.h"

#include "PngButton.h"

// CPngButton

IMPLEMENT_DYNAMIC(CPngButton, CButton)

CPngButton::CPngButton()

: m_bFlagIsColorSet(FALSE)

, m_bFlagIsTextSet(FALSE)

, m_bFlagIsImageSet(FALSE)

, m_bFlagIsFirst(TRUE)

, m_bMouseOnButton(FALSE)

, m_bIsPressed(FALSE)

, m_bIsFocused(FALSE)

, m_iTitleSize(90)

, m_iOnTransparent(0)

, m_iDownTransparent(0)

, m_iState(Disable)

, m_bFlagContinueShow(FALSE)

{

    //DEL initGDI();

    m_BaseColor = RGB(0,0,0);

}

CPngButton::~CPngButton()

{

}                         

BEGIN_MESSAGE_MAP(CPngButton, CButton)

    ON_WM_ERASEBKGND()

    ON_WM_MOUSEMOVE()

    ON_WM_KILLFOCUS()

    ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)

END_MESSAGE_MAP()

// CPngButton message handlers

void CPngButton::LoadImage(CImage &image,UINT nID)

{

    HINSTANCE hInst = AfxGetResourceHandle();

    HRSRC hRsrc = ::FindResource(hInst,MAKEINTRESOURCE(nID), _T("PNG"));

    if (hRsrc == NULL)

        return;

    DWORD len = SizeofResource(hInst, hRsrc);

    BYTE* lpRsrc = (BYTE*)LoadResource(hInst, hRsrc);

    if (lpRsrc == NULL)

        return;

    HGLOBAL m_hMem = GlobalAlloc(GMEM_FIXED, len);

    BYTE* pmem = (BYTE*)GlobalLock(m_hMem);

    memcpy(pmem,lpRsrc,len);

    IStream* pstm;

    CreateStreamOnHGlobal(m_hMem,FALSE,&pstm);

    image.Destroy();

    image.Load(pstm);

    GlobalUnlock(m_hMem);

    GlobalFree(m_hMem);

    pstm->Release();

    FreeResource(lpRsrc);

    if (image.GetBPP() == 32)

    {

        for(int i = 0; i < image.GetWidth(); i++) 

        { 

            for(int j = 0; j < image.GetHeight(); j++) 

            { 

                unsigned char* pucColor = reinterpret_cast(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; 

            } 

        }

    }

}

/*檢測和判斷按鈕狀態的消息功能們*/

void CPngButton::CancelHover(void)

{

    //功能:取消鼠標懸浮標誌位

    //參數:無

    //返回值:無

    if (m_bMouseOnButton)

    {

        m_bMouseOnButton = FALSE;

        Invalidate();

    } // if

} // End of CancelHover

void CPngButton::OnMouseMove(UINT nFlags, CPoint point)

{

    //功能:鼠標移動消息

    //參數:nFlag為指示各种虚拟按键是否按下,point為鼠標當前位置

    //返回值:無

    CWnd* wndUnderMouse = NULL;

    CWnd* wndActive = this;

    TRACKMOUSEEVENT csTME;

    CButton::OnMouseMove(nFlags, point);

    ClientToScreen(&point);

    wndUnderMouse = WindowFromPoint(point);

    // If the mouse enter the button with the left button pressed then do nothing

    if (nFlags & MK_LBUTTON && m_bMouseOnButton == FALSE)//鼠標左鍵按下闖過著跳過處理

        return;

    if (wndUnderMouse && wndUnderMouse->m_hWnd == m_hWnd && wndActive)//判斷并更新按鈕當前狀態

    {

        if (!m_bMouseOnButton)

        {

            m_bMouseOnButton = TRUE;

            Invalidate();

            csTME.cbSize = sizeof(csTME);

            csTME.dwFlags = TME_LEAVE;

            csTME.hwndTrack = m_hWnd;

            ::_TrackMouseEvent(&csTME);

        } // if

    } else CancelHover();

    CButton::OnMouseMove(nFlags, point);

}

LRESULT CPngButton::OnMouseLeave(WPARAM wParam, LPARAM lParam)

{

    //功能:鼠標離開按鈕消息

    //參數:wParam,lParam鼠標位置參數

    //返回值:LRESULT

    CancelHover();//取消懸浮狀態

    return 0;

} // End of OnMouseLeave

void CPngButton::OnKillFocus(CWnd* pNewWnd)

{

    //功能:失去焦點時消息處理

    //參數:pNewWnd指定指向接收输入焦点的窗口

    //返回值:無

    CButton::OnKillFocus(pNewWnd);

    // TODO: Add your message handler code here

    CancelHover();

}

BOOL CPngButton::OnEraseBkgnd(CDC* pDC)

{

    //功能:擦除背景消息處理

    //參數:pDC為此按鈕的DC

    //返回值:無

    return TRUE;// CButton::OnEraseBkgnd(pDC);

}

/*設置相關參數*/

void CPngButton::PreSubclassWindow()

{

    //功能:按鈕設置自繪模式

    //參數:無

    //返回值:無

    ModifyStyle(0,BS_OWNERDRAW);

    CButton::PreSubclassWindow();

}

void CPngButton::SetSize(int iWidth,int iHeight)

{

    //功能:設置按鈕大小

    //參數:iWidth為按鈕寬度,iHeight為按鈕高度

    //返回值:無

    SetWindowPos( NULL, -1, -1, iWidth, iHeight,

    SWP_NOMOVE | SWP_NOZORDER | SWP_NOREDRAW | SWP_NOACTIVATE);

}

BOOL CPngButton::SetColor(COLORREF color,UINT OnTransparent,UINT DownTransparent)

{

    //功能:設置半透明貼膜參數

    //參數:color貼膜的顏色,OnTransparent是鼠標懸浮在按鈕時其透明度,DownTransparent是按鈕按下時其透明度

    //返回值:BOOL是否設置成功

    m_BaseColor = color;//載入貼膜顏色

//DEL int ibrightness  = 0.299*GetRValue(color) + 0.587*GetGValue(color) + 0.114*GetBValue(color);//亮度

//DEL if (ibrightness > 225 || ibrightness < 15)

//DEL {

//DEL m_bFlagIsColorSet = FALSE;

//DEL return FALSE;

//DEL }

//DEL else

//DEL {

//DEL m_bFlagIsColorSet = TRUE;

//DEL return TRUE;

//DEL }

    if (OnTransparent < 0xFF && DownTransparent < 0xFF)//半透明參數需要小於255,否則不設置貼膜

    {

        //設置貼膜有效,并載入半透明度

        m_bFlagIsColorSet = TRUE;

        m_iOnTransparent = OnTransparent;

        m_iDownTransparent = DownTransparent;

    }else{

        m_bFlagIsColorSet = FALSE;//設置貼膜無效

    }

    return m_bFlagIsColorSet;//返回貼膜設置狀態

}

BOOL CPngButton::SetTitle(const CString &csTitle)

{

    //功能:設置標題

    //參數:csTitle為標題

    //返回值:BOOL標題是否顯示

    this->SetWindowTextW(csTitle);

    m_bFlagIsTextSet = TRUE;

    m_font.DeleteObject();

    m_font.CreatePointFont(m_iTitleSize, _T("微軟雅黑"));

    return m_bFlagIsTextSet;

}

BOOL CPngButton::SetTitle(const CString &csTitle,int TitleSize)

{

    //功能:設置標題

    //參數:csTitle為標題,TitleSize為標題字體大小

    //返回值:BOOL標題是否顯示

    this->SetWindowTextW(csTitle);

    m_iTitleSize = TitleSize;

    m_bFlagIsTextSet = TRUE;

    m_font.DeleteObject();

    m_font.CreatePointFont(m_iTitleSize, _T("微軟雅黑"));

    return m_bFlagIsTextSet;

}

BOOL CPngButton::SetTitle(const CString &csTitle,CFont *pFont)

{

    //功能:設置標題

    //參數:csTitle為標題,Font為

    //返回值:BOOL標題是否顯示

    this->SetWindowTextW(csTitle);

    m_bFlagIsTextSet = TRUE;

    pFont->GetLogFont(&m_lf);

    m_font.DeleteObject();

    m_font.CreateFontIndirect(&m_lf);

    return m_bFlagIsTextSet;

}

void CPngButton::SetImagePng(UINT nIDNormal,UINT nIDDisable)

{

    //功能:設置按鈕對應PNG圖片

    //參數:nID為按鈕普通狀態的PNG貼圖資源,nIDDisable為按鈕失能狀態下的PNG貼圖資源

    //返回值:無

    m_bFlagIsImageSet = TRUE;;

    if (m_bFlagIsImageSet)

    {

        LoadImage(m_image[Disable],nIDDisable);

        LoadImage(m_image[Normal],nIDNormal);

        m_iState = MaskMode;

    }

    SizeToContent();

}

void CPngButton::SetImagePng(const CString& PathNormal,const CString& PathDisable)

{

    m_bFlagIsImageSet = TRUE;;

    if (m_bFlagIsImageSet)

    {

        m_image[Disable].Load(PathDisable);

        m_image[Normal].Load(PathNormal);

        m_iState = MaskMode;

    }

    SizeToContent();

}

void CPngButton::SetImagePng(UINT nIDNormal,UINT nIDOn,UINT nIDDown,UINT nIDDisable)

{

    //功能:設置按鈕對應PNG圖片

    //參數:nID為按鈕普通狀態的PNG貼圖資源,nIDOn為鼠標懸浮在按鈕上狀態的PNG貼圖資源,nIDDown為按鈕按下狀態的PNG貼圖資源,nIDDisable為按鈕失能狀態下的PNG貼圖資源

    //返回值:無

    m_bFlagIsImageSet = TRUE;

    if (m_bFlagIsImageSet)

    {

        LoadImage(m_image[Disable],nIDDisable);

        LoadImage(m_image[Normal],nIDNormal);

        LoadImage(m_image[On],nIDOn);

        LoadImage(m_image[Down],nIDDown);

        m_iState = PictureMode;

    }

    SizeToContent();

}

void CPngButton::SetImagePng(const CString& PathNormal,const CString& PathOn,const CString& PathDown,const CString& PathDisable)

{

    m_bFlagIsImageSet = TRUE;;

    if (m_bFlagIsImageSet)

    {

        m_image[Disable].Load(PathDisable);

        m_image[Normal].Load(PathNormal);

        m_image[On].Load(PathOn);

        m_image[Down].Load(PathDown);

        m_iState = PictureMode;

    }

    SizeToContent();

}

void CPngButton::SetContinueShow(BOOL ContinueShow)

{

    //功能:設置是否一直顯示為按下狀態

    //參數:ContinueShow為是否要一直顯示為按下狀態

    //返回值:無

    m_bFlagContinueShow = ContinueShow;

}

void CPngButton::SizeToContent(void)

{

    //功能:使按鈕大小和載入的圖片大小一致

    //參數:無

    //返回值:無

    if (m_image[1] != NULL)

    {

        SetWindowPos( NULL, -1, -1,  m_image[1].GetWidth(),m_image[1].GetHeight() ,

        SWP_NOMOVE | SWP_NOZORDER | SWP_NOREDRAW | SWP_NOACTIVATE);

    } // if

} // End of SizeToContent

void CPngButton::SaveBG(void)

{

    //功能:保存父窗口擋住的背景

    //參數:無

    //返回值:無

    CRect rc;

    this->GetWindowRect(&rc);

    CDC* pDC = GetDC();

    CBitmap memBitmap;

    //得到父窗口句柄以及控件在父窗口的位置

    CDC* pParentDC = GetParent()->GetDC();

    CPoint pt(0,0);

    MapWindowPoints(GetParent(),&pt,1);

    if (m_MemDCBG == NULL)//如果已經m_MemDCBG已經創建了就不用再創建了,否則下次調用時會錯誤

        m_MemDCBG.CreateCompatibleDC(pDC);

    //將擋住的父窗口背景部分保存入m_MemDCBG中

    memBitmap.CreateCompatibleBitmap(pDC, rc.Width(), rc.Height());

    m_MemDCBG.SelectObject(&memBitmap);

    m_MemDCBG.BitBlt(0,0,rc.Width(),rc.Height(),pParentDC,pt.x,pt.y,SRCCOPY); 

    ::ReleaseDC(GetParent()->m_hWnd,*pParentDC);

    ::ReleaseDC(this->m_hWnd,*pDC);

}

BOOL CPngButton::SetShowState(BOOL NeedColorSet, BOOL NeedTextSet,BOOL NeedImageSet)

{

    //功能:設置按鈕風格

    //參數:NeedColorSet為是否顯示貼膜,NeedTextSet為是否打印文字,NeedImageSet為是否打印PNG圖片

    //返回值:無

    BOOL bFlagSuccessSet = TRUE;

    //設置是否顯示貼膜

    if (NeedColorSet)

    {

        if (m_BaseColor == NULL)

        {

            bFlagSuccessSet = FALSE;

        }else

            m_bFlagIsColorSet = NeedColorSet;

    }else{

    m_bFlagIsColorSet = NeedColorSet;

    }

    //設置是否顯示文字

    m_bFlagIsTextSet = NeedTextSet;

    //設置是否顯示png資源

    if (m_image[Disable] == NULL)

        ;

    else

        m_bFlagIsImageSet = NeedImageSet;

    return bFlagSuccessSet;

}

/*繪製按鈕*/

void CPngButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)

{

    //功能:繪製按鈕,參考BitButtonNL類

    //參數:lpDrawItemStruct按鈕參數

    //返回值:無

    m_bIsFocused  = (lpDrawItemStruct->itemState & ODS_FOCUS);//按鈕是否有焦點

    m_bIsPressed = (lpDrawItemStruct->itemState & ODS_SELECTED);//按鈕是否按下

    if (m_bFlagIsFirst)//第一次調用保存父窗口擋住的背景

    {

        SaveBG();

        m_bFlagIsFirst = FALSE;

        DrawItem(lpDrawItemStruct);

    }else{

        CRect rc;

        this->GetWindowRect(&rc);

        CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);

        pDC->SetBkMode(TRANSPARENT);

        CDC MemDC;

        CBitmap bmp;

        //創建雙緩存用的MemDC

        MemDC.CreateCompatibleDC(pDC);

        bmp.CreateCompatibleBitmap(pDC,rc.Width(),rc.Height());

        MemDC.SelectObject(&bmp);

        MemDC.BitBlt(0,0,rc.Width(),rc.Height(),&m_MemDCBG,0,0,SRCCOPY);  //畫父窗口擋住的背景

        if(IsWindowEnabled())

        {

            switch(m_iState)

            {

                case MaskMode:

                    if ((m_bFlagIsColorSet && m_bMouseOnButton ) || m_bFlagContinueShow)

                    {

                        //畫半透明貼膜

                        CDC MemDCBK;

                        CDC* pDCDrawBG;

                        pDCDrawBG = GetDC();

                        CBitmap bmpBK;

                        //創建半透明貼膜

                        MemDCBK.CreateCompatibleDC(pDCDrawBG);

                        bmpBK.CreateCompatibleBitmap(pDCDrawBG,rc.Width(),rc.Height());

                        MemDCBK.SelectObject(&bmpBK);

                        MemDCBK.FillSolidRect(0,0,rc.Width(),rc.Height(),m_BaseColor);

                        //半透明參數設置

                        BLENDFUNCTION bf;

                        bf.BlendOp=AC_SRC_OVER;

                        bf.BlendFlags=0;

                        if(m_bIsPressed || m_bFlagContinueShow)

                            bf.SourceConstantAlpha=m_iDownTransparent;

                        else

                            bf.SourceConstantAlpha=m_iOnTransparent;

                        bf.AlphaFormat=0;

                        MemDC.AlphaBlend(0,0,rc.Width(),rc.Height(),&MemDCBK,0,0,rc.Width(),rc.Height(),bf);//貼膜

                        ::ReleaseDC(this->m_hWnd, *pDCDrawBG);

                    }//end if ((m_bFlagIsColorSet && m_bMouseOnButton ) || m_bFlagContinueShow)

                    if (m_bFlagIsImageSet)

                    {

                        m_image[Normal].Draw(MemDC.m_hDC,0,0);

                    }//end if (m_bFlagIsImageSet)

                    break;

                case PictureMode:

                    if (m_bMouseOnButton || m_bFlagContinueShow)

                    {

                        if(m_bIsPressed || m_bFlagContinueShow)

                            m_image[Down].Draw((&MemDC)->m_hDC,0,0);

                        else

                            m_image[On].Draw((&MemDC)->m_hDC,0,0);

                    }else{//end if (m_bMouseOnButton || m_bFlagContinueShow)

                        m_image[Normal].Draw((&MemDC)->m_hDC,0,0);

                    }//end if (m_bMouseOnButton || m_bFlagContinueShow)...else

                    break;

            }//end switch(m_iState)

        }else{//endif(IsWindowEnabled())

            if (m_image[Disable] != NULL)

                m_image[Disable].Draw((&MemDC)->m_hDC,0,0);

            else

                m_image[Normal].Draw((&MemDC)->m_hDC,0,0);

        }

        if (m_bFlagIsTextSet)

        {

            //畫文字

            CString sTitle;

            GetWindowText(sTitle);

            //設置文字風格

            SetBkMode(MemDC, TRANSPARENT);

            //設置畫在控件中心

            CRect captionRect = lpDrawItemStruct->rcItem;

            captionRect.top--;

            MemDC.SelectObject(&m_font);

            MemDC.DrawText((LPCTSTR)sTitle, &captionRect,DT_SINGLELINE | DT_VCENTER | DT_WORDBREAK | DT_CENTER);

        }//end if (m_bFlagIsTextSet)

        pDC->BitBlt(0,0,rc.Width(),rc.Height(),&MemDC,0,0,SRCCOPY);

    }//end if (m_bFlagIsFirst)..else

}

四.结语

  今年年前写的类代码吧整整懒得优化了就发出来,有需要再优化好了.

  比较前一篇感觉代码规范了点(mmp手动缩进半天才发现可以贴代码),感觉都挺简单的应该看注释都能懂.

  看不懂也没关系按前面例子看.h试着用就完事了啦,注:有贴图的话按钮大小会跟贴图大小变化.

  海星的感觉(在公司补班打代码累了就摸了波鱼把自己搞的类贴出来,啊,摸鱼真是件幸福的事情~)

你可能感兴趣的:(MFC的PNG贴图按钮类(详细注释))