#include "stdafx.h"
#include "IconButton.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
////////////////////////////////////////////////////////////////////////////
// Description : constructor with default settings
// Parameter : -
// Return : -
// .......................................................................
// alexander.kloep@gmx.net ´2002
////////////////////////////////////////////////////////////////////////////
CIconButton::CIconButton()
{
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´t show
m_bWithTip = false; // no tip
}
////////////////////////////////////////////////////////////////////////////
// Description : destructor
// Parameter : -
// Return : -
// .......................................................................
// alexander.kloep@gmx.net ´2002
////////////////////////////////////////////////////////////////////////////
CIconButton::~CIconButton()
{
m_fnt.DeleteObject();
}
BEGIN_MESSAGE_MAP(CIconButton, CButton)
//{{AFX_MSG_MAP(CIconButton)
ON_WM_NCHITTEST()
ON_WM_MOUSEMOVE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
////////////////////////////////////////////////////////////////////////////
// Description : called by the framework when a visual aspect of an
// owner-drawn button has changed. an owner-drawn button has
// the bs_ownerdrawn style set.
// Parameter : -
// Return : -
// .......................................................................
// alexander.kloep@gmx.net ´2002
////////////////////////////////////////////////////////////////////////////
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;
HICON hIcon = NULL;
int nHotkeyPos = 0;
CString strText;
CPoint TextPos;
CPoint RecPos;
CSize TextExtent;
CPen HighlightPen ( PS_SOLID | PS_COSMETIC, 1, ::GetSysColor ( COLOR_3DHIGHLIGHT ) );
CPen DarkShadowPen ( PS_SOLID | PS_COSMETIC, 1, ::GetSysColor ( COLOR_3DDKSHADOW ) );
//
ASSERT ( lpDrawItemStruct->CtlType == ODT_BUTTON );
//
// first check if tip is open, -> close before other action
//
if ( state & ODS_SELECTED )
{
if ( ( m_bWithTip ) && ( m_bTipIsOpen ) )
{
HideTip ();
}
}
//
if ( lpDrawItemStruct->itemState & ODS_SELECTED )
uStyle |= DFCS_PUSHED;
//
// fit the buttonheight to the iconsize
//
CRect r = rect;
r.bottom = m_nIcon.cy + 6;
r.right = pDC->GetTextExtent ( strText ).cx + m_nIcon.cx + 6;
pDC->SelectStockObject ( NULL_BRUSH );
pDC->FillSolidRect ( rect, ::GetSysColor ( COLOR_BTNFACE ) );
//
// draw a frame around the button
//
::DrawFrameControl ( lpDrawItemStruct->hDC, &lpDrawItemStruct->rcItem, DFC_BUTTON, uStyle );
//
GetWindowText ( strText );
bWithStr = ! strText.IsEmpty ();
//
if ( bWithStr )
{
nHotkeyPos = DelAmpersand ( strText );
pDC->SelectObject ( m_fnt );
TextExtent = pDC->GetTextExtent ( strText );
pDC->SetBkMode ( TRANSPARENT );
pDC->SetTextColor ( m_nColor );
//
if ( m_nIconID )
{
if ( m_bIconRight )
TextPos = CPoint ( (int)( ( rect.right - m_nIcon.cx ) / 2 - TextExtent.cx / 2 ),
(int)( rect.bottom/2 - TextExtent.cy / 2 ) );
else
TextPos = CPoint ( (int)( ( rect.right - m_nIcon.cx ) / 2 - TextExtent.cx / 2 ) + m_nIcon.cx,
(int)( rect.bottom/2 - TextExtent.cy / 2 ) );
}
//
// without icon -> center text
//
else
{
TextPos = CPoint ( (int)(rect.right/2 - TextExtent.cx/2),
(int)(rect.bottom/2 - TextExtent.cy/2) );
}
//
// calculate iconposition acording to the m_bIconRight-flag
//
if ( m_bIconRight )
RecPos = CPoint ( (rect.right - m_nIcon.cx - 6 ), (rect.Height () - m_nIcon.cy + 1 ) / 2 );
else
RecPos = CPoint ( 6, (rect.Height () - m_nIcon.cy + 1 ) / 2 );
}
//
// without text -> center icon
//
else
{
RecPos = CPoint ( (int)( ( rect.right - m_nIcon.cx ) / 2 ),
(int)( ( rect.bottom - m_nIcon.cy ) / 2 ) );
}
//
if ( m_nIconID != NULL )
hIcon = AfxGetApp()->LoadIcon ( MAKEINTRESOURCE ( m_nIconID ) );
//
// move icon and text a little bit
//
if ( state & ODS_SELECTED )
{
TextPos.Offset ( 1, 1 );
RecPos.Offset ( 1, 1);
}
//
if ( state & ODS_DISABLED )
{
CSize size ( m_nIcon.cx, m_nIcon.cy );
if ( bWithStr )
pDC->DrawState ( TextPos, TextExtent, strText, DSS_DISABLED, TRUE, 0, (HBRUSH)NULL);
if ( hIcon != NULL )
{
HICON hHelper = (HICON)CopyImage ( hIcon, IMAGE_ICON, m_nIcon.cx, m_nIcon.cy, LR_MONOCHROME );
pDC->DrawState ( RecPos, size, hHelper, DSS_DISABLED, (HBRUSH)NULL );
DestroyIcon ( (HICON)hHelper );
}
}
else
{
pDC->TextOut ( TextPos.x, TextPos.y, strText );
//
// draw the icon
//
if ( hIcon != NULL )
{
DrawIconEx ( pDC->GetSafeHdc (), rect.left + RecPos.x, rect.top + RecPos.y,
hIcon, (m_nIcon.cx) ? m_nIcon.cx : 32, (m_nIcon.cy) ? m_nIcon.cy : 32,
0, NULL, DI_NORMAL );
}
}
//
// if the button have the focus, draw the focus rect
//
if ( state & ODS_FOCUS )
{
CBrush brush;
brush.CreateSysColorBrush ( COLOR_3DDKSHADOW );
pDC->FrameRect ( rect, &brush );
rect.DeflateRect ( 4, 4, 4, 4 );
pDC->DrawFocusRect ( rect );
}
//
if ( lpDrawItemStruct->itemState & ODS_SELECTED )
{
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 ) );
}
//
// at the end, mark hotkey
//
if ( ( nHotkeyPos != -1 ) && ( bWithStr ) )
{
CString sHlp = strText.Mid ( nHotkeyPos, 1 );
CSize nWidth = pDC->GetTextExtent ( sHlp );
sHlp = strText.Left ( nHotkeyPos );
CSize nStart = pDC->GetTextExtent ( sHlp );
//
if ( state & ODS_DISABLED )
; // no line -> plainest
else
{
CPen HotkeyPen ( PS_SOLID | PS_COSMETIC, 1, m_nColor );
pDC->SelectObject ( HotkeyPen );
pDC->MoveTo ( TextPos.x + nStart.cx, TextPos.y + TextExtent.cy );
pDC->LineTo ( TextPos.x + nStart.cx + nWidth.cx, TextPos.y + TextExtent.cy );
}
}
}
////////////////////////////////////////////////////////////////////////////
// Description : create a special font for the button
// Parameter : -
// Remark : specifies the pitch and family of the font "roman".
// .......................................................................
// alexander.kloep@gmx.net ´2002
////////////////////////////////////////////////////////////////////////////
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, // b