⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 colormenu.cpp

📁 这是MFC经典问答书的光盘内容
💻 CPP
字号:
#include "stdafx.h"

#include "resource.h"

#include "ColorMenu.h"

#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CColorMenu

int CColorMenu::s_ColorMap[ 16 ] =
					{
						0, 		//black
						1, 		//dark red
						2, 		//dark green
						3, 		//light brown
						4, 		//dark blue
						5, 		//purple
						6, 		//dark cyan
						12, 	//gray
						7, 		//light gray
						13, 	//red
						14, 	//green
						15, 	//yellow
						16, 	//blue
						17, 	//magenta
						18, 	//cyan
						19	 	//white
					};

CColorMenu::CColorMenu()
{
	// 1 - Create the popup menu and add owner-drawn items
	VERIFY( CreatePopupMenu() );
	ASSERT( GetMenuItemCount() == 0 );

	// 2 - Add items
	// (item data is set to item ID to provide a
	// consistency check in OnMeasureItem and OnDrawItem)
	for( int i = 0; i <= 15; ++i )
	{
		// ID_COLOR0 to ID_COLOR15 are consecutive IDs that have
		// associated string resources containing the text for each
		// menu item (like toolbar buttons)
		VERIFY( AppendMenu(	MF_OWNERDRAW,
							ID_COLOR0 + i, (LPCTSTR)(ID_COLOR0 + i) ) );
	}
}

COLORREF CColorMenu::GetColorRef( UINT nID )
{
	// Find COLORREF from menu item ID
	ASSERT( nID >= ID_COLOR0 );
	ASSERT( nID <= ID_COLOR15 );

	// 1 - Get standard color palette
	CPalette* pPal = CPalette::FromHandle(
							(HPALETTE) GetStockObject( DEFAULT_PALETTE ) );
	ASSERT( pPal != NULL );
	PALETTEENTRY pe;

	// 2 - Find color map entry in palette
	if( pPal->GetPaletteEntries( s_ColorMap[ nID-ID_COLOR0 ], 1, &pe ) != 0 )
	{
		return RGB( pe.peRed, pe.peGreen, pe.peBlue );
	}
	else
	{
		TRACE1( "Unable to find palette color entry for ID=%d\n", nID );
		return ::GetSysColor( COLOR_WINDOWTEXT );
	}
}

void CColorMenu::MeasureItem( LPMEASUREITEMSTRUCT lpMIS )
{
	ASSERT(lpMIS->CtlType == ODT_MENU);

	// 1 - Get menu item ID
	UINT id = (UINT) (WORD) lpMIS->itemID;

	// Consistency checks
	ASSERT( id == lpMIS->itemData );
	ASSERT( id >= ID_COLOR0 );
	ASSERT( id <= ID_COLOR15 );

	// 2 - Load item string
	CString strColor;
	AfxExtractSubString( strColor, CString( LPCSTR( id ) ), 0 );

	// 3 - Compute item text extent
	CDC* pdc = AfxGetMainWnd()->GetDC();
	CSize sizeText = pdc->GetTextExtent( strColor, strColor.GetLength() );
	AfxGetMainWnd()->ReleaseDC( pdc );

	// 4 - Compute check mark dimensions
	int cxCheckMark = ::GetSystemMetrics( SM_CXMENUCHECK );
	int cyCheckMark = ::GetSystemMetrics( SM_CYMENUCHECK );

	// 5 - Define final item size
	lpMIS->itemWidth = cxCheckMark + CX_COLOR_LEFT_MARGIN + CX_COLOR +
							CX_COLOR_RIGHT_MARGIN + sizeText.cx;
	lpMIS->itemHeight = max( sizeText.cy, cyCheckMark );
}

void CColorMenu::DrawItem( LPDRAWITEMSTRUCT lpDIS )
{
	ASSERT( lpDIS->CtlType == ODT_MENU );

	// 1 - Get menu item ID
	UINT id = (UINT) (WORD) lpDIS->itemID;

	// Consistency checks
	ASSERT( id == lpDIS->itemData );
	ASSERT( id >= ID_COLOR0 );
	ASSERT( id <= ID_COLOR15 );

	// 2 - Get device context & item rectangle
	CDC dc;
	dc.Attach( lpDIS->hDC );

	CRect rcItem( lpDIS->rcItem );
	int nCurrentX = rcItem.left;	// current position

	// 3 - Select background and foreground colors depending
	// on item selected state
	COLORREF crBack, crFore;
	if( lpDIS->itemState & ODS_SELECTED )
	{
		crBack = ::GetSysColor( COLOR_HIGHLIGHT );
		crFore = ::GetSysColor( COLOR_HIGHLIGHTTEXT );
	}
	else
	{
		crBack = ::GetSysColor( COLOR_MENU );
		crFore = ::GetSysColor( COLOR_MENUTEXT );
	}

	// 4 - Draw optional checkmark
	if( lpDIS->itemState & ODS_CHECKED )
	{
		// Load checkmark bitmap
		// (#define OEMRESOURCE before including Windows.h,
		// *OR* #define OBM_CHECK 32760)
		CBitmap bmCheck;
		bmCheck.LoadOEMBitmap( OBM_CHECK );

		// Compute bitmap size
		BITMAP bmStruct;
		bmCheck.GetObject( sizeof( BITMAP ), &bmStruct );
		CSize sizeBitmap( bmStruct.bmWidth, bmStruct.bmHeight );

		// Draw bitmap on menu DC
		CDC dcMem;
		dcMem.CreateCompatibleDC( &dc );
		CBitmap* pOldBitmap = dcMem.SelectObject( &bmCheck );

		dc.BitBlt(	rcItem.left, ( rcItem.top + rcItem.bottom - sizeBitmap.cy ) / 2,
					sizeBitmap.cx, sizeBitmap.cy,
					&dcMem, 0, 0, SRCCOPY ); 

		dcMem.SelectObject( pOldBitmap );	
	}

	nCurrentX += ::GetSystemMetrics( SM_CXMENUCHECK );

	// 5 - Fill item background
	CRect rcBack( nCurrentX, rcItem.top, rcItem.right, rcItem.bottom );
	CBrush brFill( crBack );
	dc.FillRect( &rcBack, &brFill );

	nCurrentX += CX_COLOR_LEFT_MARGIN;

	// 6 - Draw item color rectangle
	CBrush brColor( GetColorRef( id ) );
	CBrush* pOldBrush = dc.SelectObject( &brColor );
	CRect rcColor(	nCurrentX, rcItem.top + CY_COLOR_MARGIN,
					nCurrentX + CX_COLOR, rcItem.bottom - CY_COLOR_MARGIN );
	dc.Rectangle( rcColor );

	dc.SelectObject( pOldBrush );

	nCurrentX += CX_COLOR + CX_COLOR_RIGHT_MARGIN;

	// 7 - Draw item text
	COLORREF crOldTextColor = dc.SetTextColor( crFore );
	int nOldBkMode = dc.SetBkMode( TRANSPARENT );

	CString strColor;
	AfxExtractSubString( strColor, CString( LPCSTR( id ) ), 0 );

	dc.TextOut( nCurrentX, rcItem.top, strColor, strColor.GetLength() );

	dc.SetTextColor( crOldTextColor );
	dc.SetBkMode( nOldBkMode );

	dc.Detach();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -