四态按钮CMyButton类

来源:互联网 发布:网络不稳定老掉线 编辑:程序博客网 时间:2024/05/21 07:39

 调用方法:

CMyButton m_btnCaption;

CRect rectBtn;
BOOL bRet;
rectBtn.left    =0;
rectBtn.right    =120;
rectBtn.top        =0;
rectBtn.bottom    =40;
bRet=m_btnCaption.Create(NULL,WS_CHILD|WS_VISIBLE|BS_OWNERDRAW ,rectBtn,this,NULL);
m_btnCapiton.SetBitmap(IDB_NORMAL,IDB_HOVER,IDB_DOWN,IDB_DISABLE);

注:Button的Ownerdraw一定要选中

 

Mybutton.h

 

class CMyButton : public CButton
{
// Construction
private:
    enum ButtonStatus{NORMAL,HOVER,DOWN,DIS};
    CBitmap m_bmpNormal, m_bmpHover, m_bmpDown,m_bmpDisable;
    ButtonStatus m_Status, m_PrevStatus;
    char logs[30];
    void SetStatus(ButtonStatus bs);
    CString m_strText;
    CPoint m_pt;
    COLORREF m_crColor;
    BOOL m_bBlink;
public:
    CMyButton();
    void SetBitmap(int nIDNormal,int nIDHorer,int nIDDown);
    void SetBitmap(int nIDNormal,int nIDHorer,int nIDDown,int nIDDisalbe);
    void SetStatu(int intStatu);
    void SetFlash(BOOL bBlink);
    void SetFont(CFont pFont);
    CFont m_fontBtn;
    int m_bFlag;
    bool m_bChCursor;
// Attributes
public:

// Operations
public:

// Overrides
    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CMyButton)
    public:
    virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
    //}}AFX_VIRTUAL

// Implementation
public:
    void SetText(CString strText,CPoint pt,COLORREF crColor);
    void SetText(CString strText,int x,int y,COLORREF crColor);
    void SetBitmap(CString strNormal,CString strHorer,CString strDown);
    void SetText(int iFont,CString strText,int x,int y);
    virtual ~CMyButton();

    // Generated message map functions
protected:
    BOOL IsInRect(CRect &rect, CPoint &point);
    void DrawTransBitmap(HDC hdcDest, //   目标DC  
    int   nXOriginDest,       //   目标X偏移  
    int   nYOriginDest,       //   目标Y偏移  
    int   nWidthDest,           //   目标宽度  
    int   nHeightDest,         //   目标高度  
    HDC   hdcSrc,                   //   源DC  
    int   nXOriginSrc,         //   源X起点  
    int   nYOriginSrc,         //   源Y起点  
    int   nWidthSrc,             //   源宽度  
    int   nHeightSrc,           //   源高度  
    UINT   crTransparent     //   透明色,COLORREF类型  
    );
    //{{AFX_MSG(CMyButton)
    afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
    afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
    afx_msg void OnMouseMove(UINT nFlags, CPoint point);
    afx_msg void OnMouseLeave(WPARAM wParam,LPARAM lParam);
    afx_msg BOOL OnEraseBkgnd(CDC* pDC);
    //}}AFX_MSG

    DECLARE_MESSAGE_MAP()
};

 

 

MyButton.cpp:

// MyButton.cpp : implementation file
//

#include "stdafx.h"
#include "MyButton.h"
#include "winuser.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CMyButton

CMyButton::CMyButton()
{

    m_Status=NORMAL;
    m_strText="";
    m_bFlag=0;
    m_bBlink=FALSE;
    m_bChCursor=FALSE;
    //m_fontBtn.CreateFont(15, 0, 0, 0, FW_BOLD, FALSE, FALSE,0,0,0,0,0,0, "Times New Roman");
}

CMyButton::~CMyButton()
{
}


BEGIN_MESSAGE_MAP(CMyButton, CButton)
    //{{AFX_MSG_MAP(CMyButton)
    ON_WM_LBUTTONDOWN()
    ON_WM_LBUTTONUP()
    ON_WM_MOUSEMOVE()
    ON_MESSAGE(WM_MOUSELEAVE,OnMouseLeave)
    ON_WM_ERASEBKGND()
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMyButton message handlers

void CMyButton::OnLButtonDown(UINT nFlags, CPoint point)
{
    SetStatus(DOWN);
    SetCapture();
    CButton::OnLButtonDown(nFlags, point);
}
BOOL CMyButton::IsInRect(CRect &rect, CPoint &point)
{

    return (point.x >= 0 && point.x <= (rect.right - rect.left) && point.y >= 0 && point.y <= (rect.bottom - rect.top))? TRUE : FALSE;

}
void CMyButton::OnLButtonUp(UINT nFlags, CPoint point)
{
    try
    {
        CRect ButtonRect;

        SetStatus(NORMAL);
        ReleaseCapture();
        Invalidate();
        CButton::OnLButtonUp(nFlags, point);

        GetClientRect(&ButtonRect);
       
        if (m_PrevStatus == DOWN && IsInRect(ButtonRect,point))
            GetParent()->SendMessage(WM_COMMAND,MAKEWPARAM(GetDlgCtrlID(),0),(LPARAM) m_hWnd);
    }
    catch(...)
    {
    }


}

void CMyButton::OnMouseMove(UINT nFlags, CPoint point)
{
    try
    {
    CRect ButtonRect;
    TRACKMOUSEEVENT tme;
    GetWindowRect(&ButtonRect);
    //sprintf(logs,"Button Rect(%d,%d,%d,%d), Mouse Point= (%d,%d)",ButtonRect.left,ButtonRect.right,
    //        ButtonRect.top, ButtonRect.bottom, point.x, point.y);

//    SetCursor()
    if(m_bChCursor)
        SetCursor(LoadCursor(NULL,IDC_ARROW));
//    GetParent()->SetWindowText(logs);

    if (m_Status == DOWN)
    {
        if (IsInRect(ButtonRect,point))
        {
            //SetStatus(DOWN);
        }
        else
        {
            if(m_bFlag==1)m_crColor=(COLORREF)RGB(255,255,255);
            if(m_bFlag==2)m_crColor=(COLORREF)RGB(0,0,0);
            if(m_bFlag==3)m_crColor=(COLORREF)RGB(255,255,255);
            SetStatus(HOVER);
            Invalidate(FALSE);
        }
    }
    else if (m_PrevStatus == DOWN && m_Status == HOVER)
    {
        if(m_bFlag==1)m_crColor=(COLORREF)RGB(0,0,0);
        if(m_bFlag==2)m_crColor=(COLORREF)RGB(0,0,0);
        if(m_bFlag==3)m_crColor=(COLORREF)RGB(255,255,255);
        SetStatus(DOWN);
    }
    else
    {
        if (IsInRect(ButtonRect,point))
        {
            //GetParent()->SetWindowText("END HOVER");
            if(m_bFlag==1)m_crColor=(COLORREF)RGB(0,0,0);
            if(m_bFlag==2)m_crColor=(COLORREF)RGB(0,0,0);
            if(m_bFlag==3)m_crColor=(COLORREF)RGB(255,255,255);
            SetStatus(HOVER);
            Invalidate(FALSE);
        }
        else
        {
            //GetParent()->SetWindowText("END NORMAL");
            if(m_bFlag==1)m_crColor=(COLORREF)RGB(255,255,255);
            if(m_bFlag==2)m_crColor=(COLORREF)RGB(0,0,0);
            if(m_bFlag==3)m_crColor=(COLORREF)RGB(255,255,255);
            SetStatus(NORMAL);
            //Invalidate();
        }

       
    }

   


    CButton::OnMouseMove(nFlags, point);


    tme.cbSize = sizeof(TRACKMOUSEEVENT);
    tme.dwFlags = TME_LEAVE;
    tme.hwndTrack = m_hWnd;

    _TrackMouseEvent(&tme);
    }
    catch(...)
    {
    }
   
}

void CMyButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
    //CButton::DrawItem(lpDrawItemStruct);
    try
    {
    CDC *pthisDC;
    CDC bmpDC;
    CBitmap *pOldBitmap;

    pthisDC = CDC::FromHandle(lpDrawItemStruct->hDC);

    bmpDC.CreateCompatibleDC(pthisDC);
    if (!this->IsWindowEnabled()) //无效状态
    {
        m_Status=DIS;
        m_PrevStatus=DIS;
    }
    else
    {
        if (m_PrevStatus==DIS)
        {
            m_Status=NORMAL;
            m_PrevStatus=NORMAL;
        }
    }
    switch (m_Status)
    {
    case DIS:
        pOldBitmap = bmpDC.SelectObject(&m_bmpDisable);
        break;
    case NORMAL:
        pOldBitmap = bmpDC.SelectObject(&m_bmpNormal);
        //GetParent()->SetWindowText("Normal");
        break;
    case HOVER:
        pOldBitmap = bmpDC.SelectObject(&m_bmpHover);
    //    GetParent()->SetWindowText("Hover");
        break;
    case DOWN:
        pOldBitmap = bmpDC.SelectObject(&m_bmpDown);
    //    GetParent()->SetWindowText("Down");
        break;
    }

    pthisDC->BitBlt(0,0,lpDrawItemStruct->rcItem.right-lpDrawItemStruct->rcItem.left,
        lpDrawItemStruct->rcItem.bottom - lpDrawItemStruct->rcItem.top,&bmpDC,0,0,SRCCOPY);
//     pthisDC->StretchBlt(0,0,lpDrawItemStruct->rcItem.right-lpDrawItemStruct->rcItem.left,
//         lpDrawItemStruct->rcItem.bottom - lpDrawItemStruct->rcItem.top,&bmpDC,0,0,lpDrawItemStruct->rcItem.right-lpDrawItemStruct->rcItem.left,
//         lpDrawItemStruct->rcItem.bottom - lpDrawItemStruct->rcItem.top,SRCCOPY);
    CRect rc;
    rc.left=lpDrawItemStruct->rcItem.left+m_pt.x;
    rc.top=lpDrawItemStruct->rcItem.top+m_pt.y;
    rc.bottom=lpDrawItemStruct->rcItem.bottom;
    rc.right=lpDrawItemStruct->rcItem.right;

    if (m_fontBtn.m_hObject!=NULL)
    {
        pthisDC->SelectObject(&m_fontBtn);
    }
    pthisDC->SetBkMode(TRANSPARENT);
    pthisDC->SetTextColor(m_crColor);
    pthisDC->DrawText(m_strText,&rc,DT_LEFT|DT_VCENTER);
   
    bmpDC.SelectObject(pOldBitmap);
    bmpDC.DeleteDC();
    }
    catch(...)
    {
    }
   
   
}
void CMyButton::SetStatus(ButtonStatus bs)
{

    m_PrevStatus = m_Status;
    m_Status = bs;

}
void CMyButton::OnMouseLeave(WPARAM wParam,LPARAM lParam)
{
    if(m_bFlag==1)m_crColor=(COLORREF)RGB(255,255,255);
    if(m_bFlag==2)m_crColor=(COLORREF)RGB(0,0,0);
    if(m_bFlag==3)m_crColor=(COLORREF)RGB(255,255,255);
    if(m_bChCursor) SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
    SetStatus(NORMAL);
    Invalidate();
}
void CMyButton::SetBitmap(int nIDNormal, int nIDHorer, int nIDDown)
{
    try
    {
        m_bmpNormal.DeleteObject();
        m_bmpHover.DeleteObject();
        m_bmpDown.DeleteObject();
        m_bmpNormal.LoadBitmap(nIDNormal);
        m_bmpHover.LoadBitmap(nIDHorer);
        m_bmpDown.LoadBitmap(nIDDown);
        if(m_bFlag==1)m_crColor=(COLORREF)RGB(255,255,255);
        if(m_bFlag==2)m_crColor=(COLORREF)RGB(0,0,0);
        if(m_bFlag==3)m_crColor=(COLORREF)RGB(255,255,255);
        Invalidate();
    }
    catch(...)
    {
    }
}
void CMyButton::SetBitmap(int nIDNormal, int nIDHorer, int nIDDown,int nIDDisable)
{
    try
    {
        m_bmpNormal.DeleteObject();
        m_bmpHover.DeleteObject();
        m_bmpDown.DeleteObject();
        m_bmpDisable.DeleteObject();
        m_bmpNormal.LoadBitmap(nIDNormal);
        m_bmpHover.LoadBitmap(nIDHorer);
        m_bmpDown.LoadBitmap(nIDDown);
        m_bmpDisable.LoadBitmap(nIDDisable);
        if(m_bFlag==1)m_crColor=(COLORREF)RGB(255,255,255);
        if(m_bFlag==2)m_crColor=(COLORREF)RGB(0,0,0);
        if(m_bFlag==3)m_crColor=(COLORREF)RGB(255,255,255);
        Invalidate();
    }
    catch(...)
    {
    }
}
void CMyButton::SetStatu(int intStatu)
{
    switch(intStatu)
    {
        case 1:
            SetStatus(NORMAL);
            break;
        case 2:
            SetStatus(HOVER);
            break;
        case 3:
            SetStatus(DOWN);
        case 4:
            SetStatus(DIS);
            break;
    }
    Invalidate();
}
void CMyButton::SetFlash(BOOL bBlink)
{
    try
    {
        if(bBlink)
        {
            m_bBlink=!m_bBlink;
            if(m_bBlink)
                SetStatus(DOWN);
            else
                SetStatus(NORMAL);
        }
        else
        {   
            m_bBlink=0;
            SetStatus(NORMAL);
        }
            Invalidate();
    }
    catch(...)
    {
    }

}
void CMyButton::SetFont(CFont pFont)
{
    m_fontBtn.Attach(pFont);
}
BOOL CMyButton::OnEraseBkgnd(CDC* pDC)
{
    // TODO: Add your message handler code here and/or call default
    return true;
    //return CButton::OnEraseBkgnd(pDC);
}

void CMyButton::SetBitmap(CString strNormal, CString strHorer, CString strDown)
{
    try
    {
        m_bmpNormal.DeleteObject();
        m_bmpHover.DeleteObject();
        m_bmpDown.DeleteObject();


        HBITMAP hBitmap;
        hBitmap=(HBITMAP)::LoadImage(NULL,strNormal,IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_CREATEDIBSECTION);
        m_bmpNormal.Attach(hBitmap);
        hBitmap=(HBITMAP)::LoadImage(NULL,strHorer,IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_CREATEDIBSECTION);
        m_bmpHover.Attach(hBitmap);
        hBitmap=(HBITMAP)::LoadImage(NULL,strDown,IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_CREATEDIBSECTION);
        m_bmpDown.Attach(hBitmap);
        if(m_bFlag==1)m_crColor=(COLORREF)RGB(255,255,255);
        if(m_bFlag==2)m_crColor=(COLORREF)RGB(0,0,0);
        if(m_bFlag==3)m_crColor=(COLORREF)RGB(255,255,255);
        Invalidate();
    }
    catch(...)
    {
    }
}

void CMyButton::SetText(CString strText,CPoint pt,COLORREF crColor)
{
    try
    {
        m_strText=strText;
        m_pt.x=pt.x;
        m_pt.y=pt.y;
        m_crColor=crColor;
    }
    catch(...)
    {
    }
}
void CMyButton::SetText(CString strText,int x,int y,COLORREF crColor)
{
    try
    {
        m_strText=strText;
        m_pt.x=x;
        m_pt.y=y;
        m_crColor=crColor;
    }
    catch(...)
    {
    }
}
void CMyButton::SetText(int iFont,CString strText,int x,int y)
{
    try
    {
        int iLength=0;
        m_fontBtn.DeleteObject();
        m_fontBtn.CreateFont(iFont, 0, 0, 0, FW_BOLD, FALSE, FALSE,0,0,0,0,0,0, "Tahoma");
       
        m_strText=strText;
        iLength=strText.GetLength();
        if(iFont>15&&iLength<10)
        {
            m_pt.x=(10-iLength)/2*7;
            m_pt.y=4;
        }
        else
        {
            m_pt.x=x;
            m_pt.y=y;
        }
        m_crColor=RGB(255,255,255);
        m_bFlag=3;
    }
    catch(...)
    {
    }
}
void CMyButton::DrawTransBitmap(HDC   hdcDest, //   目标DC  
    int   nXOriginDest,       //   目标X偏移  
    int   nYOriginDest,       //   目标Y偏移  
    int   nWidthDest,           //   目标宽度  
    int   nHeightDest,         //   目标高度  
    HDC   hdcSrc,                   //   源DC  
    int   nXOriginSrc,         //   源X起点  
    int   nYOriginSrc,         //   源Y起点  
    int   nWidthSrc,             //   源宽度  
    int   nHeightSrc,           //   源高度  
    UINT   crTransparent     //   透明色,COLORREF类型  
    )  
  {  
  HBITMAP   hOldImageBMP,   hImageBMP   =   CreateCompatibleBitmap(hdcDest,   nWidthDest,   nHeightDest); //   创建兼容位图  
  HBITMAP   hOldMaskBMP,   hMaskBMP   =   CreateBitmap(nWidthDest,   nHeightDest,   1,   1,   NULL); //   创建单色掩码位图  
  HDC hImageDC   =   CreateCompatibleDC(hdcDest);  
  HDC hMaskDC   =   CreateCompatibleDC(hdcDest);  
  hOldImageBMP   =   (HBITMAP)SelectObject(hImageDC,   hImageBMP);  
  hOldMaskBMP   =   (HBITMAP)SelectObject(hMaskDC,   hMaskBMP);  
   
  //   将源DC中的位图拷贝到临时DC中  
  if(nWidthDest==nWidthSrc&&nHeightDest==nHeightSrc)  
        BitBlt(hImageDC, 0, 0, nWidthDest,nHeightDest,hdcSrc,nXOriginSrc,nYOriginSrc,SRCCOPY);  
  else  
        StretchBlt(hImageDC,   0,   0,   nWidthDest,   nHeightDest,  hdcSrc,   nXOriginSrc,   nYOriginSrc,   nWidthSrc,   nHeightSrc,   SRCCOPY);  
   //   设置透明色  
  SetBkColor(hImageDC,   crTransparent);  
  //   生成透明区域为白色,其它区域为黑色的掩码位图  
  BitBlt(hMaskDC,   0,   0,   nWidthDest,   nHeightDest,   hImageDC,   0,   0,   SRCCOPY);  
   //   生成透明区域为黑色,其它区域保持不变的位图  
  SetBkColor(hImageDC,   RGB(0,0,0));  
  SetTextColor(hImageDC,   RGB(255,255,255));  
  BitBlt(hImageDC,   0,   0,   nWidthDest,   nHeightDest,   hMaskDC,   0,   0,   SRCAND);  
   
  //   透明部分保持屏幕不变,其它部分变成黑色  
  SetBkColor(hdcDest,RGB(0xff,0xff,0xff));  
  SetTextColor(hdcDest,RGB(0,0,0));  
  BitBlt(hdcDest,   nXOriginDest,   nYOriginDest,   nWidthDest,   nHeightDest,   hMaskDC,   0,   0,   SRCAND);  
   
  //   "或"运算,生成最终效果  
  BitBlt(hdcDest,   nXOriginDest,   nYOriginDest,   nWidthDest,   nHeightDest,   hImageDC,   0,   0,   SRCPAINT);  
   
  SelectObject(hImageDC,   hOldImageBMP);  
  DeleteDC(hImageDC);  
  SelectObject(hMaskDC,   hOldMaskBMP);  
  DeleteDC(hMaskDC);  
  DeleteObject(hImageBMP);  
  DeleteObject(hMaskBMP);  
  }