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

📄 hsmenu.cpp

📁 漂亮菜单
💻 CPP
📖 第 1 页 / 共 3 页
字号:
}

void CHSMenu::DrawItemAnimation(LPDRAWITEMSTRUCTPRO lpdisp )
{
	if ( ( lpdisp->uFlags & MENU_SELECTED ) && !( lpdisp->uFlags & ITEM_SEPARATOR ) )
	{
		int		nWidth  = lpdisp->rect.right - lpdisp->rect.left;
		int		nHeight = lpdisp->rect.bottom- lpdisp->rect.top;

		HDC		hdcMem  = ::CreateCompatibleDC( lpdisp->hDC );
		HBITMAP hbmpMem = ::CreateCompatibleBitmap( lpdisp->hDC, nWidth, nHeight );
		HGDIOBJ hobjOld = ::SelectObject( hdcMem, hbmpMem );
		::BitBlt( hdcMem, 0, 0, nWidth, nHeight, lpdisp->hDC, lpdisp->rect.left, lpdisp->rect.top, SRCCOPY );

//------------------------------------------------------------------------------------------

		DRAWITEMSTRUCTPRO	disp;

		disp.hDC			= hdcMem;
		disp.lpcStr			= lpdisp->lpcStr;
		disp.ulData			= lpdisp->ulData;
		disp.uFlags			= lpdisp->uFlags;
		disp.rect.left		= 0;
		disp.rect.top		= 0;
		disp.rect.right		= nWidth;
		disp.rect.bottom	= nHeight;

		DrawItem( &disp );

//------------------------------------------------------------------------------------------

		DrawAnimateMenuItem( &lpdisp->rect, lpdisp->hDC, disp.hDC, m_nItemAniType, m_nItemAniStep, m_nItemAniDelay ); 

		::SelectObject( hdcMem, hobjOld );
		::DeleteObject( hbmpMem );
		::DeleteDC( hdcMem );
	}
	else
	{
		DrawItem( lpdisp );
	}
}

// Draw the menu item which you want
void CHSMenu::DrawItem(LPDRAWITEMSTRUCTPRO lpdisp)
{
	// Draw a separator
	if ( lpdisp->uFlags & ITEM_SEPARATOR )
	{
		DrawItemBkgnd( lpdisp );
		DrawItemSpr( lpdisp );
		return;
	}

	// Draw or Clear Select Background
	DrawItemBkgnd( lpdisp );

	// Draw the Menu item Text
	DrawItemText( lpdisp );

	// if this Item has son, then Graphics arrowhead
	if ( lpdisp->uFlags & ITEM_POPUP )
		DrawItemArrow( lpdisp );
}

// Draw(Selected) or Clear(Leave) the item Background 
void CHSMenu::DrawItemBkgnd(LPDRAWITEMSTRUCTPRO lpdisp)
{
	int		nClrBorder, nClrBk;
	RECT&	rect = lpdisp->rect;
	HRGN	hrgnItem = NULL;
	
	if ( GetState( MENU_SELECTED ) && !( lpdisp->uFlags & ITEM_SEPARATOR ) )
	{
		nClrBk	   = CLR_BKGNDSEL;
		nClrBorder = CLR_BORDERSEL;
	}
	else
	{
		nClrBk	   = CLR_BKGNDMENU;
		nClrBorder = CLR_BKGNDMENU;
	}

	if ( m_pfnCustomMenuItem )
		 hrgnItem = (HRGN)m_pfnCustomMenuItem( &rect );

	if ( hrgnItem == NULL )
	{
		DrawRect(	lpdisp->hDC, 
					m_clrMenu[nClrBorder], 
					m_clrMenu[nClrBk], 
					rect.left, 
					rect.top, 
					rect.right, 
					rect.bottom	 );
	}
	else
	{
		DrawRgn(lpdisp->hDC, m_clrMenu[nClrBorder], m_clrMenu[nClrBk], hrgnItem );
		::DeleteObject( hrgnItem );
	}
}

// Draw Menu Item's Name
void CHSMenu::DrawItemText(LPDRAWITEMSTRUCTPRO lpdisp)
{
	HGDIOBJ		hfntOld;
	COLORREF	clrText;
	RECT		rect;
	RECT&		rectT = lpdisp->rect;

	rect.left   = rectT.left + 20;
	rect.top    = ( rectT.top + rectT.bottom - m_nFontHeight ) / 2;
	rect.right	= 1000;
	rect.bottom	= 100;
	
	if ( lpdisp->uFlags & ITEM_GRAY )	 
		clrText = GetSysColor( COLOR_GRAYTEXT );
	else
		clrText = m_clrMenu[GetState( MENU_SELECTED ) ? CLR_TEXTSEL : CLR_TEXTNORMAL];
	
	SetTextColor( lpdisp->hDC, clrText );
	SetBkMode( lpdisp->hDC, TRANSPARENT );
	hfntOld = SelectObject( lpdisp->hDC, m_hFont );
	DrawText( lpdisp->hDC, lpdisp->lpcStr, -1, &rect, DT_NOCLIP|DT_LEFT ); 
	SelectObject( lpdisp->hDC, hfntOld );
}

// Draw Separator Item
void CHSMenu::DrawItemSpr(LPDRAWITEMSTRUCTPRO lpdisp)
{
	POINT		pt[2];
	RECT&		rect = lpdisp->rect;

	pt[0].x = rect.left + 8;
	pt[1].x = rect.right - 8;
	pt[0].y = pt[1].y = ( rect.top + rect.bottom ) / 2;

	DrawPolyline( lpdisp->hDC, m_clrMenu[CLR_BORDERSPR], pt, 2 );
}

// Draw Item Arrow ( Only Popup Item has )
void CHSMenu::DrawItemArrow(LPDRAWITEMSTRUCTPRO lpdisp)
{
	RECT&		rect = lpdisp->rect;

	int clrArrow;

	if ( lpdisp->uFlags & ITEM_GRAY )
		clrArrow = GetSysColor( COLOR_GRAYTEXT );
	else
		clrArrow = m_clrMenu[GetState( MENU_SELECTED ) ? CLR_ARROWSEL : CLR_TEXTNORMAL];

	DrawArrow( lpdisp->hDC, clrArrow, rect.right-8, (rect.top+rect.bottom)/2, 4 );
}

BOOL CHSMenu::IsEffectItem()
{	
	if ( m_nCurSel == SELNONE ) return FALSE;

	UINT uFlag = m_qMenuItem[m_nCurSel].m_uFlags; 

	return ( ( uFlag & ITEM_POPUP     ) == 0 && 
			 ( uFlag & ITEM_DISABLE   ) == 0 &&
			 ( uFlag & ITEM_GRAY      ) == 0 &&
			 ( uFlag & ITEM_SEPARATOR ) == 0
			);
}

BOOL CHSMenu::PointInMenu(short x, short y)
{
	if ( x>0 && x<m_nMenuWidth && y>0 && y<m_nMenuHeight )
	{
		HRGN hrgnMenu = ::CreateRectRgn( 0, 0, 0, 0 );
		::GetWindowRgn( m_hMenu, hrgnMenu );

		BOOL bInMenu = ::PtInRegion( hrgnMenu, x, y );
		::DeleteObject( hrgnMenu );

		return bInMenu;
	}

	return FALSE;
}

/*void CHSMenu::OnEraseBkgnd(HWND hWnd, HDC hDC)
{

}
*/

void CHSMenu::DrawMenuBkgnd(HWND hWnd, HDC hDC)
{
	HRGN hrgnMenu = ::CreateRectRgn( 0, 0, 0, 0 );
	::GetWindowRgn( hWnd, hrgnMenu );

	DrawRgn( hDC, m_clrMenu[CLR_BORDERMENU], m_clrMenu[CLR_BKGNDMENU], hrgnMenu );

	::DeleteObject( hrgnMenu );
}

void CHSMenu::DrawAnimateMenu( RECT *pRect, HDC hDC, HDC hDCMem, int nType, int nStep, int nTimeDelay)
{
	DrawAnimation( pRect, hDC, hDCMem, nType, nStep, nTimeDelay ); 
/*
	int nWidth		= pRect->right	- pRect->left;
	int nHeight		= pRect->bottom	- pRect->top;
	::BitBlt( hDC, pRect->left, pRect->top, nWidth, nHeight, hDCMem, 0, 0, SRCCOPY );
*/
}

void CHSMenu::OnPaint(HWND hWnd, HDC hDC)
{
//------------------------------------------------------------------------------------------
	if ( !GetState( MENU_SELECTED ) && m_nCurPop == SELNONE && m_nCurSel == SELNONE && m_qMenuItem.size() )
	{
		RECT rect;
		rect.left = rect.top = 0;
		rect.right  = m_nMenuWidth;
		rect.bottom = m_nMenuHeight;

		HDC		hdcMem  = ::CreateCompatibleDC( hDC );
		HBITMAP hbmpMem = ::CreateCompatibleBitmap( hDC, m_nMenuWidth, m_nMenuHeight );
		HGDIOBJ hobjOld = ::SelectObject( hdcMem, hbmpMem );
		::BitBlt( hdcMem, 0, 0, m_nMenuWidth, m_nMenuHeight, hDC, 0, 0, SRCCOPY );

		SetState( MENU_SELECTED, TRUE );
		OnPaint( hWnd, hdcMem );

		DrawAnimateMenu( &rect, hDC, hdcMem, m_nMenuAniType, m_nMenuAniStep, m_nMenuAniDelay );

		::SelectObject( hdcMem, hobjOld );
		::DeleteObject( hbmpMem );
		::DeleteDC( hdcMem );

		return;
	}
//------------------------------------------------------------------------------------------
	SetState( MENU_SELECTED, FALSE );

	DrawMenuBkgnd( hWnd, hDC );

	DRAWITEMSTRUCTPRO	disp;
	DEQUEITEM::const_iterator	it, itend = m_qMenuItem.end();

	disp.hDC = hDC;
	disp.rect.left  = m_nMenuEdge;
	disp.rect.right	= m_nMenuWidth - m_nMenuEdge;
	
	for ( it = m_qMenuItem.begin(); it != itend; it++ )
	{
		disp.ulData		 = it->m_ulData;
		disp.uFlags		 = it->m_uFlags | m_uMenuFlag;
		disp.lpcStr		 = it->m_strName.c_str();	
		disp.rect.top	 = it->m_nTop;
		disp.rect.bottom = it->m_nTop + it->m_nHeight;

		DrawItemAnimation( &disp );
	}

	if ( m_nCurPop != SELNONE )
	{
		SetState( MENU_SELECTED, TRUE );

		HSITEM& MenuItem = m_qMenuItem[m_nCurPop];

		disp.ulData		 = MenuItem.m_ulData;
		disp.uFlags		 = MenuItem.m_uFlags | m_uMenuFlag;
		disp.lpcStr		 = MenuItem.m_strName.c_str();	
		disp.rect.top	 = MenuItem.m_nTop;
		disp.rect.bottom = MenuItem.m_nTop + MenuItem.m_nHeight;

		DrawItemAnimation( &disp );
	}
}

#define ID_HSMENU_RENAME		1000
#define ID_HSMENU_PROPERTIY		1001

void CHSMenu::OnLButtonDown(HWND hWnd, short x, short y)
{
	if ( !PointInMenu( x, y ) ) 
		DestroyAllMenu();
}

void CHSMenu::OnLButtonUp(HWND hWnd, short x, short y)
{
	if ( PointInMenu( x, y ) && IsEffectItem() )
	{
		DestroyAllMenu();
//		::SendMessage( m_hWndParent, WM_COMMAND, MAKEWORD( m_qMenuItem[m_nCurSel].m_uID, 0 ),0 );
		::SendMessage( m_hWndParent, WM_COMMAND, m_qMenuItem[m_nCurSel].m_uID, 0 );
	}
}

void CHSMenu::OnRButtonDown(HWND hWnd, short x, short y)
{
	if ( !PointInMenu( x, y ) ) 
		DestroyAllMenu();
}

void CHSMenu::OnRButtonUp(HWND hWnd, short x, short y)
{
/*	if ( ::IsWindow( m_hMenu ) && PointInMenu( x, y ) )
	{
		CHSMenu* pHSMenu = new CHSMenu;
		pHSMenu->CreateMenu();
		pHSMenu->AppendMenu( "Rename", ID_HSMENU_RENAME );
		pHSMenu->AppendMenu( "Propertiy", ID_HSMENU_PROPERTIY );

		POINT pt;
		pt.x = x;
		pt.y = y;
		::ClientToScreen( m_hMenu, &pt );
		UINT uID = pHSMenu->TrackPopMenu( pt.x, pt.y, m_hWndParent );
		delete pHSMenu;

		switch( uID )
		{	
			case ID_HSMENU_RENAME:
				AfxMessageBox( "Rename" );
				break;

			case ID_HSMENU_PROPERTIY:
				break;

			default:;
		}	

		::ReleaseCapture();
		::SetCapture( hWnd );
	}
*/
}

// this function cycle destroy all the popup item's son
void CHSMenu::DestroyAllPop( void )
{
	if ( m_nCurPop == SELNONE )	return;

	int		 nCurPop;
	CHSMenu	*pDel, *pNext;

	pNext = m_qMenuItem[m_nCurPop].m_pPopupHSMenu;

	::SetActiveWindow( m_hMenu );

	do
	{
		pDel = pNext;
		nCurPop = pDel->m_nCurPop;

		if ( nCurPop != SELNONE )
			 pNext = pDel->m_qMenuItem[nCurPop].m_pPopupHSMenu;
		else pNext = NULL;

		pDel->DestroyMenu();

	} while ( pNext );	

	m_nCurPop = SELNONE;
	SetState( MENU_POPUPED, FALSE );
}

// Deatroy All Menu Window
void CHSMenu::DestroyAllMenu()
{
	CHSMenu	 *pDel = this;
	DestroyAllPop();

	do
	{
		pDel->DestroyMenu();
		pDel = pDel->m_pParent;

	} while ( pDel );
}

inline void CHSMenu::DestroyMenu()
{
	if ( m_hMenu )
	{
		SetState( MENU_SELECTED, FALSE );
		SetState( MENU_POPUPED,  FALSE );
		::DestroyWindow( m_hMenu );
		m_hMenu = NULL;
	}
}

static LRESULT CALLBACK lpfnWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
	CHSMenu	*pHSMenu = (CHSMenu *)( GetWindowLong( hWnd, GWL_USERDATA ) );
static nn=0;
	switch ( uMsg )
	{
		case WM_MOUSEMOVE:
			pHSMenu->OnMouseMove( hWnd, LOWORD(lParam), HIWORD(lParam) );
			break;

		case WM_TIMER:
			pHSMenu->OnTimer( hWnd, wParam );
			break;

		case WM_LBUTTONDOWN:
			pHSMenu->OnLButtonDown( hWnd, LOWORD(lParam), HIWORD(lParam) );
			break;

		case WM_LBUTTONUP:
			pHSMenu->OnLButtonUp( hWnd, LOWORD(lParam), HIWORD(lParam) );
			break;

		case WM_RBUTTONDOWN:
			pHSMenu->OnRButtonDown( hWnd, LOWORD(lParam), HIWORD(lParam) );
			break;

		case WM_RBUTTONUP:
			pHSMenu->OnRButtonUp( hWnd, LOWORD(lParam), HIWORD(lParam) );
			break;

//		case WM_ERASEBKGND:
//			pHSMenu->OnEraseBkgnd( hWnd, (HDC)wParam );
//			break;

		case WM_PAINT:
			{
				PAINTSTRUCT	ps;
				BeginPaint( hWnd, &ps );
				pHSMenu->OnPaint( hWnd, ps.hdc );
				EndPaint( hWnd, &ps );
			}
			break;

//		case WM_MOUSEWHEEL:
//			break;

		case WM_MBUTTONDOWN:
			pHSMenu->OnRButtonDown( hWnd, LOWORD(lParam), HIWORD(lParam) );
			break;

		case WM_KEYDOWN:
			pHSMenu->OnKeyDown( hWnd, (UINT)wParam, HIWORD(lParam), LOWORD(lParam));
			break;

//		case WM_KEYUP:
//			pHSMenu->OnKeyUp( hWnd, (UINT)wParam, HIWORD(lParam), LOWORD(lParam));
//			break;

//		case WM_CHAR:
//			pHSMenu->OnChar( hWnd, (char)wParam );
//			break;

		case WM_SYSKEYDOWN:
			pHSMenu->DestroyAllMenu();
			break;

		case WM_ACTIVATE:
		{
			if ( LOWORD(wParam) == WA_INACTIVE && pHSMenu->m_hWndParent != (HWND)lParam )
			{
				TCHAR	sClassName[50];
				GetClassName( (HWND)lParam, sClassName, sizeof(sClassName)/sizeof(TCHAR) );
				if ( lstrcmp( sClassName, "HSMENU_PRODUCT_BY_HANSONG" ) )
					pHSMenu->DestroyAllMenu();
			}
		}	break;

//		case WM_CAPTURECHANGED:
//			break;

		case WM_CREATE:
			SetWindowLong( hWnd, GWL_USERDATA, (long)( (LPCREATESTRUCT)lParam )->lpCreateParams );
			break;

//		case WM_DESTROY:
//			pHSMenu->OnDestroy( hWnd );
//			break;

		default:
			return DefWindowProc( hWnd, uMsg, wParam, lParam );
	}

	return 0;
}





DWORD CustomMenu(HWND hMenu)
{
	HRGN	hRgn;
	RECT	rect;
	::GetWindowRect( hMenu, &rect );
	int	nMenuWidth  = rect.right  - rect.left;
	int	nMenuHeight = rect.bottom - rect.top	;

//	 hRgn = CreateRoundRectRgn( 0, 0, nMenuWidth, nMenuHeight, 20, 20 );

	int		nRate = 9;
	POINT	ptSel[6];

	ptSel[0].x = nRate;
	ptSel[0].y = 0;
	ptSel[1].x = nMenuWidth;
	ptSel[1].y = 0;
	ptSel[2].x = nMenuWidth;
	ptSel[2].y = nMenuHeight - nRate;
	ptSel[3].x = nMenuWidth - nRate;
	ptSel[3].y = nMenuHeight;
	ptSel[4].x = 0;
	ptSel[4].y = nMenuHeight;
	ptSel[5].x = 0;
	ptSel[5].y = nRate;

	hRgn = ::CreatePolygonRgn( ptSel, 6, WINDING );

	::SetWindowRgn( hMenu, hRgn, true );
	::DeleteObject( hRgn );

//-----------------------------------------------------------------------------------
/*
	// Translucence window

	// Only active on platform windows2000/xp 
	// win98/me do not support.

	// Do not enable that code when the animate stype of class 'CHSMenu' is turn on
	// unless the performance of your CPU is excellent !

	SetWindowLong( hMenu, GWL_EXSTYLE, GetWindowLong( hMenu, GWL_EXSTYLE ) | 0x80000 );
	HINSTANCE instance = LoadLibrary( "User32.dll" );
	if ( instance )
	{
		typedef BOOL ( WINAPI *PSETLAYEREDWINDOWATTRIBUTES )( HWND, COLORREF, BYTE, DWORD );
		PSETLAYEREDWINDOWATTRIBUTES pSetLayeredWindowAttributes = NULL;
		pSetLayeredWindowAttributes = (PSETLAYEREDWINDOWATTRIBUTES)GetProcAddress( instance, "SetLayeredWindowAttributes" );

		if ( pSetLayeredWindowAttributes )
			 pSetLayeredWindowAttributes( hMenu, 0, 231, 2 ); 

		FreeLibrary( instance );
	}
*/
//-----------------------------------------------------------------------------------

	return DWORD(0);
}


DWORD CustomMenuItem( const RECT *prcItem )
{
//	return CreateRoundRectRgn( prcItem->left, prcItem->top, prcItem->right, prcItem->bottom,18,18 );

/*
{
	HRGN hRgnRect, hRgnElliptic;

	hrgnBk = CreateRectRgn( 0, 0, 0, 0 );
	hRgnRect  = CreateRectRgn( prcItem->left, prcItem->top, prcItem->right, prcItem->bottom );
	hRgnElliptic = CreateEllipticRgn( prcItem->left-20, prcItem->top, prcItem->left+30, prcItem->bottom );

	CombineRgn( hrgnBk, hRgnRect, hRgnElliptic, RGN_DIFF );
	hrgnBk = CreateRectRgn( prcItem->left, prcItem->top, prcItem->right, prcItem->bottom );
	hrgnBk = CreateRoundRectRgn( prcItem->left, prcItem->top, prcItem->right, prcItem->bottom, 18, 18 );
}
*/


	int		nRate = 9;
	POINT	ptSel[6];

	ptSel[0].x = prcItem->left + nRate;
	ptSel[0].y = prcItem->top;
	ptSel[1].x = prcItem->right;
	ptSel[1].y = prcItem->top;
	ptSel[2].x = prcItem->right;
	ptSel[2].y = prcItem->bottom - nRate ;
	ptSel[3].x = prcItem->right - nRate;
	ptSel[3].y = prcItem->bottom;
	ptSel[4].x = prcItem->left;
	ptSel[4].y = prcItem->bottom;
	ptSel[5].x = prcItem->left;
	ptSel[5].y = prcItem->top + nRate;

	return (DWORD)CreatePolygonRgn( ptSel, 6, WINDING );
}

⌨️ 快捷键说明

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