www.pudn.com > StaticTreeControl.rar > ContextMenu.cpp
// ContextMenu.cpp: implementation of the CContextMenu class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "customtreecontrol.h"
#include "ContextMenu.h"
#include "mmsystem.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CContextMenu::CContextMenu()
{
m_iWidth = 0;
m_iHeight = 0;
m_bSoundOn = TRUE;
}
CContextMenu::~CContextMenu()
{
for( int i = 0; i < m_cptrMenuItems.GetSize(); i++ )
delete (CContextMenuItem*)( m_cptrMenuItems.GetAt( i ) );
m_cptrMenuItems.RemoveAll();
}
/////////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
/////////////////////////////////////////////////////////////////////////////
CContextMenu& CContextMenu::SetTextFont( CFont* font )
{
m_pFont = font;
return *this;
}
CContextMenu& CContextMenu::ToggleSound( BOOL bSoundOn )
{
m_bSoundOn = bSoundOn;
return *this;
}
CContextMenu& CContextMenu::AppendMenuItem( UINT nFlags, UINT nID, CString csText, CString csWavFile, CDC* pDC )
{
CContextMenuItem* cccItem = new CContextMenuItem( csText, csWavFile );
// Store the pointer
m_cptrMenuItems.Add( cccItem );
// Append menu
CMenu::AppendMenu( nFlags | MF_OWNERDRAW, nID, (ODDCHAR*)cccItem );
// Calculate the size of the menu's text
if( !csText.IsEmpty() )
{
CSize cSize = pDC->GetTextExtent( csText );
m_iWidth = max( m_iWidth, cSize.cx );
m_iHeight = max( m_iHeight, 8 + cSize.cy );
}
return *this;
}
CContextMenu& CContextMenu::SetColors( COLORREF crText, COLORREF crBackground, COLORREF crDisabled,
COLORREF crSelected, COLORREF crBorder )
{
m_crText = crText;
m_crBackground = crBackground;
m_crDisabled = crDisabled;
m_crSelected = crSelected;
m_crBorder = crBorder;
return *this;
}
/////////////////////////////////////////////////////////////////////////////
// PROTECTED METHODS
/////////////////////////////////////////////////////////////////////////////
void CContextMenu::MeasureItem( LPMEASUREITEMSTRUCT lpMIS )
{
// Separator?
if( GetMenuState( lpMIS->itemID, MF_BYCOMMAND ) & MF_SEPARATOR )
{
lpMIS->itemWidth = m_iWidth;
lpMIS->itemHeight = 6;
}
else
{
lpMIS->itemWidth = m_iWidth;
lpMIS->itemHeight = m_iHeight;
}
}
void CContextMenu::DrawItem( LPDRAWITEMSTRUCT lpDIS )
{
// Get the relevant information
CDC* pDC = CDC::FromHandle( lpDIS->hDC );
CRect rItem = lpDIS->rcItem;
BOOL bSelected = lpDIS->itemState & ODS_SELECTED;
UINT nAction = lpDIS->itemAction;
UINT nState = GetMenuState( lpDIS->itemID, MF_BYCOMMAND );
CContextMenuItem* cccItem = reinterpret_cast( lpDIS->itemData );
// Does this menu item need to be drawn?
if( nAction & ODA_SELECT || nAction & ODA_DRAWENTIRE )
{
// Background
pDC->FillSolidRect( rItem, m_crBackground );
// Separator or Text
if( nState & MF_SEPARATOR )
{
rItem.DeflateRect( 4, 2, 4, 2 );
// A thin rectangle that could be anything you want
pDC->FillSolidRect( rItem, m_crBorder );
}
else
{
// Prepare the device context and store previous values
COLORREF crOldColor = pDC->SetTextColor( m_crText );
int iMode = pDC->SetBkMode( TRANSPARENT );
CFont* pOldFont = pDC->SelectObject( m_pFont );
// Is the item disabled?
if( nState & MFS_DISABLED )
{
rItem.DeflateRect( 8, 0, 0, 0 );
pDC->SetTextColor( m_crDisabled );
pDC->DrawText( cccItem->m_csText, rItem, DT_VCENTER | DT_LEFT | DT_SINGLELINE );
}
else
{
// If the item is selected, paint a rectangle, change the background color
// and play the wav file if relevant
if( bSelected )
{
rItem.DeflateRect( 2, 2, 2, 2 );
pDC->Draw3dRect( rItem, m_crBorder, m_crBorder );
rItem.DeflateRect( 1, 1, 1, 1 );
pDC->FillSolidRect( rItem, m_crSelected );
rItem.DeflateRect( 5, -3, 0, -3 );
if( m_bSoundOn )
{
// Stop any currently playing wav
PlaySound( NULL, NULL, SND_NOWAIT | SND_PURGE );
// Play this item's wav
PlaySound( cccItem->m_csWavFile, NULL, SND_NOWAIT | SND_FILENAME | SND_ASYNC );
}
}
else
rItem.DeflateRect( 8, 0, 0, 0 );
// Last, draw the text on top of everything else
pDC->DrawText( cccItem->m_csText, rItem, DT_VCENTER | DT_LEFT | DT_SINGLELINE );
}
// Clean up
pDC->SelectObject ( pOldFont );
pDC->SetBkMode ( iMode );
pDC->SetTextColor ( crOldColor );
}
}
}