#pragma once const int TIPBGRCOLOR = RGB ( 255, 255, 0 ); class CIconButton : public CButton { public: CIconButton(); virtual ~CIconButton(); void SetItalic ( bool bVal = true ) { m_TextMetrics.tmItalic = bVal; NewFont (); }; void SetUnderline ( bool bVal = true ) { m_TextMetrics.tmUnderlined = bVal; NewFont (); }; void SetStrikeOut ( bool bVal = true ) { m_TextMetrics.tmStruckOut = bVal; NewFont (); }; void SetFaceName ( const CString &sVal ) { m_sFaceName = sVal; NewFont (); }; void SetWeight ( const int nVal ) { m_TextMetrics.tmWeight = nVal; NewFont (); }; void SetIconID ( const UINT nID ) { m_nIconID = nID; }; void SetTextColor ( const COLORREF color ) { m_nColor = color; }; void SetIconSize ( const int x, const int y ) { m_nIcon.cx = x; m_nIcon.cy = y; }; void SetIconRight ( bool bVal = true ) { m_bIconRight = bVal; }; void Disable ( void ); void Enable ( void ); void SetTipText ( const CString &sTxt ) { m_sTip = sTxt; m_bWithTip = true; }; void SetHoverImageFile ( const CStringW &sHoverImageFile ) { m_sHoverImageFile = sHoverImageFile; } void SetLeaveImageFile ( const CStringW &sLeaveImageFile ) { m_sImageFile = m_sLeaveImageFile = sLeaveImageFile; } //{{AFX_VIRTUAL(CIconButton) public: virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct); //}}AFX_VIRTUAL protected: //{{AFX_MSG(CIconButton) afx_msg LRESULT OnNcHitTest(CPoint point); afx_msg void OnMouseMove(UINT nFlags, CPoint point); afx_msg void OnMouseLeave(); //}}AFX_MSG DECLARE_MESSAGE_MAP() private: void NewFont ( void ); int DelAmpersand ( CString &sTxt ); void HideTip ( void ); void ShowTip ( void ); void GetCurrentTextMetric ( void ); void DrawTipBoxAndText ( void ); bool RestoreBitmap ( void ); bool SaveBitmap ( void ); // bool m_bIconRight; TEXTMETRIC m_TextMetrics; CSize m_nIcon; UINT m_nIconID; COLORREF m_nColor; CFont m_fnt; CString m_sFaceName; // bool m_bWithTip; bool m_bTipIsOpen; CString m_sTip; CSize m_TipDim; CPoint m_TipPos; CRect m_TipRect; HBITMAP m_hMemBmp; HDC m_hMemDC; HDC m_hOwnerDC; CStringW m_sImageFile; CStringW m_sHoverImageFile; CStringW m_sLeaveImageFile; bool m_bHover; }; #include "stdafx.h" #include "IconButton.h" #include <gdiplus.h> #include <atlbase.h> using namespace Gdiplus; #pragma comment(lib, "Gdiplus") CIconButton::CIconButton() : m_bHover(false), m_sHoverImageFile("res//dlg_button_over_80.png"), m_sLeaveImageFile("res//dlg_button_80.png"), m_sImageFile("res//dlg_button_80.png") { m_fnt.FromHandle ( (HFONT)GetStockObject ( SYSTEM_FONT ) ); memset ( &m_TextMetrics, 0, sizeof ( TEXTMETRIC ) ); // m_bIconRight = false; m_nIconID = 0; // no icon m_nIcon.cx = ::GetSystemMetrics ( SM_CXICON ); // systemsize m_nIcon.cy = ::GetSystemMetrics ( SM_CYICON ); m_nColor = ::GetSysColor ( COLOR_BTNTEXT ); // systemcolor // // init for tip // m_sTip = ""; // no tiptext m_bTipIsOpen = false; // don磘 show m_bWithTip = false; // no tip } CIconButton::~CIconButton() { m_fnt.DeleteObject(); } BEGIN_MESSAGE_MAP(CIconButton, CButton) //{{AFX_MSG_MAP(CIconButton) ON_WM_NCHITTEST() ON_WM_MOUSEMOVE() ON_WM_MOUSELEAVE() //}}AFX_MSG_MAP END_MESSAGE_MAP() void CIconButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { CRect rect = lpDrawItemStruct->rcItem; CDC *pDC = CDC::FromHandle ( lpDrawItemStruct->hDC ); UINT state = lpDrawItemStruct->itemState; UINT uStyle = DFCS_BUTTONPUSH; bool bWithStr = true; CString strText; CAutoPtr<Bitmap> spImage(new Bitmap(m_sImageFile, FALSE)); if (NULL == spImage) { return CButton::DrawItem(lpDrawItemStruct); } HBITMAP hImage; spImage->GetHBITMAP(0, &hImage); if (NULL == hImage) { return CButton::DrawItem(lpDrawItemStruct); } if ( state & ODS_SELECTED ) { if ( ( m_bWithTip ) && ( m_bTipIsOpen ) ) { HideTip (); } } if ( lpDrawItemStruct->itemState & ODS_SELECTED ) { uStyle |= DFCS_PUSHED; } rect.right = rect.left + spImage->GetWidth(); rect.bottom = rect.left + spImage->GetHeight(); CPoint point(rect.left, rect.top); CSize size(rect.right - rect.left, rect.bottom - rect.top); if (state & ODS_DISABLED) { ::DrawFrameControl ( lpDrawItemStruct->hDC, &rect, DFC_BUTTON, uStyle ); } else { pDC->DrawState(point, size, hImage, DST_BITMAP | DSS_NORMAL); } if ( state & ODS_FOCUS ) { rect.DeflateRect ( 4, 4, 4, 4 ); pDC->DrawFocusRect ( rect ); } // if ( lpDrawItemStruct->itemState & ODS_SELECTED ) { CPen DarkShadowPen( PS_SOLID | PS_COSMETIC, 1, ::GetSysColor ( COLOR_3DDKSHADOW ) ); CPen HighlightPen( PS_SOLID | PS_COSMETIC, 1, ::GetSysColor ( COLOR_3DHIGHLIGHT ) ); pDC->SelectObject ( DarkShadowPen ); pDC->MoveTo ( CPoint ( lpDrawItemStruct->rcItem.left, lpDrawItemStruct->rcItem.bottom-1 ) ); pDC->LineTo ( CPoint ( lpDrawItemStruct->rcItem.left, lpDrawItemStruct->rcItem.top ) ); pDC->LineTo ( CPoint ( lpDrawItemStruct->rcItem.right-1, lpDrawItemStruct->rcItem.top ) ); pDC->SelectObject ( HighlightPen ); pDC->LineTo ( CPoint ( lpDrawItemStruct->rcItem.right-1, lpDrawItemStruct->rcItem.bottom-1 ) ); pDC->LineTo ( CPoint ( lpDrawItemStruct->rcItem.left, lpDrawItemStruct->rcItem.bottom-1 ) ); } GetWindowText ( strText ); if (!strText.IsEmpty ()) { if (state & ODS_DISABLED) { CSize TextExtent = pDC->GetTextExtent ( strText ); CPoint TextPos = CPoint ((int)(rect.right/2 - TextExtent.cx/2), (int)(rect.bottom/2 - TextExtent.cy/2) ); pDC->DrawState ( TextPos, TextExtent, strText, DSS_DISABLED, TRUE, 0, (HBRUSH)NULL); } else { pDC->SetBkMode(TRANSPARENT); pDC->DrawText( strText, rect , (DT_SINGLELINE | DT_CENTER | DT_VCENTER)); } } DeleteObject((HGLOBAL)hImage); } void CIconButton::NewFont() { m_fnt.DeleteObject (); m_fnt.CreateFont ( m_TextMetrics.tmHeight, // nHeight m_TextMetrics.tmMaxCharWidth, // nWidth 0, // nEscapement 0, // nOrientation m_TextMetrics.tmWeight, // nWeight m_TextMetrics.tmItalic, // bItalic m_TextMetrics.tmUnderlined, // bUnderline m_TextMetrics.tmStruckOut, // bStrikeOut m_TextMetrics.tmCharSet, // nCharSet OUT_DEFAULT_PRECIS, // nOutPrecision CLIP_DEFAULT_PRECIS, // nClipPrecision DEFAULT_QUALITY, // nQuality m_TextMetrics.tmPitchAndFamily, // nPitchAndFamily (LPCTSTR)m_sFaceName ); // lpszFacename } void CIconButton::Disable ( void ) { EnableWindow ( false ); Invalidate (); UpdateWindow (); } void CIconButton::Enable ( void ) { EnableWindow ( true ); Invalidate (); UpdateWindow (); } int CIconButton::DelAmpersand ( CString &sTxt ) { int nPos = 0; if ( ( nPos = sTxt.Find ( "&" ) ) != -1 ) { CString sLeft = sTxt.Left ( nPos ); CString sRight = sTxt.Mid ( nPos + 1 ); sTxt = sLeft + sRight; } return nPos; } /// // void CIconButton::HideTip ( void ) { RestoreBitmap (); m_bTipIsOpen = false; } /// // void CIconButton::ShowTip ( void ) { if ( m_bWithTip ) { SetCapture (); GetCurrentTextMetric (); DrawTipBoxAndText (); m_bTipIsOpen = true; } } /// // void CIconButton::GetCurrentTextMetric ( void ) { if ( m_bWithTip ) { CDC *pDC = GetParent ()->GetDC (); if ( pDC ) { m_TipDim.cx = pDC->GetTextExtent ( m_sTip ).cx + 4; m_TipDim.cy = pDC->GetTextExtent ( m_sTip ).cy + 4; } } } /// // void CIconButton::DrawTipBoxAndText ( void ) { if ( m_bWithTip ) { if ( ! m_bTipIsOpen ) { //CDC *pDC = GetDC (); CDC *pDC = GetOwner ()->GetDC (); if ( pDC ) { CBrush BkGrBrush ( TIPBGRCOLOR ); CBrush *pOldBrush = pDC->SelectObject ( &BkGrBrush ); CPen BlackPen ( PS_SOLID, 1, RGB ( 0, 0, 0 ) ); CPen *pOldPen = pDC->SelectObject ( &BlackPen ); // m_TipRect.SetRect ( 0, 0, m_TipDim.cx, m_TipDim.cy ); m_TipRect.OffsetRect ( m_TipPos.x, m_TipPos.y ); // CRect ParentRect; GetParent ()->GetWindowRect ( ParentRect ); if ( m_TipRect.right > ParentRect.right ) { int nDiv = m_TipRect.right - ParentRect.right + 5; m_TipRect.right -= nDiv; m_TipRect.left -= nDiv; } // GetOwner ()->ScreenToClient ( m_TipRect ); SaveBitmap (); pDC->Rectangle ( m_TipRect ); pDC->SetBkMode ( TRANSPARENT ); pDC->DrawText ( m_sTip, m_TipRect, DT_CENTER ); pDC->SelectObject ( pOldBrush ); pDC->SelectObject ( pOldPen ); } } } } /// // LRESULT CIconButton::OnNcHitTest(CPoint point) { if ( m_bWithTip ) { if ( ! m_bTipIsOpen ) { m_TipPos = point; ShowTip (); } } return CButton::OnNcHitTest(point); } /// // void CIconButton::OnMouseMove(UINT nFlags, CPoint point) { CRect ClientRect; GetClientRect ( &ClientRect ); bool bHover = m_bHover; m_bHover = !!ClientRect.PtInRect (point); if (bHover != m_bHover) { InvalidateRect(NULL); if (m_bHover) { m_sImageFile = m_sHoverImageFile; TRACKMOUSEEVENT tme; tme.cbSize = sizeof(tme); tme.dwFlags = TME_LEAVE; tme.hwndTrack = m_hWnd; ::_TrackMouseEvent(&tme); } } if (!m_bHover) { HideTip (); ReleaseCapture (); } CButton::OnMouseMove ( nFlags, point ); } void CIconButton::OnMouseLeave() { m_bHover = false; m_sImageFile = m_sLeaveImageFile; CButton::OnMouseLeave(); RedrawWindow(); } /// // bool CIconButton::RestoreBitmap ( void ) { bool bResult = false; // ::BitBlt ( m_hOwnerDC, m_TipRect.left, m_TipRect.top, m_TipDim.cx, m_TipDim.cy, m_hMemDC, 0, 0, SRCCOPY ); DeleteObject ( m_hMemBmp ); DeleteDC ( m_hMemDC ); DeleteDC ( m_hOwnerDC ); // return bResult; } /// // bool CIconButton::SaveBitmap ( void ) { bool bResult = true; // m_hOwnerDC = GetOwner ()->GetDC ()->m_hDC; m_hMemDC = ::CreateCompatibleDC ( m_hOwnerDC ); m_hMemBmp = ::CreateCompatibleBitmap ( m_hOwnerDC, m_TipDim.cx, m_TipDim.cy ); SelectObject ( m_hMemDC, m_hMemBmp ); ::BitBlt ( m_hMemDC, 0, 0, m_TipDim.cx, m_TipDim.cy, m_hOwnerDC, m_TipRect.left, m_TipRect.top, SRCCOPY ); // return bResult; }