//头文件
//CGWBButton.h
#if !defined(AFX_WBBUTTON_H__518122CF_358F_11D4_8F4F_00402656D980__INCLUDED_)
#define AFX_WBBUTTON_H__518122CF_358F_11D4_8F4F_00402656D980__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
class CAutoFont;
#define SAFE_DELETE(p) { if(p) { delete (p); (p)=NULL; } }
class CGWBButton : public CButton
{
typedef enum mode
{
NORMAL ,
HOVER ,
DOWN ,
DISABLE
}stateBtn;
enum state
{
notInited = 0,
FileLoaded = 1,
BitmapInited = 2
};
public:
CGWBButton();
/*
功能:为按钮加载背景图片,支持透明,各个状态的图标在一张图上
参数:strPath本地图片路径,
count图片中包含的图标的个数,
nWidth每个图标的宽度,
nHeight每个图标的高度,
bSizeChange是否改变图标大小适应控件
*/
bool LoadImg( CString strPath,int count,int nWidth,int nHeight,int nInterval,BOOL bMouseMove = FALSE,bool bSizeChange = true);
/*
功能:为按钮加载背景图片,支持透明,各个状态的图标不在一张图上
参数:strPath本地图片Normal状态路径,
strPath本地图片Normal状态路径,
strPath本地图片Normal状态路径,
strPath本地图片Normal状态路径,
bSizeChange是否改变图标大小适应控件
*/
bool LoadImg(CString strNormal,CString strHover,CString strDown,CString strDisable,BOOL bMouseMove = FALSE,bool bSizeChange = true);
void SetButtonDef( int TopHeight, int BottomHeight, int LeftWidth, int RightWidth );
void SetBackColor( COLORREF color ) { m_BkColor = color; }
COLORREF GetBackColor() { return m_BkColor; }
void SetTextFont( CFont & fnt );
void SetTextFont( CAutoFont & fnt );
CFont * GetTextFont() { return (CFont *)m_pFnt; }
CAutoFont * GetTextAutoFont() { return m_pFnt; }
void SetFontColor( COLORREF color );
void SetBackImage(CString strPath);//设置背景图片
virtual ~CGWBButton();
protected:
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
DECLARE_MESSAGE_MAP()
private:
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
private:
int m_State;
stateBtn m_state;
void DrawBitmap( CDC * pDC, int mode );
UINT m_RcId; // Resource ID
int m_NumofPics;
Bitmap* m_pNormalBitmap;
Bitmap* m_pHoverBitmap;
Bitmap* m_pDownBitmap;
Bitmap* m_pDisableBitmap;
Bitmap* m_pBackImage;
bool m_bBackImage;
int m_TopHeight; //= 8;
int m_BottomHeight; //= 8;
int m_LeftWidth; //= 8;
int m_RightWidth;// = 17;
bool m_bMouseOver;
bool m_bEnabled;
int m_dwWidth;
int m_dwHeight;
BOOL m_bDCStored;
CDC m_memDC;
bool m_bSizeChange;
COLORREF m_BkColor;
CAutoFont * m_pFnt;
BOOL m_bTracking ;//是否追踪鼠标状态
BOOL m_bMouseMove;
public:
afx_msg void OnMouseLeave();
};
#ifndef _MEMDC_H_
#define _MEMDC_H_
//
// CMemDCWB - memory DC
//
// Author: Keith Rule
// Email: [email protected]
// Copyright 1996-1997, Keith Rule
//
// You may freely use or modify this code provided this
// Copyright is included in all derived versions.
//
// This class implements a memory Device Context
class CMemDCWB : public CDC {
private:
CBitmap* m_bitmap;
CBitmap* m_oldBitmap;
CDC* m_pDC;
CRect m_rcBounds;
public:
CMemDCWB(CDC* pDC, const CRect& rcBounds) : CDC()
{
CreateCompatibleDC(pDC);
m_bitmap = new CBitmap;
m_bitmap->CreateCompatibleBitmap(pDC, rcBounds.Width(), rcBounds.Height());
m_oldBitmap = SelectObject(m_bitmap);
m_pDC = pDC;
m_rcBounds = rcBounds;
//For some reason the background color is not correct,
//so we use the button face color.
DWORD color = ::GetSysColor( COLOR_BTNFACE );
CBrush bkg(color);
FillRect(rcBounds, &bkg);
}
~CMemDCWB()
{
m_pDC->BitBlt(m_rcBounds.left, m_rcBounds.top, m_rcBounds.Width(), m_rcBounds.Height(),
this, m_rcBounds.left, m_rcBounds.top, SRCCOPY);
SelectObject(m_oldBitmap);
if (m_bitmap != NULL) delete m_bitmap;
}
CMemDCWB* operator->() {
return this;
}
};
#endif
/
#endif // !defined(AFX_WBBUTTON_H__518122CF_358F_11D4_8F4F_00402656D980__INCLUDED_)
//源文件CGWButton.cpp
#include "stdafx.h"
#include "GWBButton.h"
#include "AutoFont.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
CGWBButton::CGWBButton()
{
m_TopHeight = 8;
m_BottomHeight = 8;
m_LeftWidth = 8;
m_RightWidth = 17;
m_State = notInited;
m_pFnt = new CAutoFont(_T("MS Sans Serif"));
m_BkColor = RGB(255,0,255);
m_RcId = 0; // Resource ID
m_NumofPics = 0;
m_bDCStored = FALSE;
m_pNormalBitmap = NULL;
m_pHoverBitmap = NULL;
m_pDownBitmap = NULL;
m_pDisableBitmap = NULL;
m_bMouseOver = false;
m_bEnabled = true;
m_bTracking = FALSE;
m_pBackImage = NULL;
m_bBackImage = FALSE;
m_bMouseMove = TRUE;
}
CGWBButton::~CGWBButton()
{
SAFE_DELETE(m_pNormalBitmap) ;
SAFE_DELETE(m_pHoverBitmap);
SAFE_DELETE(m_pDownBitmap) ;
SAFE_DELETE(m_pDisableBitmap);
SAFE_DELETE(m_pBackImage);
SAFE_DELETE(m_pFnt);
}
BEGIN_MESSAGE_MAP(CGWBButton, CButton)
//{{AFX_MSG_MAP(CGWBButton)
ON_WM_ERASEBKGND()
//}}AFX_MSG_MAP
ON_WM_MOUSEMOVE()
ON_WM_MOUSELEAVE()
END_MESSAGE_MAP()
void CGWBButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
UINT state = lpDrawItemStruct->itemState;
//CRect rect;
//rect.CopyRect(&lpDIS->rcItem);
m_state = NORMAL;
if (state & ODS_FOCUS)
{
if (state & ODS_SELECTED)
{
m_state = DOWN;
}
else
{
if(m_bMouseOver)
m_state = HOVER;
}
}
else
{
m_state = NORMAL;
}
if (state & ODS_DISABLED)
{
m_state = DISABLE;
m_bEnabled = false;
}
CDC xdc;
xdc.Attach( lpDrawItemStruct->hDC );
CRect rc;
GetClientRect(rc);
CMemDCWB dc(&xdc,rc);
DrawBitmap( &dc, m_state );
int imode = dc.SetBkMode(TRANSPARENT);
CFont *pOldFnt = dc.SelectObject(m_pFnt);
COLORREF oldColor;
oldColor = dc.SetTextColor( m_pFnt->GetFontColor() );
CString txt;
GetWindowText(txt);
dc.DrawText(txt,rc,DT_CENTER | DT_VCENTER | DT_SINGLELINE);
dc.SetTextColor( oldColor );
dc.SelectObject(pOldFnt);
dc.SetBkMode(imode );
}
bool CGWBButton::LoadImg(CString strPath,int count,int nWidth,int nHeight,int nInterval,BOOL bMouseMove,bool bSizeChange)
{
OutputDebugString(_T(" CGWBButton::LoadImg")+ strPath);
m_NumofPics = count;
Bitmap *pSrc = new Gdiplus::Bitmap(strPath);
m_pNormalBitmap = pSrc->Clone(0,0,nWidth,nHeight,PixelFormat32bppARGB);
int nWidthtest = m_pNormalBitmap->GetWidth();
CString strOut;
strOut.Format(_T("Normal nWidthtest:%d,nWidth:%d,nHeight:%d"),nWidthtest,nWidth,nHeight);
OutputDebugString(strOut);
m_pHoverBitmap = pSrc->Clone(nWidth+nInterval,0,nWidth,nHeight,PixelFormat32bppARGB);
nWidthtest = m_pHoverBitmap->GetWidth();
strOut.Format(_T("Hover nWidthtest:%d"),nWidthtest);
OutputDebugString(strOut);
m_pDownBitmap = pSrc->Clone((nWidth+nInterval)*2,0,nWidth,nHeight,PixelFormat32bppARGB);
m_pDisableBitmap = pSrc->Clone(0,0,nWidth,nHeight,PixelFormat32bppARGB);
delete pSrc;
m_State = FileLoaded;
m_bSizeChange = bSizeChange;
m_bMouseMove = bMouseMove;
return true;
}
bool CGWBButton::LoadImg(CString strNormal,CString strHover,CString strDown,CString strDisable,BOOL bMouseMove,bool bSizeChange )
{
SAFE_DELETE(m_pNormalBitmap) ;
SAFE_DELETE(m_pHoverBitmap);
SAFE_DELETE(m_pDownBitmap) ;
SAFE_DELETE(m_pDisableBitmap);
m_pNormalBitmap = Bitmap::FromFile(strNormal);
if (strHover.IsEmpty())
{
m_pHoverBitmap = Bitmap::FromFile(strNormal);
}
else
{
m_pHoverBitmap = Bitmap::FromFile(strHover);
}
if (strDown.IsEmpty())
{
m_pDownBitmap = Bitmap::FromFile(strNormal);
}
else
{
m_pDownBitmap = Bitmap::FromFile(strDown);
}
if (strDisable.IsEmpty())
{
m_pDisableBitmap = Bitmap::FromFile(strNormal);
}
else
{
m_pDisableBitmap = Bitmap::FromFile(strDisable);
}
m_State = FileLoaded;
m_bSizeChange = bSizeChange;
m_bMouseMove = bMouseMove;
return true;
}
//设置背景图片
void CGWBButton::SetBackImage(CString strPath)
{
if (strPath.IsEmpty())
{
SAFE_DELETE(m_pBackImage);
m_bBackImage = false;
}
else
{
m_pBackImage = Bitmap::FromFile(strPath);
m_bBackImage = true;
}
}
void CGWBButton::DrawBitmap( CDC * pDC, int mode )
{
//if( m_State < FileLoaded ) return;
CRect rc;
GetClientRect(rc);
COLORREF crOldText = pDC->SetTextColor(RGB(0,0,0));
CDC memDC;
CBitmap bmp;
memDC.CreateCompatibleDC(pDC);
bmp.CreateCompatibleBitmap(pDC,rc.Width(),rc.Height());
memDC.SelectObject(&bmp);
Bitmap* pOldBitmap;
switch(mode)
{
case NORMAL:
pOldBitmap = m_pNormalBitmap;
break;
case HOVER:
pOldBitmap = m_pHoverBitmap;
break;
case DOWN:
pOldBitmap = m_pDownBitmap;
break;
case DISABLE:
pOldBitmap = m_pDisableBitmap;
break;
default:
return;
}
if (!pOldBitmap)
return;
int nWidth = rc.Width();
int nHeight = rc.Height();
memDC.BitBlt(0, 0, nWidth, nHeight, &m_memDC, 0, 0, SRCCOPY);
Graphics graphic(memDC.GetSafeHdc());
Rect rect(0,0,rc.Width(),rc.Height());
if (m_bBackImage)
{
graphic.DrawImage(m_pBackImage,rect,0,0,pOldBitmap->GetWidth(),pOldBitmap->GetHeight(),UnitPixel);
}
if (m_bSizeChange)
{
graphic.DrawImage(pOldBitmap,rect,0,0,pOldBitmap->GetWidth(),pOldBitmap->GetHeight(),UnitPixel);
}
else
{
graphic.DrawImage(pOldBitmap,0,0,0,0,pOldBitmap->GetWidth(),pOldBitmap->GetHeight(),UnitPixel);
}
pDC->StretchBlt(0,0,nWidth,nHeight,&memDC,0,0,nWidth
,nHeight,SRCCOPY);
memDC.DeleteDC();
CFont* pOldFont;
pOldFont = pDC->SelectObject(GetFont());
CString txt;
GetWindowText(txt);
if (!txt.IsEmpty())
{
pDC->SetBkMode(TRANSPARENT);//graphic.DrawString(txt,pOldFont,)//
pDC->DrawText(txt,rc,DT_CENTER | DT_VCENTER | DT_SINGLELINE);
}
pDC->SelectObject(pOldFont);
}
BOOL CGWBButton::OnEraseBkgnd(CDC* pDC)
{
if(!m_bDCStored)
{
CRect rect;
GetClientRect(&rect);
if(m_memDC.m_hDC!=NULL)
{
m_memDC.DeleteDC();
}
m_memDC.CreateCompatibleDC (pDC);
CBitmap btScreen;
btScreen.CreateCompatibleBitmap (pDC,rect.Width(),rect.Height());
m_memDC.SelectObject (&btScreen);
CClientDC paintDC(GetParent());
CRect rt;
GetWindowRect(rt);
ScreenToClient(rt);
m_memDC.BitBlt (0,0,rect.Width(),rect.Height(),pDC,0,0,SRCCOPY);
m_bDCStored=true;
btScreen.DeleteObject();
}
return TRUE;
}
void CGWBButton::SetButtonDef( int TopHeight, int BottomHeight, int LeftWidth, int RightWidth )
{
m_TopHeight = TopHeight;
m_BottomHeight = BottomHeight;
m_LeftWidth = LeftWidth;
m_RightWidth = RightWidth;
}
void CGWBButton::SetTextFont( CFont & fnt )
{
LOGFONT lf;
fnt.GetLogFont(&lf);
SAFE_DELETE(m_pFnt);
m_pFnt = new CAutoFont(lf);
}
void CGWBButton::SetFontColor( COLORREF color )
{
m_pFnt->SetFontColor(color);
UpdateWindow();
}
void CGWBButton::OnMouseMove(UINT nFlags, CPoint point)
{
m_bEnabled = IsWindowEnabled();
if(!m_bMouseOver&&m_bEnabled)
{
m_bMouseOver=true;
m_state = HOVER;
if (!m_bTracking)
{
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(TRACKMOUSEEVENT);
tme.dwFlags = TME_LEAVE | TME_HOVER;//要触发的消息
tme.hwndTrack = this->m_hWnd;
tme.dwHoverTime = 10;// 若不设此参数,则无法触发mouseHover
if (::_TrackMouseEvent(&tme)) //MOUSELEAVE|MOUSEHOVER消息由此函数触发
{
m_bTracking = true;
}
}
if(m_bMouseMove)
{
}
else
{
CString txt;
GetWindowText(txt);
if (!txt.IsEmpty())
{
SetWindowText(txt);
}
CClientDC dc(this);
DrawBitmap(&dc,HOVER);
}
}
CButton::OnMouseMove(nFlags, point);
}
void CGWBButton::OnMouseLeave()
{
m_bTracking = false;
CPoint point;
CRect rect;
GetWindowRect(&rect);
GetCursorPos(&point);
if (!rect.PtInRect(point) && m_bMouseOver&&m_bEnabled)
{
if(m_bMouseMove)
{
((CDlgQQTalkMFC*)GetParent())->MouseMove(FALSE);
}
else
{
CString txt;
GetWindowText(txt);
CClientDC dc(this);
DrawBitmap(&dc,NORMAL);
}
}
m_bMouseOver=false;
CButton::OnMouseLeave();
}