⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xskinbutton.cpp

📁 一个在WINCE5.0下开发的MP4播放器,可以播放多种视频文件,画面优质.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "stdafx.h"
#include "xSkinButton.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CxSkinButton
CxSkinButton::CxSkinButton()
{
    m_nDrawMode        = 1;                             // normal drawing mode
    m_nFocusRectMargin = 0;                             // disable focus dotted rect
    m_hClipRgn         = NULL;                          // no clipping region
    m_clrText          = GetSysColor(COLOR_BTNTEXT);    // default button text color
    m_bButtonDown      = FALSE;
    m_bChecked         = FALSE;
}

CxSkinButton::~CxSkinButton()
{
    if (m_hClipRgn)
        DeleteObject(m_hClipRgn);

    DestroyBitmap();
}

void CxSkinButton::DestroyBitmap()
{
    m_bmpNormal.DeleteObject();
    m_bmpDown.DeleteObject();
    m_bmpDisabled.DeleteObject();
    m_bmpMask.DeleteObject();
    m_bmpOver.DeleteObject();
    m_bmpFocus.DeleteObject();
}

/////////////////////////////////////////////////////////////////////////////
BEGIN_MESSAGE_MAP(CxSkinButton, CButton)
//{{AFX_MSG_MAP(CxSkinButton)
    ON_WM_ERASEBKGND()
    ON_WM_LBUTTONDOWN()
    ON_WM_LBUTTONUP()
    ON_WM_MOUSEMOVE()
    ON_WM_LBUTTONDBLCLK()
    ON_WM_KILLFOCUS()
    //ON_CONTROL_REFLECT_EX(BN_CLICKED, OnClicked)
    ON_WM_KEYDOWN()
//}}AFX_MSG_MAP
//    ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)
    ON_MESSAGE(WM_CXSHADE_RADIO , OnRadioInfo)
    ON_MESSAGE(BM_SETCHECK , OnBMSetCheck)
    ON_MESSAGE(BM_GETCHECK , OnBMGetCheck)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CxSkinButton message handlers
/////////////////////////////////////////////////////////////////////////////
void CxSkinButton::PreSubclassWindow() 
{
    //  get specific BS_ styles
    m_nStyle = GetButtonStyle();
    if ((m_nStyle & BS_AUTOCHECKBOX)==BS_AUTOCHECKBOX)
        m_nStyle=BS_CHECKBOX;
    else if ((m_nStyle & BS_AUTORADIOBUTTON)==BS_AUTORADIOBUTTON)
        m_nStyle=BS_RADIOBUTTON;
    else { m_nStyle=BS_PUSHBUTTON; }

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

/////////////////////////////////////////////////////////////////////////////
BOOL CxSkinButton::OnEraseBkgnd(CDC* pDC) 
{
    return TRUE;
}	// doesn't erase the button background

/////////////////////////////////////////////////////////////////////////////
void CxSkinButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) 
{
    ASSERT (lpDrawItemStruct);
    
    //  Check if the button state in not in inconsistent mode...
    POINT mouse_position;
    if ((m_bButtonDown) && (::GetCapture() == m_hWnd) && (::GetCursorPos(&mouse_position)))
    {
        if (::WindowFromPoint(mouse_position) == m_hWnd)
        {
            if ((GetState() & BST_PUSHED) != BST_PUSHED)
            {
                SetState(TRUE);
                return;
            }
        }
        else
        {
            if ((GetState() & BST_PUSHED) == BST_PUSHED)
            {
                SetState(FALSE);
                return;
            }
        }
    }

    CString sCaption = _T("");
    CDC*    pDC = CDC::FromHandle(lpDrawItemStruct->hDC);	// get device context
    RECT    r   = lpDrawItemStruct->rcItem;					// context rectangle
    int     cx  = r.right  - r.left ;						// get width
    int     cy  = r.bottom - r.top  ;						// get height
    // get text box position
    RECT    tr  = {r.left+m_nFocusRectMargin+2,r.top,r.right-m_nFocusRectMargin-2,r.bottom};

    //GetWindowText(sCaption);							// get button text
    pDC->SetBkMode(TRANSPARENT);

    // Select the correct skin 
    if (lpDrawItemStruct->itemState & ODS_DISABLED)
    {
        //  DISABLED BUTTON
        if (m_bmpDisabled.m_hObject == NULL)
            pDC->FillSolidRect(&r,GetSysColor(COLOR_BTNFACE));
        else
            DrawBitmap(pDC, m_bmpDisabled, r, m_nDrawMode);

        // if needed, draw the standard 3D rectangular border
        if (m_bBorder)
            pDC->DrawEdge(&r,EDGE_RAISED,BF_RECT);

        // paint the etched button text
        pDC->SetTextColor(GetSysColor(COLOR_3DHILIGHT));
        pDC->DrawText(sCaption, &tr, DT_SINGLELINE|DT_VCENTER|DT_CENTER);
        pDC->SetTextColor(GetSysColor(COLOR_GRAYTEXT));
        OffsetRect(&tr, -1, -1);
        pDC->DrawText(sCaption, &tr, DT_SINGLELINE|DT_VCENTER|DT_CENTER);
    }
    else
    {
        //  SELECTED (DOWN) BUTTON
        if ((lpDrawItemStruct->itemState & ODS_SELECTED) || m_bChecked)
        {
            if (m_bmpDown.m_hObject == NULL)
                // no skin selected for selected state -> standard button
                pDC->FillSolidRect(&r,GetSysColor(COLOR_BTNFACE));
            else
            {
                //  paint the skin
                DrawBitmap(pDC, m_bmpDown, r, m_nDrawMode);
            }
            OffsetRect(&tr,1,1);  //shift text
            // if needed, draw the standard 3D rectangular border
            if (m_bBorder)
                pDC->DrawEdge(&r,EDGE_SUNKEN,BF_RECT);
        }
        else
        {
            //  DEFAULT BUTTON
            if (m_bmpNormal.m_hObject == NULL)
                pDC->FillSolidRect(&r, GetSysColor(COLOR_BTNFACE));
            else
            {
                if ((lpDrawItemStruct->itemState & ODS_FOCUS) && (m_bmpFocus.m_hObject != NULL))
                {
                    DrawBitmap(pDC, m_bmpFocus, r, m_nDrawMode);
                }
                else
                {
                    DrawBitmap(pDC, m_bmpNormal, r, m_nDrawMode);
                }
            }
            // if needed, draw the standard 3D rectangular border
            if (m_bBorder)
                pDC->DrawEdge(&r, EDGE_RAISED, BF_RECT);
        }

        // paint the focus rect
        if ((lpDrawItemStruct->itemState & ODS_FOCUS)&&(m_nFocusRectMargin > 0))
        {
            r.left   += m_nFocusRectMargin;
            r.top    += m_nFocusRectMargin;
            r.right  -= m_nFocusRectMargin;
            r.bottom -= m_nFocusRectMargin;
            DrawFocusRect(lpDrawItemStruct->hDC, &r);
        }

        //  paint the enabled button text
        pDC->SetTextColor(m_clrText);
        pDC->DrawText(sCaption,&tr,DT_SINGLELINE|DT_VCENTER|DT_CENTER);
    }
}

/////////////////////////////////////////////////////////////////////////////
int CxSkinButton::GetBitmapWidth (HBITMAP hBitmap)
{
    BITMAP bm;
    GetObject(hBitmap,sizeof(BITMAP),(PSTR)&bm);
    return bm.bmWidth;
}

/////////////////////////////////////////////////////////////////////////////
int CxSkinButton::GetBitmapHeight (HBITMAP hBitmap)
{
    BITMAP bm;
    GetObject(hBitmap, sizeof(BITMAP), (PSTR)&bm);
    return bm.bmHeight;
}

/////////////////////////////////////////////////////////////////////////////
void CxSkinButton::DrawBitmap(CDC* dc, HBITMAP hbmp, RECT r, int DrawMode)
{
    //	DrawMode: 0=Normal; 1=stretch; 2=tiled fill
    if (DrawMode == 2)
    {
        FillWithBitmap(dc,hbmp,r);
        return;
    }
    if (!hbmp) return;	//safe check

    int cx=r.right  - r.left;
    int cy=r.bottom - r.top;
    CDC dcBmp,dcMask;
    dcBmp.CreateCompatibleDC(dc);
    dcBmp.SelectObject(hbmp);
    
    if (m_bmpMask.m_hObject != NULL)
    {
        dcMask.CreateCompatibleDC(dc);
        dcMask.SelectObject(m_bmpMask);

        CDC hdcMem;
        hdcMem.CreateCompatibleDC(dc);
        CBitmap hBitmap;
        hBitmap.CreateCompatibleBitmap(dc,cx,cy);
        hdcMem.SelectObject(hBitmap);

        hdcMem.BitBlt(r.left,r.top,cx,cy,dc,0,0,SRCCOPY);
        if (!DrawMode)
        {
            hdcMem.BitBlt(r.left,r.top,cx,cy,&dcBmp,0,0,SRCINVERT);
            hdcMem.BitBlt(r.left,r.top,cx,cy,&dcMask,0,0,SRCAND);
            hdcMem.BitBlt(r.left,r.top,cx,cy,&dcBmp,0,0,SRCINVERT);
        }
        else
        {
            int bx = GetBitmapWidth(hbmp);
            int by = GetBitmapHeight(hbmp);
            hdcMem.StretchBlt(r.left,r.top,cx,cy,&dcBmp,0,0,bx,by,SRCINVERT);
            hdcMem.StretchBlt(r.left,r.top,cx,cy,&dcMask,0,0,bx,by,SRCAND);
            hdcMem.StretchBlt(r.left,r.top,cx,cy,&dcBmp,0,0,bx,by,SRCINVERT);
        }
        dc->BitBlt(r.left,r.top,cx,cy,&hdcMem,0,0,SRCCOPY);

        hdcMem.DeleteDC();
        hBitmap.DeleteObject();

        DeleteDC(dcMask);
    }
    else
    {
        if (!DrawMode)
        {
            dc->BitBlt(r.left,r.top,cx,cy,&dcBmp,0,0,SRCCOPY);
        }
        else
        {
            int bx = GetBitmapWidth(hbmp);
            int by = GetBitmapHeight(hbmp);
            dc->StretchBlt(r.left, r.top, cx, cy, &dcBmp, 0, 0, bx, by, SRCCOPY);
        }
    }
    DeleteDC(dcBmp);
}

/////////////////////////////////////////////////////////////////////////////
void CxSkinButton::FillWithBitmap(CDC* dc, HBITMAP hbmp, RECT r)
{
    if (!hbmp) return;
    CDC memdc;
    memdc.CreateCompatibleDC(dc);
    memdc.SelectObject(hbmp);
    int w = r.right - r.left;
    int	h = r.bottom - r.top;
    int x,y,z;
    int	bx=GetBitmapWidth(hbmp);
    int	by=GetBitmapHeight(hbmp);
    for (y = r.top ; y < h ; y += by)
    {
        if ((y + by) > h) by = h - y;
        z = bx;
        for (x = r.left ; x < w ; x += z)
        {
            if ((x + z) > w) z = w - x;
            dc->BitBlt(x, y, z, by, &memdc, 0, 0, SRCCOPY);
        }
    }
    DeleteDC(memdc);
}

void CxSkinButton::SetSkin(LPCTSTR normal, LPCTSTR down, LPCTSTR over, LPCTSTR disabled,
                 LPCTSTR focus, LPCTSTR mask, short drawmode, short border, short margin)
{
    DestroyBitmap();

    if (normal != NULL)
    {
        m_bmpNormal.LoadBitmapEx(normal);
        if (m_bmpNormal.m_hObject != NULL)
        {
            SetWindowPos(NULL, 0, 0, GetBitmapWidth(m_bmpNormal), GetBitmapHeight(m_bmpNormal), SWP_NOREPOSITION);
        }
    }
    if (down != NULL)
        m_bmpDown.LoadBitmapEx(down);
    if (over != NULL)
        m_bmpOver.LoadBitmapEx(over);
    if (focus != NULL)
        m_bmpFocus.LoadBitmapEx(focus);
    
    if (disabled != NULL)
        m_bmpDisabled.LoadBitmapEx(disabled);
    else if (normal != NULL)
        m_bmpDisabled.LoadBitmapEx(normal);
    
    m_nDrawMode        = max(0, min(drawmode,2));
    m_bBorder          = border;
    m_nFocusRectMargin = max(0,margin);
    
    if (mask > 0)
    {
        m_bmpMask.LoadBitmap(mask);
        if (m_hClipRgn)
            DeleteObject(m_hClipRgn);
        m_hClipRgn = CreateRgnFromBitmap(m_bmpMask,RGB(255,255,255));
        if (m_hClipRgn)
        {
            SetWindowRgn(m_hClipRgn, TRUE);
            SelectClipRgn((HDC)GetDC(),m_hClipRgn);
        }
        if (m_nDrawMode == 0)
        {
            SetWindowPos(NULL,0,0,GetBitmapWidth(m_bmpMask), GetBitmapHeight(m_bmpMask),SWP_NOZORDER|SWP_NOMOVE);
        }
    }
}

/////////////////////////////////////////////////////////////////////////////
void CxSkinButton::SetSkin(UINT normal, UINT down, UINT over, UINT disabled, UINT focus,
        UINT mask, short drawmode, short border, short margin)
{
    DestroyBitmap();

    if (normal > 0)
    {
        m_bmpNormal.LoadBitmap(normal);
        if (m_bmpNormal.m_hObject != NULL)
        {
            SetWindowPos(NULL, 0, 0, GetBitmapWidth(m_bmpNormal), GetBitmapHeight(m_bmpNormal), SWP_NOREPOSITION);
        }
    }
    if (down > 0)   m_bmpDown.LoadBitmap(down);
    if (over > 0)   m_bmpOver.LoadBitmap(over);
    if (focus > 0)  m_bmpFocus.LoadBitmap(focus);

    if (disabled > 0)    m_bmpDisabled.LoadBitmap(disabled);
    else if (normal > 0) m_bmpDisabled.LoadBitmap(normal);

    m_nDrawMode        = max(0, min(drawmode,2));
    m_bBorder          = border;
    m_nFocusRectMargin = max(0,margin);

    if (mask > 0)
    {
        m_bmpMask.LoadBitmap(mask);
        if (m_hClipRgn)
            DeleteObject(m_hClipRgn);
        m_hClipRgn = CreateRgnFromBitmap(m_bmpMask,RGB(255,255,255));
        if (m_hClipRgn)
        {
            SetWindowRgn(m_hClipRgn, TRUE);
            SelectClipRgn((HDC)GetDC(),m_hClipRgn);
        }
        if (m_nDrawMode == 0)
        {
            SetWindowPos(NULL,0,0,GetBitmapWidth(m_bmpMask), GetBitmapHeight(m_bmpMask),SWP_NOZORDER|SWP_NOMOVE);
        }
    }
}
/////////////////////////////////////////////////////////////////////////////
HRGN CxSkinButton::CreateRgnFromBitmap(HBITMAP hBmp, COLORREF color)
{
    if (!hBmp) return NULL;

    BITMAP bm;
    GetObject( hBmp, sizeof(BITMAP), &bm );	// get bitmap attributes

    CDC dcBmp;
    dcBmp.CreateCompatibleDC(GetDC());	//Creates a memory device context for the bitmap
    dcBmp.SelectObject(hBmp);			//selects the bitmap in the device context

    const DWORD RDHDR = sizeof(RGNDATAHEADER);
    const DWORD MAXBUF = 40;		// size of one block in RECTs
    LPRECT  pRects;								
    DWORD   cBlocks = 0;			// number of allocated blocks
    INT     i, j;					// current position in mask image
    INT     first = 0;				// left position of current scan line
    // where mask was found
    bool	wasfirst = FALSE;		// set when if mask was found in current scan line
    bool	ismask;					// set when current color is mask color
    
    // allocate memory for region data

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -