📄 colormenu.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 + -