// InnerButton.cpp : implementation file // #include "stdafx.h" #include "resource.h" #include "InnerButton.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif #pragma comment( lib, "Msimg32.lib" ) ///////////////////////////////////////////////////////////////////////////// /* CInnerButton 用来显示一张图片 能够感应鼠标的经过 从CButton派生的一个自画按钮 */ CInnerButton::CInnerButton() { m_bOver=FALSE; m_bTracking=FALSE; m_pGif = NULL; } CInnerButton::~CInnerButton() { } BEGIN_MESSAGE_MAP(CInnerButton, CButton) //{{AFX_MSG_MAP(CInnerButton) ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave) ON_MESSAGE(WM_MOUSEHOVER, OnMouseHover) ON_WM_MOUSEMOVE() ON_WM_ERASEBKGND() //}}AFX_MSG_MAP ON_WM_TIMER() END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CInnerButton message handlers void CInnerButton::PreSubclassWindow() { // TODO: Add your specialized code here and/or call the base class this->ModifyStyle(0,BS_OWNERDRAW); CButton::PreSubclassWindow(); } void CInnerButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { //从lpDrawItemStruct获取控件的相关信息 CRect rect = lpDrawItemStruct->rcItem; CDC *pDC=CDC::FromHandle(lpDrawItemStruct->hDC); int nSaveDC=pDC->SaveDC(); UINT state = lpDrawItemStruct->itemState; TCHAR szText[MAX_PATH + 1]; ::GetWindowText(m_hWnd, szText, MAX_PATH); ///// ///准备工作 CPen *pOldPen,BorderPen,NullPen; HBRUSH pOldBrush; CBrush BGBrush; NullPen.CreatePen(PS_NULL,0,RGB(241,238,231)); BGBrush.CreateSolidBrush(RGB(241,238,231)); BorderPen.CreatePen(PS_SOLID,1,RGB(79,107,160)); ///如果鼠标经过的话,画一个边框 if(m_bOver) { pOldPen=pDC->SelectObject(&NullPen); pDC->SelectObject(&BGBrush); pDC->Rectangle(&rect); pDC->SelectObject(pOldPen); } Graphics g(lpDrawItemStruct->hDC); g.DrawImage(m_pGif->GetImg(), rect.left, rect.top, rect.Width(), rect.Height()); //鼠标经过状态 if(m_bOver) { //////////// pOldPen=pDC->SelectObject(&BorderPen); pOldBrush=HBRUSH(pDC->SelectObject(HBRUSH(::GetStockObject(NULL_BRUSH)))); pDC->Rectangle(&rect); pDC->SelectObject(pOldPen); pDC->SelectObject(pOldBrush); } ///输出文本 if (szText!=NULL) { TEXTMETRIC tm; pDC->GetTextMetrics(&tm); CFont* hFont = GetFont(); CFont* hOldFont = pDC->SelectObject(hFont); CSize sizeExtent = pDC->GetTextExtent(szText, lstrlen(szText)); CPoint pt; pt.x=(rect.right-tm.tmAveCharWidth*lstrlen(szText))/2-2; pt.y=rect.bottom-tm.tmHeight-2; int nMode = pDC->SetBkMode(TRANSPARENT); pDC->SetTextColor(RGB(60,77,129)); if (state & ODS_DISABLED) pDC->DrawState(pt, sizeExtent, szText, DSS_DISABLED, TRUE, 0, (HBRUSH)NULL); else pDC->DrawState(pt, sizeExtent, szText, DSS_NORMAL, TRUE, 0, (HBRUSH)NULL); pDC->SelectObject(hOldFont); pDC->SetBkMode(nMode); } } ///跟踪鼠标,使用了TrackMouseEvent()函数 void CInnerButton::OnMouseMove(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default if(!m_bTracking) { TRACKMOUSEEVENT tme; tme.cbSize = sizeof(tme); tme.hwndTrack = m_hWnd; tme.dwFlags = TME_LEAVE | TME_HOVER; tme.dwHoverTime = 1; _TrackMouseEvent(&tme); m_bTracking=TRUE; } CButton::OnMouseMove(nFlags, point); } LRESULT CInnerButton::OnMouseHover(WPARAM wParam,LPARAM lParam) { m_bOver=TRUE; this->Invalidate(); return 0; } LRESULT CInnerButton::OnMouseLeave(WPARAM wParam,LPARAM lParam) { m_bOver=FALSE; m_bTracking=FALSE; this->Invalidate(); return 0; } ////画背景色 BOOL CInnerButton::OnEraseBkgnd(CDC* pDC) { RECT rect; this->GetClientRect(&rect); CPen BorderPen; BorderPen.CreatePen(PS_SOLID,1,RGB(255,255,255)); pDC->SelectObject(&BorderPen); pDC->SelectObject(HBRUSH(::GetStockObject(WHITE_BRUSH))); pDC->Rectangle(&rect); return TRUE; } void CInnerButton::SetGif(CGif* pGif) { m_pGif = pGif; } void CInnerButton::PlayGif() { m_pGif->SelectFrame(0); SetTimer(1, m_pGif->GetFrameTime() * 10, NULL); Invalidate(FALSE); } void CInnerButton::OnTimer(UINT_PTR nIDEvent) { KillTimer(nIDEvent); if (m_pGif->IsLastFrame()) { m_pGif->SelectFrame(0); SetTimer(1, 1000, NULL); } else { m_pGif->NextFrame(); SetTimer(1, m_pGif->GetFrameTime() * 10, NULL); } Invalidate(FALSE); }