www.pudn.com > dmtbfq.rar > COOLMENU.CPP


// CoolMenu.cpp: implementation of the CCoolMenu class. 
// 
////////////////////////////////////////////////////////////////////// 
 
#include "stdafx.h" 
#include "CoolMenu.h" 
 
 
#define RGB_BUTTON_BLACK    (GetSysColor(COLOR_WINDOWFRAME)) 
#define RGB_BUTTON_WHITE    (GetSysColor(COLOR_BTNHIGHLIGHT)) 
#define RGB_BUTTON_LIGHT    (GetSysColor(COLOR_BTNFACE)) 
#define RGB_BUTTON_DARK     (GetSysColor(COLOR_BTNSHADOW)) 
#define RGB_MENU_FACE       (GetSysColor(COLOR_MENU)) 
#define RGB_MENUTEXT_BACK   (GetSysColor(COLOR_HIGHLIGHT)) 
#define RGB_MENU_TEXT       (GetSysColor(COLOR_MENUTEXT)) 
#define RGB_DEFINE_BLUE     (RGB(0,210,60)) 
 
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
 
CCoolMenu::CCoolMenu() 
{ 
	m_iMenuWidth=100; 
	m_iMenuHeight=33; 
	m_nIconSize=32; 
 
	m_iItemNum=0; 
	m_iUpHeight=0; 
    m_iBackImageWidth=30; 
 
	m_clrMenuStart=RGB(0,110,180); 
    m_clrMenuEnd = RGB_MENU_FACE; 
 
	m_clrBarStart=RGB(0,220,180); 
    m_clrBarEnd = RGB_MENU_FACE; 
} 
 
CCoolMenu::~CCoolMenu() 
{ 
} 
 
void CCoolMenu::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct) 
{  
	CDCHandle DC= lpDrawItemStruct->hDC; 
	CDCHandle * pDC= &DC; 
 
	CRect  rc=lpDrawItemStruct->rcItem; 
	UINT  ID=lpDrawItemStruct->itemID; 
//	DWORD  Data=lpDrawItemStruct->itemData; 
	 
	int nThisID = m_MenuItemList.FindItemIndexByID(ID); 
    int nImageID = m_MenuItemList.FindItemImageByID (ID); 
 
	if(ID==MF_SEPARATOR) 
	{ 
		CRect  rect; 
		rect.left=rc.left+m_iBackImageWidth; 
		rect.right=rc.right; 
		rect.top=rc.top+int((rc.bottom-rc.top)/2.0); 
		rect.bottom=rc.bottom; 
		pDC->DrawEdge(rect,EDGE_ETCHED,BF_TOP); 
		m_iUpHeight+=rc.Height()-rect.Height(); 
	} 
	else 
	{ 
		pDC->SetBkMode(TRANSPARENT); 
 
		CRect  ImageRect,TextRect; 
		CRect  BkRect; 
		ImageRect=rc; 
		ImageRect.left+=m_iBackImageWidth+2; 
		ImageRect.right=ImageRect.left+m_nIconSize;   
 
		TextRect=rc; 
    	    TextRect.left=ImageRect.right; 
 		 
        BkRect=rc; 
		 BkRect.left =m_iBackImageWidth+1 ; 
 
		if(lpDrawItemStruct->itemState==ODS_SELECTED) 
		{ 
		//	pDC->FillSolidRect(&BkRect,RGB_DEFINE_BLUE); 
    	    DrawGradient(pDC, &BkRect,m_clrMenuStart, m_clrMenuEnd,FALSE); 
 
			if (nImageID >=0 ) 
    			pDC->Draw3dRect(&ImageRect,RGB_BUTTON_WHITE,RGB_BUTTON_DARK); 
		//	pDC->Draw3dRect(&TextRect,RGB_DEFINE_BLUE,RGB_DEFINE_BLUE); 
		} 
		else 
		{ 
		 	pDC->FillSolidRect(&BkRect,RGB_MENU_FACE); 
		//	pDC->Draw3dRect(&ImageRect,RGB_MENU_FACE,RGB_MENU_FACE); 
		//	pDC->Draw3dRect(&TextRect,RGB_MENU_FACE,RGB_MENU_FACE); 
		} 
		//绘制图象 
	 	int  x,y; 
	 	x=ImageRect.left+int((ImageRect.Width()-m_iImageWidth)/2.0); 
	 	y=ImageRect.top+int((ImageRect.Height()-m_iImageWidth)/2.0); 
 
		if (nImageID >=0) 
 	    	m_ImageList.Draw(pDC->m_hDC ,nImageID,CPoint(x,y),ILD_TRANSPARENT); 
 
		 TextRect.left+=5; 
		CString strMenuText=m_MenuItemList.FindItemTextByID (ID); 
 
	  	pDC->DrawText(_T(strMenuText),strMenuText.GetLength (), 
			  &TextRect,DT_LEFT|DT_SINGLELINE|DT_VCENTER); 
	} 
 
	//绘制背景图 
 // 	if (lpDrawItemStruct->itemAction & ODA_DRAWENTIRE) 
 //		m_BackImageList.Draw(pDC,item.m_iIndex,CPoint(rc.left,rc.top),ILD_TRANSPARENT); 
 
	if ( nThisID == m_iItemNum)  //最后一个MenuItem 
	{ 
	     CRect RectBar(0,0,m_iBackImageWidth,rc.bottom ); 
        DrawGradient( pDC, &RectBar,m_clrBarEnd, m_clrBarStart,TRUE); 
	} 
 
}  
void CCoolMenu::SetBackImage(UINT nID,int cx,int row) 
{ 
//	COLORREF  cl=GetSysColor(COLOR_MENU); 
//	m_BackImageList.Create(nID,m_iMenuHeight,row,cl); 
	m_iBackImageHeight=m_iMenuHeight; 
 
	m_iMenuHeight=cx; 
	m_iBackImageWidth=21; 
} 
 
void CCoolMenu::SetImage(UINT nID, int cx, int row) 
{ 
	COLORREF  cl=GetSysColor(COLOR_MENU); 
	m_ImageList.Create(nID,cx,row,cl); 
	m_iImageWidth=cx; 
} 
 
void CCoolMenu::MeasureItem(LPMEASUREITEMSTRUCT  lpMeasureItemStruct) 
{  
    	if(lpMeasureItemStruct->itemID==MF_SEPARATOR) 
    		lpMeasureItemStruct->itemHeight = 10; 
    	else 
	    	lpMeasureItemStruct->itemHeight = m_iMenuHeight; 
	    lpMeasureItemStruct->itemWidth  = m_iMenuWidth; 
}  
 
void CCoolMenu::AppendCoolMenu(UINT nID, CString text , int nImageID/*=-1*/) 
{	 
	if(nID==MF_SEPARATOR) 
		AppendMenu(MF_SEPARATOR|MF_OWNERDRAW, nID,(LPCTSTR)text); 
	else 
		AppendMenu(MF_ENABLED | MF_OWNERDRAW, nID,(LPCTSTR)text); 
 
 	MenuItem  item; 
 	item.m_strMenuText=text; 
 	item.m_iIndex=m_iItemNum; 
	item.m_iID =nID; 
	item.m_iImageID = nImageID; 
 
	m_MenuItemList.Add (item); 
 
 	m_iItemNum+=1; 
 
 	int nWidth=text.GetLength () * 8 + m_iImageWidth + m_nIconSize+60 ; 
 
 	m_iMenuWidth = ( m_iMenuWidth > nWidth)  ? m_iMenuWidth : nWidth ; 
} 
 
 
void CCoolMenu::DrawGradient(CDCHandle * pDC, CRect * pRect , COLORREF clrStart ,  
								     COLORREF clrEnd,BOOL bVertice /*=FALSE */) 
{ 
	RECT rectFill;			   // Rectangle for filling band 
	float fStep;              // How wide is each band? 
	CBrush brush;			// Brush to fill in the bar	 
 
	int r, g, b;							// First distance, then starting value 
	float rStep, gStep, bStep;		// Step size for each color 
 
	// Get the color differences 
	r = (GetRValue(clrEnd) - GetRValue(clrStart)); 
	g = (GetGValue(clrEnd) - GetGValue(clrStart)); 
	b =  (GetBValue(clrEnd) - GetBValue(clrStart)); 
 
	// Make the number of steps equal to the greatest distance 
	int nSteps = max(abs(r), max(abs(g), abs(b))); 
 
	// Determine how large each band should be in order to cover the 
	// client with nSteps bands (one for every color intensity level) 
   if (bVertice ) 
	   fStep = (float) pRect->Height() / (float)nSteps; 
   else 
	   fStep = (float) pRect->Width() / (float)nSteps; 
 
	// Calculate the step size for each color 
	rStep = r/(float)nSteps; 
	gStep = g/(float)nSteps; 
	bStep = b/(float)nSteps; 
 
	// Reset the colors to the starting position 
	r = GetRValue(clrStart); 
	g = GetGValue(clrStart); 
	b = GetBValue(clrStart); 
 
	rectFill= *pRect; 
 
	// Start filling bands 
	for (int i= 0; i < nSteps; i++)  
	{		 
	  if( bVertice) 
	  { 
		  rectFill.top    =  pRect->top  + (int)(i * fStep);	 
		  rectFill.bottom =  pRect->top   + (int)( (i+1) * fStep );	 
	  } 
	  else 
	  { 
		  rectFill.left  =  pRect->left + (int)(i * fStep);	 
		  rectFill.right =  pRect->left + (int) ( (i+1) * fStep );	 
	  } 
 
	  //CDC::FillSolidRect is faster, but it does not handle 8-bit color depth 
	//	VERIFY(brush.CreateSolidBrush(RGB(r+rStep*i, g + gStep*i, b + bStep *i))); 
	  //  	pDC->FillRect(&rectFill,&brush); 
        pDC->FillSolidRect(&rectFill,RGB(r+rStep*i, g + gStep*i, b + bStep *i) ); 
	//	VERIFY(brush.DeleteObject()); 
	} 
}