//========================================================================
//TITLE:
//    CButton更新至v1.3.3
//AUTHOR:
//    norains
//DATE:
//    Wednesday  09-January-2008
//Environment:
//    VS2005 + SDK-WINCE5.0-MIPSII  
//    EVC + SDK-WINCE5.0-MIPSII 
//========================================================================

    V1.1.1版本地址及相关用法:http://blog.csdn.net/norains/archive/2007/05/21/1619805.aspx
   
   
    相对v1.1.1版本有如下改动:
   
    添加如下函数:
    SetVisible() -- 设置是否可见
    SetImgInfo() -- 设置图片信息
   
    文字显示增加如下函数:
    SetTextStrikeOut(BOOL bStrikeOut);
    SetTextUnderline(BOOL bUnderline);
    SetTextItalic(BOOL bItalic);
    SetTextWeight(int iWeight);
    GetTextPosition(RECT * prcOut);
    SetTextPointSize(int iPointSize);
    SetTextFormat(UINT uFormat);
    SetTextColor(COLORREF crColor);
    SetText(const TCHAR *pszText);
    SetTextPosition(const RECT *prc);
   
    修正SetText()函数当形参为NULL会出现异常的bug.


//////////////////////////////////////////////////////////////////////
// Button.h: interface for the CButton class.
//
//Version: 
//    1.3.3
//Data:
//    2007.11.20  
//////////////////////////////////////////////////////////////////////

#ifndef BUTTON_H
#define BUTTON_H



//---------------------------------------------------------------------------
//Struct data

//The image displayed information
#ifndef _DISPIMAGEINFO
#define _DISPIMAGEINFO
    typedef 
struct
    {
        LONG imgID;
        LONG left;
        LONG top;
        LONG right;
        LONG bottom;
    }DISPIMAGEINFO,
*PDISPIMAGEINFO;
#endif //_DISPIMAGEINFO


#ifndef _BUTTONIMAGEINFO
#define _BUTTONIMAGEINFO
//All the button image information
typedef struct
{
    DISPIMAGEINFO ImgInfoDisable;
    DISPIMAGEINFO ImgInfoEnable;
    DISPIMAGEINFO ImgInfoPush;
}BUTTONIMAGEINFO,
*PBUTTONIMAGEINFO;
#endif //_BUTTONIMAGEINFO
//---------------------------------------------------------------------------
//Enum data

//For the button draw
enum ButtonDrawType
{
    BTN_DRAW_AUTO,
    BTN_DRAW_PUSH,
    BTN_DRAW_ENABLE,
    BTN_DRAW_DISABLE
};

//------------------------------------------------------------------------------
//Class

class CButton  
{
public:        
    CButton
& operator =(const CButton &rhs);

    
//For the image
    void SetImgPosition(const RECT * pRc);
    
void GetImgPosition(RECT *prcOut);
    
void SetImgInfo(const BUTTONIMAGEINFO *pImgInfo);
    
void SetImgInfoPush(const DISPIMAGEINFO *pImgInfo);
    
void SetImgInfoDisable(const DISPIMAGEINFO *pImgInfo);
    
void SetImgInfoEnable(const DISPIMAGEINFO *pImgInfo);

    
//For the text
    void SetTextStrikeOut(BOOL bStrikeOut);
    
void SetTextUnderline(BOOL bUnderline);
    
void SetTextItalic(BOOL bItalic);
    BOOL SetTextWeight(
int iWeight);
    
void GetTextPosition(RECT * prcOut);
    
void SetTextPointSize(int iPointSize);
    
void SetTextFormat(UINT uFormat);
    
void SetTextColor(COLORREF crColor);
    BOOL SetText(
const TCHAR *pszText);
    
void SetTextPosition(const RECT *prc);
    
    
void SetVisible(BOOL bVisible);
    
void SetTransparent(BOOL bTran);
    
void SetTransparentColor(COLORREF crColor);
    
void SetHinstance(HINSTANCE hInst);
    BOOL Draw(HDC hdc, ButtonDrawType btnDraw 
= BTN_DRAW_AUTO);    
    
void SetEnable(BOOL bEnable);
    BOOL GetEnable();
    BOOL CheckTap(
const LPPOINT ppt);

    

    CButton();
    CButton(
const DISPIMAGEINFO *pImgDisable,const DISPIMAGEINFO *pImgEnable,const DISPIMAGEINFO *pImgPush,const TCHAR *pcszText);
    
virtual ~CButton();


protected:
    BOOL Draw(HDC hdc, ButtonDrawType btnDraw,RECT 
*prcImg,RECT *prcText);


private:
    BOOL m_bEnable;
    RECT m_rcWndImg;
    DISPIMAGEINFO m_ImgPush;
    DISPIMAGEINFO m_ImgEnable;
    DISPIMAGEINFO m_ImgDisable;
    HANDLE m_hBmpPush;
    HANDLE m_hBmpEnable;
    HANDLE m_hBmpDisable;
    HINSTANCE m_hInst;
    COLORREF m_crTranColor;
    BOOL m_bTran;
    BOOL m_bVisible;

    RECT m_rcWndText;    
    TCHAR 
*m_pszText;
    ULONG m_ulSizeText;
    UINT m_uFormat;
    
int m_iPointSize;
    COLORREF m_crTextColor;
    
int m_iWeight;
    BOOL m_bItalic;
    BOOL m_bUnderline;
    BOOL m_bStrikeOut;


};

#endif // #ifndef BUTTON_H

 



//////////////////////////////////////////////////////////////////////
// Button.cpp: implementation of the CButton class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Button.h"


//-------------------------------------------------------------------
//Macro define
#define DEFAULT_TRANSPARENT_COLOR    RGB(125,125,125)
#define DEFAULT_TEXT_COLOR        RGB(0,0,0)
#define DEFAULT_FORMAT            (DT_LEFT | DT_SINGLELINE)
#define DEFAULT_POINT_SIZE        0
#define DEFAULT_WEIGHT            0

#define MAX_WEIGHT                1000
#define MIN_WEIGHT                0
//--------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CButton::CButton():
m_bEnable(TRUE),
m_hBmpPush(NULL),
m_hBmpEnable(NULL),
m_hBmpDisable(NULL),
m_hInst(NULL),
m_crTranColor(DEFAULT_TRANSPARENT_COLOR),
m_bTran(FALSE),
m_bVisible(TRUE),
m_pszText(NULL),
m_ulSizeText(0),
m_crTextColor(DEFAULT_TEXT_COLOR),
m_uFormat(DEFAULT_FORMAT),
m_iPointSize(DEFAULT_POINT_SIZE),
m_iWeight(0),
m_bItalic(FALSE),
m_bUnderline(FALSE),
m_bStrikeOut(FALSE)
{   
    memset(&m_rcWndImg,0,sizeof(m_rcWndImg));
    memset(&m_ImgPush,0,sizeof(m_ImgPush));
    memset(&m_ImgEnable,0,sizeof(m_ImgEnable));
    memset(&m_ImgDisable,0,sizeof(m_ImgDisable));   

}



CButton::CButton(const DISPIMAGEINFO *pImgDisable,
                 const DISPIMAGEINFO *pImgEnable,
                 const DISPIMAGEINFO *pImgPush,
                 const TCHAR *pcszText):
m_bEnable(TRUE),
m_hBmpPush(NULL),
m_hBmpEnable(NULL),
m_hBmpDisable(NULL),
m_hInst(NULL),
m_crTranColor(DEFAULT_TRANSPARENT_COLOR),
m_bTran(FALSE),
m_bVisible(TRUE),
m_pszText(NULL),
m_ulSizeText(0),
m_crTextColor(DEFAULT_TEXT_COLOR),
m_uFormat(DEFAULT_FORMAT),
m_iPointSize(DEFAULT_POINT_SIZE),
m_iWeight(0),
m_bItalic(FALSE),
m_bUnderline(FALSE),
m_bStrikeOut(FALSE)
{
    CButton();

    SetImgInfoDisable(pImgDisable);
    SetImgInfoEnable(pImgEnable);
    SetImgInfoPush(pImgPush);
    SetText(pcszText);
}

CButton::~CButton()
{
    if(m_hBmpPush != NULL)
    {
        DeleteObject(m_hBmpPush);
        m_hBmpPush = NULL;
    }

    if(m_hBmpEnable != NULL)
    {
        DeleteObject(m_hBmpEnable);
        m_hBmpEnable = NULL;
    }

    if(m_hBmpDisable != NULL)
    {
        DeleteObject(m_hBmpDisable);
        m_hBmpDisable = NULL;
    }

    if(m_pszText != NULL)
    {
        delete [] m_pszText;
        m_pszText = NULL;
    }
}


//--------------------------------------------------------------------
//Description:
//    The button is enable or not
//
//-------------------------------------------------------------------
BOOL CButton::GetEnable()
{
    return m_bEnable;
}



//--------------------------------------------------------------------
//Description:
//    Set the button status
//
//-------------------------------------------------------------------
void CButton::SetEnable(BOOL bEnable)
{
    m_bEnable = bEnable;
}


//--------------------------------------------------------------------
//Description:
//    Draw the button
//
//-------------------------------------------------------------------
BOOL CButton::Draw(HDC hdc, ButtonDrawType btnDraw)
{
    return Draw(hdc,btnDraw,&m_rcWndImg,&m_rcWndText);
}


//--------------------------------------------------------------------
//Description:
//    Set the handle of instance
//
//-------------------------------------------------------------------
void CButton::SetHinstance(HINSTANCE hInst)
{
    m_hInst = hInst;
}


//--------------------------------------------------------------------
//Description:
//    Set the image of enable
//
//-------------------------------------------------------------------
void CButton::SetImgInfoEnable(const DISPIMAGEINFO *pImgInfo)
{
    if(m_hBmpEnable != NULL)
    {
        DeleteObject(m_hBmpEnable);
        m_hBmpEnable = NULL;
    }

    m_ImgEnable = *pImgInfo;
}
//--------------------------------------------------------------------
//Description:
//    Set the image of disable
//
//-------------------------------------------------------------------
void CButton::SetImgInfoDisable(const DISPIMAGEINFO *pImgInfo)
{
    if(m_hBmpDisable != NULL)
    {
        DeleteObject(m_hBmpDisable);
        m_hBmpDisable = NULL;
    }

    m_ImgDisable = *pImgInfo;
}
//--------------------------------------------------------------------
//Description:
//    Set the image of push
//
//-------------------------------------------------------------------
void CButton::SetImgInfoPush(const DISPIMAGEINFO *pImgInfo)
{
    if(m_hBmpPush != NULL)
    {
        DeleteObject(m_hBmpPush);
        m_hBmpPush = NULL;
    }

    m_ImgPush = *pImgInfo;
}

//--------------------------------------------------------------------
//Description:
//    Set the button position
//
//-------------------------------------------------------------------
void CButton::SetImgPosition(const RECT *pRc)
{
    m_rcWndImg = *pRc;
}


//--------------------------------------------------------------------
//Description:
//    Check tapped position in the area.If the button is disable,
//it would return FALSE.
//
//-------------------------------------------------------------------
BOOL CButton::CheckTap(const LPPOINT ppt)
{
    if(m_bEnable == FALSE || m_bVisible == FALSE)
    {
        return FALSE;
    }

    if( ppt->x >= m_rcWndImg.left && ppt->x <= m_rcWndImg.right && ppt->y >= m_rcWndImg.top && ppt->y <= m_rcWndImg.bottom)
    {
        return TRUE;
    }
    else
    {
        return FALSE;
    }

}

//--------------------------------------------------------------------
//Description:
//    Get the position as rect
//
//---------------------------------------------------------------------
void CButton::GetImgPosition(RECT *prcOut)
{
    *prcOut = m_rcWndImg;
}


//--------------------------------------------------------------------
//Description:
//    Set the transparent color
//
//-------------------------------------------------------------------
void CButton::SetTransparentColor(COLORREF crColor)
{
    m_crTranColor = crColor;
}
//--------------------------------------------------------------------
//Description:
//    Set the transparent mode
//
//Parameters:
//    bTran:[in]
//        TRUE  - Don't draw the transparent color
//        FALSE - Draw all the color
//
//-------------------------------------------------------------------
void CButton::SetTransparent(BOOL bTran)
{
    m_bTran = bTran;
}


//--------------------------------------------------------------------
//Description:
//    Set the visible
//
//Parameters:
//    bVisible:[in]
//        TRUE - visible
//        FALSE - invisible
//
//--------------------------------------------------------------------
void CButton::SetVisible(BOOL bVisible)
{
    m_bVisible = bVisible;
}

//--------------------------------------------------------------------
//Description:
//    Set the button image
//
//-------------------------------------------------------------------
void CButton::SetImgInfo(const BUTTONIMAGEINFO *pImgInfo)
{
    SetImgInfoDisable(&pImgInfo->ImgInfoDisable);
    SetImgInfoEnable(&pImgInfo->ImgInfoEnable);
    SetImgInfoPush(&pImgInfo->ImgInfoPush);
}






//--------------------------------------------------------------------
//Description:
//    Set the control position
//
//--------------------------------------------------------------------
void CButton::SetTextPosition(const RECT *prc)
{
    m_rcWndText = *prc;
}


//--------------------------------------------------------------------
//Description:
//    Set the text. If you want to display the text ,you should call the Display()
//
//--------------------------------------------------------------------
BOOL CButton::SetText(const TCHAR *pszText)
{
    ULONG ulLen = 0;

    if(pszText != NULL)
    {
        ulLen = _tcslen(pszText);
    }

    if(m_pszText == NULL)
    {       
        m_pszText = new TCHAR [ulLen + 1];
       
        if(m_pszText == NULL)
        {
            return FALSE;
        }

        m_ulSizeText = ulLen + 1;
    }
    else if(ulLen + 1 > m_ulSizeText)
    {
        delete [] m_pszText;

        m_pszText = new TCHAR [ulLen + 1];
       
        if(m_pszText == NULL)
        {
            return FALSE;
        }

        m_ulSizeText = ulLen + 1;
    }

    if(pszText != NULL)
    {
        _tcscpy(m_pszText,pszText);
    }
    else
    {
        m_pszText[0] = '/0';
    }

    return TRUE;
}




//--------------------------------------------------------------------
//Description:
//    Set the text color
//
//--------------------------------------------------------------------
void CButton::SetTextColor(COLORREF crColor)
{
    m_crTextColor = crColor;
}



//--------------------------------------------------------------------
//Description:
//    Set Format.
//
//Parameters:
//    The value you should see the uFormat of DrawText()
//--------------------------------------------------------------------
void CButton::SetTextFormat(UINT uFormat)
{
    m_uFormat = uFormat;
}


//--------------------------------------------------------------------
//Description:
//    Set the point size of text
//
//---------------------------------------------------------------------
void CButton::SetTextPointSize(int iPointSize)
{
    m_iPointSize = iPointSize;
}


//--------------------------------------------------------------------
//Description:
//    Get the position as rect
//
//---------------------------------------------------------------------
void CButton::GetTextPosition(RECT *prcOut)
{
    *prcOut = m_rcWndText;
}


//--------------------------------------------------------------------
//Description:
//    Specifies the weight of the font in the range 0 through 1000. For example,
//400 is normal and 700 is bold. If this value is zero, a default weight is used.
//
//---------------------------------------------------------------------
BOOL CButton::SetTextWeight(int iWeight)
{
    if(iWeight < MIN_WEIGHT || iWeight > MAX_WEIGHT)
    {
        return FALSE;
    }

    m_iWeight = iWeight;

    return TRUE;
}



//--------------------------------------------------------------------
//Description:
//    Set the italic
//
//---------------------------------------------------------------------
void CButton::SetTextItalic(BOOL bItalic)
{
    m_bItalic = bItalic;
}



//--------------------------------------------------------------------
//Description:
//    Set the underline
//
//---------------------------------------------------------------------
void CButton::SetTextUnderline(BOOL bUnderline)
{
    m_bUnderline = bUnderline;
}


//--------------------------------------------------------------------
//Description:
//    Set the strikeOut
//
//---------------------------------------------------------------------
void CButton::SetTextStrikeOut(BOOL bStrikeOut)
{
    m_bStrikeOut = bStrikeOut;
}



//--------------------------------------------------------------------
//Description:
//    Overload the operator "="
//
//---------------------------------------------------------------------
CButton& CButton::operator =(const CButton &rhs)
{
    if(this == &rhs)
    {
        return *this;
    }


    this->m_bEnable = rhs.m_bEnable;
    this->m_rcWndImg = rhs.m_rcWndImg;
    this->m_ImgPush = rhs.m_ImgPush;
    this->m_ImgEnable = rhs.m_ImgEnable;
    this->m_ImgDisable = rhs.m_ImgDisable;
    if(m_hBmpPush != NULL)
    {
        DeleteObject(m_hBmpPush);
        //Don't set the value
        m_hBmpPush = NULL;
    }
    if(m_hBmpEnable != NULL)
    {
        DeleteObject(m_hBmpEnable);
        //Don't set the value
        m_hBmpEnable = NULL;
    }
    if(m_hBmpDisable != NULL)
    {
        DeleteObject(m_hBmpDisable);
        //Don't set the value
        m_hBmpDisable = NULL;
    }
    this->m_hInst = rhs.m_hInst;
    this->m_crTranColor = rhs.m_crTranColor;
    this->m_bTran = rhs.m_bTran;
    this->m_bVisible = rhs.m_bVisible;
    this->m_bItalic = rhs.m_bItalic;
    this->m_bStrikeOut = rhs.m_bStrikeOut;
    this->m_bUnderline = rhs.m_bUnderline;
    this->m_crTextColor = rhs.m_crTextColor;
    this->m_iPointSize = rhs.m_iPointSize;
    this->m_iWeight = rhs.m_iWeight;
    this->m_rcWndText = rhs.m_rcWndText;
    this->m_uFormat = rhs.m_uFormat;
    this->m_ulSizeText = rhs.m_ulSizeText;
    if(this->m_pszText != NULL)
    {
        delete [] this->m_pszText;
        this->m_pszText = NULL;
    }
    if(rhs.m_pszText != NULL)
    {
        this->m_pszText = new TCHAR[_tcslen(rhs.m_pszText) + 1];
        _tcscpy(this->m_pszText,rhs.m_pszText);
    }

   


    return *this;
}



//--------------------------------------------------------------------
//Description:
//    Draw the button
//
//-------------------------------------------------------------------
BOOL CButton::Draw(HDC hdc, ButtonDrawType btnDraw, RECT *prcImg, RECT *prcText)
{
    if(m_bVisible == FALSE)
    {
        return TRUE;
    }

    if(m_hInst == NULL)
    {
        return FALSE;
    }


    //Draw the image
    HANDLE hBmp = NULL;
    PDISPIMAGEINFO pInfo;

    if(btnDraw == BTN_DRAW_AUTO)
    {
        if(m_bEnable == TRUE)
        {
            if(m_hBmpEnable == NULL)
            {
                m_hBmpEnable = LoadImage(m_hInst,MAKEINTRESOURCE(m_ImgEnable.imgID),IMAGE_BITMAP,0,0,0);
            }

            hBmp = m_hBmpEnable;
            pInfo = &m_ImgEnable;
        }
        else
        {
            if(m_hBmpDisable == NULL)
            {
                m_hBmpDisable = LoadImage(m_hInst,MAKEINTRESOURCE(m_ImgDisable.imgID),IMAGE_BITMAP,0,0,0);
            }

            hBmp = m_hBmpDisable;
            pInfo = &m_ImgDisable;
        }
    }
    else if(btnDraw == BTN_DRAW_ENABLE)
    {
        if(m_hBmpEnable == NULL)
        {
            m_hBmpEnable = LoadImage(m_hInst,MAKEINTRESOURCE(m_ImgEnable.imgID),IMAGE_BITMAP,0,0,0);
        }

        hBmp = m_hBmpEnable;
        pInfo = &m_ImgEnable;
    }
    else if(btnDraw == BTN_DRAW_DISABLE)
    {
        if(m_hBmpDisable == NULL)
        {
            m_hBmpDisable = LoadImage(m_hInst,MAKEINTRESOURCE(m_ImgDisable.imgID),IMAGE_BITMAP,0,0,0);
        }

        hBmp = m_hBmpDisable;
        pInfo = &m_ImgDisable;
    }
    else if(btnDraw == BTN_DRAW_PUSH)
    {
        if(m_hBmpPush == NULL)
        {
            m_hBmpPush = LoadImage(m_hInst,MAKEINTRESOURCE(m_ImgPush.imgID),IMAGE_BITMAP,0,0,0);
        }

        hBmp = m_hBmpPush;
        pInfo = &m_ImgPush;
    }


    //Create a DC that matches the device
    HDC hdcMem = CreateCompatibleDC(hdc);
    //Select the bitmap into to the compatible device context
    HGDIOBJ hOldSel = SelectObject(hdcMem,hBmp);
    //Copy the bitmap image from the memory DC to the screen DC
    if(m_bTran == FALSE)
    {
        StretchBlt(hdc,prcImg->left,prcImg->top,(prcImg->right - prcImg->left),(prcImg->bottom - prcImg->top),
            hdcMem,pInfo->left,pInfo->top,(pInfo->right - pInfo->left),(pInfo->bottom - pInfo->top),SRCCOPY);
    }
    else
    {
        TransparentBlt(hdc,prcImg->left,prcImg->top,(prcImg->right - prcImg->left),(prcImg->bottom - prcImg->top),
            hdcMem,pInfo->left,pInfo->top,(pInfo->right - pInfo->left),(pInfo->bottom - pInfo->top),m_crTranColor);
    }
    //Restore original bitmap selection and destroy the memory DC
    SelectObject(hdcMem,hOldSel);   
    DeleteDC(hdcMem);





    //Draw the text
    COLORREF crOldTextColor = ::SetTextColor(hdc,m_crTextColor);
    int iOldMode = ::SetBkMode(hdc,TRANSPARENT);
   
    LOGFONT lf = {0};
    HFONT hFontNew, hFontOld;
    lf.lfQuality = CLEARTYPE_QUALITY;
    lf.lfCharSet = DEFAULT_CHARSET;
    lf.lfHeight = -1 * (m_iPointSize * GetDeviceCaps(hdc,LOGPIXELSY) / 72);
    lf.lfItalic = m_bItalic;
    lf.lfUnderline = m_bUnderline;
    lf.lfStrikeOut = m_bStrikeOut;
    lf.lfWeight = m_iWeight;
   
    hFontNew = CreateFontIndirect(&lf);
    hFontOld = (HFONT) SelectObject(hdc, hFontNew);
   
    DrawText(hdc,m_pszText,-1,prcText,m_uFormat);

    SelectObject(hdc, hFontOld);
    DeleteObject(hFontNew);

    ::SetTextColor(hdc,crOldTextColor);
    ::SetBkMode(hdc,iOldMode);

    return TRUE;
}