封装两个按钮类,图片切换按钮,显示效果一样,实现不同

第一种实现

#include "stdafx.h"
#include "ToolBarButten.h"


IMPLEMENT_DYNAMIC(CToolBarButten, CBitmapButton)
CToolBarButten::CToolBarButten()
{
    m_bOver/*(鼠标位于按钮之上)*/ = FALSE;
    m_bSelected/*(按钮被按下)*/ = FALSE;
    m_bTracking/*(在鼠标按下释放)*/ = FALSE;
    m_bFocus /*按钮为当前焦点*/ = FALSE;
}


CToolBarButten::~CToolBarButten()
{
}

BEGIN_MESSAGE_MAP(CToolBarButten, CBitmapButton)
    ON_WM_MOUSEMOVE()
    ON_WM_MOUSELEAVE()
    ON_WM_MOUSEHOVER()
END_MESSAGE_MAP()

void CToolBarButten::OnMouseMove(UINT nFlags, CPoint point)
{
    // TODO:  在此添加消息处理程序代码和/或调用默认值
    if (!m_bTracking)
    {
        TRACKMOUSEEVENT tme;
        tme.cbSize = sizeof(tme);
        tme.hwndTrack = m_hWnd;
        tme.dwFlags = TME_LEAVE | TME_HOVER;
        tme.dwHoverTime = 1;//光标停在按钮上,改变状态的时间,以1毫秒为单位
        m_bTracking = _TrackMouseEvent(&tme);
    }    
    CButton::OnMouseMove(nFlags, point);

}


void CToolBarButten::OnMouseLeave()
{
    // TODO:  在此添加消息处理程序代码和/或调用默认值
    m_bOver = FALSE; //   鼠标没位于按钮之上     
    m_bTracking = FALSE;           //鼠标离开按钮       
    InvalidateRect(NULL, FALSE);  //让按钮重画

    CButton::OnMouseLeave();
}


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

    m_bOver = TRUE;  //鼠标盘旋在按钮上空
    InvalidateRect(NULL); //重画!

    CButton::OnMouseHover(nFlags, point);
}



void CToolBarButten::SetBitmapId(int nNormal,int nOver, int nPressed, int nFocus)
{
    m_NormalBitmap.LoadBitmap(nNormal);
    m_PressedBitmap.LoadBitmap(nPressed);
    m_FocusBitmap.LoadBitmap(nFocus);
    m_OverBitmap.LoadBitmap(nOver);

}



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

    CButton::PreSubclassWindow();
    ModifyStyle(0, BS_OWNERDRAW);
}

void CToolBarButten::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{

        CRect rect = lpDrawItemStruct->rcItem;
        CDC *pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
        int nSaveDC = pDC->SaveDC();
        UINT state = lpDrawItemStruct->itemState;
    
    
        //鼠标停留按钮的状态
        if (m_bOver)
        {
            CDC MemDC;
            MemDC.CreateCompatibleDC(pDC);
            BITMAP  bitmap;
            m_OverBitmap.GetBitmap(&bitmap);
            CBitmap  *pbmpm_old = MemDC.SelectObject(&m_OverBitmap);
            pDC->SetStretchBltMode(COLORONCOLOR);//防止bmp图片失真  
            pDC->StretchBlt(0, 0, rect.Width(), rect.Height(), &MemDC, 0, 0, bitmap.bmWidth, bitmap.bmHeight, SRCCOPY); 
        }
    
        else
        {      
            CDC MemDC;
            MemDC.CreateCompatibleDC(pDC);
            BITMAP  bitmap;
            m_NormalBitmap.GetBitmap(&bitmap);
            CBitmap  *pbmpm_old = MemDC.SelectObject(&m_NormalBitmap);
            pDC->SetStretchBltMode(COLORONCOLOR);//防止bmp图片失真  
            pDC->StretchBlt(0, 0, rect.Width(), rect.Height(), &MemDC, 0, 0, bitmap.bmWidth, bitmap.bmHeight, SRCCOPY);
        }
    
        //按钮被按下(选中)
        if (state & ODS_SELECTED)
        {     
            CDC MemDC;
            MemDC.CreateCompatibleDC(pDC);
            BITMAP  bitmap;
            m_PressedBitmap.GetBitmap(&bitmap);
            CBitmap  *pbmpm_old = MemDC.SelectObject(&m_PressedBitmap);
            pDC->SetStretchBltMode(COLORONCOLOR);//防止bmp图片失真  
            pDC->StretchBlt(0, 0, rect.Width(), rect.Height(), &MemDC, 0, 0, bitmap.bmWidth, bitmap.bmHeight, SRCCOPY);
        }
}

第二种实现

#include "stdafx.h" 
#include "ThreeStateBitmapButton.h" 

IMPLEMENT_DYNAMIC(CThreeStateBitmapButton, CBitmapButton)

CThreeStateBitmapButton::CThreeStateBitmapButton()
:m_bTracked(FALSE)
{
}

BOOL CThreeStateBitmapButton::LoadListBitmap(UINT nIDBitmapResource, UINT nBitmapContainCount)
{
    // delete old bitmaps (if present) 
    m_bitmap.DeleteObject();
    m_bitmapSel.DeleteObject();
    m_bitmapFocus.DeleteObject();
    m_bitmapDisabled.DeleteObject();

    if (nBitmapContainCount < 1)
    {
        TRACE(traceAppMsg, 0, "Failed to load bitmap.
");
        return FALSE;
    }

    CBitmap bmpSrc;
    if (!bmpSrc.LoadBitmap(nIDBitmapResource))
    {
        TRACE(traceAppMsg, 0, "Failed to load bitmap.
");
        return FALSE;   // need this one image 
    }
    BITMAP bmpInfo;
    bmpSrc.GetBitmap(&bmpInfo);

    CClientDC dc(this);
    CDC dcSrc, dcDest;
    dcSrc.CreateCompatibleDC(&dc);
    CBitmap *pOldBmpSrc = dcSrc.SelectObject(&bmpSrc);

    int nWidth = bmpInfo.bmWidth / nBitmapContainCount;
    int nHeight = bmpInfo.bmHeight;
    dcDest.CreateCompatibleDC(&dc);
    m_bitmap.CreateCompatibleBitmap(&dcSrc, nWidth, nHeight);
    CBitmap *pOldBmpDest = dcDest.SelectObject(&m_bitmap);
    dcDest.BitBlt(0, 0, nWidth, nHeight, &dcSrc, 0, 0, SRCCOPY);
    dcDest.SelectObject(pOldBmpDest);

    if (nBitmapContainCount > 1)
    {
        m_bitmapSel.CreateCompatibleBitmap(&dcSrc, nWidth, nHeight);
        pOldBmpDest = dcDest.SelectObject(&m_bitmapSel);
        dcDest.BitBlt(0, 0, nWidth, nHeight, &dcSrc, nWidth, 0, SRCCOPY);
        dcDest.SelectObject(pOldBmpDest);
    }
    if (nBitmapContainCount > 2)
    {
        m_bitmapFocus.CreateCompatibleBitmap(&dcSrc, nWidth, nHeight);
        pOldBmpDest = dcDest.SelectObject(&m_bitmapFocus);
        dcDest.BitBlt(0, 0, nWidth, nHeight, &dcSrc, nWidth * 2, 0, SRCCOPY);
        dcDest.SelectObject(pOldBmpDest);
    }
    if (nBitmapContainCount > 3)
    {
        m_bitmapDisabled.CreateCompatibleBitmap(&dcSrc, nWidth, nHeight);
        pOldBmpDest = dcDest.SelectObject(&m_bitmapDisabled);
        dcDest.BitBlt(0, 0, nWidth, nHeight, &dcSrc, nWidth * 3, 0, SRCCOPY);
        dcDest.SelectObject(pOldBmpDest);
    }
    dcSrc.SelectObject(pOldBmpSrc);
    return TRUE;
}

BEGIN_MESSAGE_MAP(CThreeStateBitmapButton, CBitmapButton)
    ON_WM_MOUSEMOVE()
    ON_WM_MOUSELEAVE()
END_MESSAGE_MAP()

void CThreeStateBitmapButton::DrawItem(LPDRAWITEMSTRUCT lpDIS)
{
    ASSERT(lpDIS != NULL);
    // must have at least the first bitmap loaded before calling DrawItem 
    ASSERT(m_bitmap.m_hObject != NULL);     // required 

    // use the main bitmap for up, the selected bitmap for down 
    CBitmap* pBitmap = &m_bitmap;
    UINT state = lpDIS->itemState;
    if ((state & ODS_SELECTED) && m_bitmapSel.m_hObject != NULL)
        pBitmap = &m_bitmapSel;
    //else if ((state & ODS_FOCUS) && m_bitmapFocus.m_hObject != NULL) 
    //pBitmap = &m_bitmapFocus;   // third image for focused 
    else if ((state & ODS_DISABLED) && m_bitmapDisabled.m_hObject != NULL)
        pBitmap = &m_bitmapDisabled;   // last image for disabled 
    else if (m_bTracked && m_bitmapFocus.m_hObject != NULL)
        pBitmap = &m_bitmapFocus;   // third image for focused 

    // draw the whole button 
    CDC* pDC = CDC::FromHandle(lpDIS->hDC);
    CDC memDC;
    memDC.CreateCompatibleDC(pDC);
    CBitmap* pOld = memDC.SelectObject(pBitmap);
    if (pOld == NULL)
        return;     // destructors will clean up 

    CRect rect;
    rect.CopyRect(&lpDIS->rcItem);
    pDC->BitBlt(rect.left, rect.top, rect.Width(), rect.Height(),
        &memDC, 0, 0, SRCCOPY);
    memDC.SelectObject(pOld);
}

void CThreeStateBitmapButton::OnMouseMove(UINT nFlags, CPoint point)
{
    if (!m_bTracked)
    {
        TRACKMOUSEEVENT tme;
        tme.cbSize = sizeof(tme);
        tme.dwFlags = TME_LEAVE;
        tme.dwHoverTime = 0;
        tme.hwndTrack = m_hWnd;
        TrackMouseEvent(&tme);

        m_bTracked = TRUE;
        Invalidate(FALSE);
    }
    CBitmapButton::OnMouseMove(nFlags, point);
}

void CThreeStateBitmapButton::OnMouseLeave()
{
    m_bTracked = FALSE;
    Invalidate(FALSE);

    CBitmapButton::OnMouseLeave();
}

void CThreeStateBitmapButton::PreSubclassWindow()
{
    CBitmapButton::PreSubclassWindow();
    ModifyStyle(0, BS_OWNERDRAW);
}

下载

原文地址:https://www.cnblogs.com/ye-ming/p/8796225.html