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

📄 hsmenu.cpp

📁 漂亮菜单
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// HSMenu.cpp: implementation of the CHSMenu class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "HSMenu.h"
#include "HSGraphics.h"
//#include "HSAnimationMemDC.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif


///////////////////////////////////////////////////////////////////////////////////////////////
//$//								作者 : 韩 松                                 
//$//                                                                          
//$//			程序名称 :CHSMenu                                              
//$//			程序类型 :菜单类												
//$//			邮箱地址 :hs_china@yahoo.com								
//$//           QQ号码    :102567329
//$//																		
//$//			作者声明 :此部分代码全是作者所写,可以随便传播,但要保持  
//$//					   文件的完整性,如果您有问题或有好的建议、意见请您	
//$//					   给我来信,非常感谢!							
//$//                                      
//$//					   CHSMenu 类的使用细节请您参考附带的说明。		
//$//					   另有 CHSMenuPro 类(由CHSMenu派生)见文档      
//$//					   HSMenuPro.h/cpp							  
//$//																	
//////////////////////////////////////////////////////////////////////////////////////////////



//////////////////////////////////////////////////////////////////////
// HSITEM Class
//////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
/*
void HSITEM::Assign(const HSITEM &MenuItem)
{
	m_uID			= MenuItem.m_uID; 
	m_ulData		= MenuItem.m_ulData;
	m_uFlags		= MenuItem.m_uFlags;
	m_nTop			= MenuItem.m_nTop;
	m_strName		= MenuItem.m_strName;
	m_pPopupHSMenu	= MenuItem.m_pPopupHSMenu;
}

HSITEM& HSITEM::operator =(const HSITEM &MenuItem)
{
	Assign( MenuItem );
	return *this;
}

HSITEM::HSITEM( const HSITEM& MenuItem )
{
	Assign( MenuItem );
}
*/
inline HSITEM::HSITEM()
{
	m_nTop			= 0;
	m_nHeight		= 0;
	m_uID			= 0; 
	m_ulData		= 0;
	m_uFlags		= ITEM_NORMAL;
	m_pPopupHSMenu	= NULL;
}

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////


/*
CLR_BKGNDSEL		0
CLR_BKGNDMENU		1
CLR_BORDERMENU		2
CLR_BORDERSEL		3
CLR_BORDERSPR		4
CLR_TEXTSEL			5
CLR_TEXTNORMAL		6
*/

COLORREF CHSMenu::m_clrMenu[CLRCOUNT_BASE] =
											{ GetSysColor( COLOR_HIGHLIGHT ),
											  GetSysColor( COLOR_MENU ),
											  RGB( 170, 170, 170 ),
											  RGB( 47 , 60 , 174 ),
											  RGB( 160, 160, 160 ),
											  GetSysColor( COLOR_HIGHLIGHTTEXT ),
											  GetSysColor( COLOR_MENUTEXT ),
											  GetSysColor( COLOR_HIGHLIGHTTEXT )
											};

UINT	CHSMenu::m_nMenuEdge		= 3;
UINT	CHSMenu::m_nPopupDelay		= 300;
UINT	CHSMenu::m_nFontHeight		= 18;
UINT	CHSMenu::m_nMenuAniType		= ANIMATE_NONE;
UINT    CHSMenu::m_nMenuAniStep		= 12;
UINT    CHSMenu::m_nMenuAniDelay	= 100;
UINT	CHSMenu::m_nItemAniType		= ANIMATE_NONE;
UINT    CHSMenu::m_nItemAniStep		= 4;
UINT    CHSMenu::m_nItemAniDelay	= 60;
HFONT	CHSMenu::m_hFont			= (HFONT)GetStockObject( DEFAULT_GUI_FONT );
ULONG	CHSMenu::m_ulMenuFlag		= 0;

PFNCUSTOMMENU		CHSMenu::m_pfnCustomMenu	 = (PFNCUSTOMMENU)NULL;
PFNCUSTOMMENUITEM	CHSMenu::m_pfnCustomMenuItem = (PFNCUSTOMMENUITEM)NULL;

//////////////////////////////////////////////////////////////////////

IMPLEMENT_DYNAMIC( CHSMenu, CObject );

WORD CHSMenu::GetVersion()
{
	return MAKEWORD( 3, 8 );
}

CHSMenu::CHSMenu()
{
}

CHSMenu::~CHSMenu()
{
}

// Create a HSMenu
BOOL CHSMenu::CreateMenu( void )
{
	Initialize();

	// Register HSMenu
	if ( (m_ulMenuFlag & MENU_REGISTERED) == 0 )
	{
		WNDCLASS	wc;

		wc.style			= 0;
		wc.cbClsExtra		= 0;
		wc.cbWndExtra		= 0;
		wc.lpszMenuName		= NULL;
		wc.hbrBackground	= NULL;
		wc.hIcon			= NULL;

		wc.hCursor			= ::LoadCursor( NULL, IDC_ARROW );
		wc.hInstance		= AfxGetInstanceHandle();
		wc.lpfnWndProc		= lpfnWndProc;
		wc.lpszClassName	= "HSMENU_PRODUCT_BY_HANSONG";

		if ( !::RegisterClass( &wc ) )
			return FALSE;

		m_uMenuFlag |= MENU_REGISTERED;
	}

	return TRUE;
}

// Initialize Parameter
inline void CHSMenu::Initialize( void )
{
	m_pParent		= NULL;
	m_uMenuFlag		= MENU_NORMAL;
	m_nMenuHeight	= m_nMenuEdge*2 + MENUCAPTION;
	m_nMenuWidth	= m_nMenuEdge*2 + 0;
	m_nCurSel		= SELNONE;
	m_nCurPop		= SELNONE;
	m_nSprHeight	= 5;
	m_nMenuItemHeight = 22;

	m_qMenuItem.clear();
}

void CHSMenu::SetState(UINT uFlag, int bSet)
{
	if ( bSet )
		 m_uMenuFlag |=  ( uFlag );
	else m_uMenuFlag &= ~( uFlag );
}

BOOL CHSMenu::GetState(UINT uFlag) const
{
	return ( ( m_uMenuFlag & ( uFlag ) ) != 0ul );
}
/*
void CHSMenu::AppendMenu(UINT uFlag, UINT uID, ULONG ulData, LPCSTR pszName)
{
	AppendMenu( pszName, uID, ulData, uFlag );
}
*/
// Append a New menu item to end
void CHSMenu::AppendMenu(LPCTSTR pszName, UINT uID, ULONG ulData, UINT uFlags)
{
	HSITEM	MenuItem;

	MenuItem.m_uFlags = ( uFlags & ITEM_X );
	MenuItem.m_ulData  = ulData;
	MenuItem.m_uID = uID;
	MenuItem.m_strName = pszName ? pszName : "( Empty )";

	// Save New Item informations
	m_qMenuItem.push_back( MenuItem );
}

// Append a popup menu item
BOOL CHSMenu::AppendPopup(LPCTSTR pszName, CHSMenu *pPopupMenu, UINT uID, ULONG ulData, UINT uFlags)
{
	if ( pPopupMenu && pPopupMenu->m_pParent )
		return FALSE;

	AppendMenu( pszName, uID, ulData, uFlags&~ITEM_SEPARATOR );

	return SetSubMenu( m_qMenuItem.size()-1, pPopupMenu, MF_BYPOSITION );
}

// Insert a menu item 
BOOL CHSMenu::InsertMenu(int nItem, LPCTSTR pszName, UINT uID, ULONG ulData, UINT uFlags, UINT uFlag)
{
	if ( ( nItem = GetItemIndex( nItem, uFlag ) ) == FINDNONE )
		return FALSE;

	if ( m_qMenuItem.size() < 2 )
		AppendMenu( pszName, uID, ulData, uFlags );
	else
	{
		HSITEM	MenuItem;
		HSITEM& tMenuItem = m_qMenuItem[nItem];

		MenuItem.m_uFlags = ( uFlags & ITEM_X );
		MenuItem.m_ulData  = ulData;
		MenuItem.m_uID = uID;
		MenuItem.m_strName = pszName ? pszName : "( Empty )";

		// Save New Item informations
		m_qMenuItem.insert( m_qMenuItem.begin() + nItem, MenuItem );
	}

	return TRUE;
}

BOOL CHSMenu::InsertPopup(int nItem, LPCTSTR pszName, CHSMenu *pPopupMenu, UINT uID, ULONG ulData, UINT uFlags, UINT uFlag)
{
	if ( m_qMenuItem.size() < 2 )
		return AppendPopup( pszName, pPopupMenu, uID, ulData, uFlags );
	else
	{
		if ( ( pPopupMenu && pPopupMenu->m_pParent ) ||
		     ( uFlags & ITEM_SEPARATOR )			 ||
			 !InsertMenu( nItem, pszName, uID, ulData, uFlags, uFlag )
		   ) return FALSE;

		SetSubMenu( nItem, pPopupMenu, uFlag );
	}
	
	return TRUE;
}

BOOL CHSMenu::LoadMenu(UINT uIDResource, int nMenuPos )
{
	CMenu *pMenu = new CMenu;

	if ( pMenu->LoadMenu( uIDResource ) )
	{
//		FreeMenu();
		MapMenuFrom( pMenu->GetSubMenu( nMenuPos ) );
		pMenu->DestroyMenu();

		delete pMenu;
		return TRUE;
	}

	delete pMenu;
	return FALSE;
}


void CHSMenu::MapMenuFrom( CMenu *pMenu )
{
	CString strText;
	int nTotalMenu	 = pMenu->GetMenuItemCount();

	CreateMenu();

	for ( int nPosition=0; nPosition<nTotalMenu; nPosition++ )
	{
 		pMenu->GetMenuString( nPosition, strText, MF_BYPOSITION );

 		UINT	uID		= pMenu->GetMenuItemID( nPosition );
 		UINT	uFlags	= pMenu->GetMenuState( nPosition, MF_BYPOSITION );

 		if ( uID == (UINT)-1 )
 		{
 			CMenu *pMenuPop = pMenu->GetSubMenu( nPosition );

 			if ( pMenuPop )
 			{
 				CHSMenu *pHSMenuPop = new CHSMenu;
  				pHSMenuPop->MapMenuFrom( pMenuPop );
				AppendPopup( strText, pHSMenuPop, uID, NULL, uFlags );
			}
 		}
 		else
 		{
 			AppendMenu( strText, uID, NULL, uFlags );
 		}
	}
}


void CHSMenu::FreeMenu()
{
	CPtrArray	arypHSMenu;

	GetPopMenuArray( this, &arypHSMenu );
	DestroyAllMenu();

	//Start from 1
	int nTotalItem = arypHSMenu.GetSize();

	for ( int nItem=1; nItem<nTotalItem; nItem++ )
	{
		CHSMenu *pHSMenu = (CHSMenu*)arypHSMenu.GetAt( nItem );

		delete pHSMenu;		//  内存泄漏?????????????
	}

	Initialize();
}

void CHSMenu::GetPopMenuArray( CHSMenu* pHSMenu, CPtrArray* pPtrArray )
{
	pPtrArray->Add( (void*)pHSMenu );

	int nTotalMenu = pHSMenu->GetMenuItemCount();

	for ( int nItem=0; nItem<nTotalMenu; nItem++ )
	{
		CHSMenu *pDel = m_qMenuItem[nItem].m_pPopupHSMenu;

		if ( pDel )
			 pDel->GetPopMenuArray( pDel, pPtrArray );
	}
}
// Delete menu item
BOOL CHSMenu::DeleteMenu(int nItem, UINT uFlag)
{
	if ( ( nItem = GetItemIndex( nItem, uFlag ) ) == FINDNONE )
		return FALSE;

	SetSubMenu( nItem, NULL, uFlag );

	if ( nItem == ( m_qMenuItem.size() - 1 ) )	// must do this first
	{	// Remove The Last Item
		m_nMenuHeight -= m_qMenuItem[nItem].m_nHeight;
		m_qMenuItem.pop_back();
	}
	else
	if ( nItem == 0 )
		m_qMenuItem.pop_front();
	else
		m_qMenuItem.erase( m_qMenuItem.begin() + nItem );

	int iend = m_qMenuItem.size();

	return TRUE;
}

// Enable or Disable a Menu item
BOOL CHSMenu::EnableMenuItem(int nItem, UINT uItemFlags, UINT uFlag)
{
	if ( ( nItem = GetItemIndex( nItem, uFlag ) ) == FINDNONE )
		return FALSE;
	
	if ( uItemFlags == ITEM_ENABLE )
	{
		m_qMenuItem[nItem].m_uFlags &= ~( ITEM_DISABLE | ITEM_GRAY );
	}
	else
	{
		if ( uItemFlags & ITEM_DISABLE )
			m_qMenuItem[nItem].m_uFlags |= ITEM_DISABLE;

		if ( uItemFlags & ITEM_GRAY )
			m_qMenuItem[nItem].m_uFlags |= ITEM_GRAY;
	}

	return TRUE;
}


// Return Current Selected Item, none to return ( SELNONE )
int CHSMenu::GetCurSelItem( void ) const
{
	return m_nCurSel;
}

// Get the Total item 
int CHSMenu::GetMenuItemCount() const
{
	return (int)m_qMenuItem.size();
}

// Private FN
int CHSMenu::GetItemIndex(int nItem, UINT uFlag) const
{
	if ( m_qMenuItem.size() == 0 )
		return FINDNONE;

	int nIndex = FINDNONE;

	if ( uFlag == MF_BYPOSITION )
	{
		if ( nItem >= 0 && nItem < m_qMenuItem.size() ) 
			nIndex = nItem;
	}
	else
	{
		DEQUEITEM::size_type  index, iend;

		iend = m_qMenuItem.size();

		for ( index = 0; index < iend; index++ )
			if ( m_qMenuItem[index].m_uID == (UINT)nItem ) 	
			{
				nIndex = (int)index;
				break;
			}
	}

	return nIndex;
}

// Get the submenu of this item, return NULL if none
CHSMenu* CHSMenu::GetSubMenu(int nItem, UINT uFlag) const
{
	if ( ( nItem = GetItemIndex( nItem, uFlag ) ) == FINDNONE )
		return NULL;

	return (CHSMenu*)m_qMenuItem[nItem].m_pPopupHSMenu;
}

// Set a submenu for this item
BOOL CHSMenu::SetSubMenu(int nItem, CHSMenu *pPopupMenu, UINT uFlag)
{
	if ( ( nItem = GetItemIndex( nItem, uFlag ) ) == FINDNONE )
		return FALSE;

	if ( pPopupMenu && pPopupMenu->m_pParent )
		return FALSE;
	
	HSITEM& MenuItem = m_qMenuItem[nItem];

	if ( MenuItem.m_uFlags & ITEM_SEPARATOR )
		return FALSE;

	if ( MenuItem.m_pPopupHSMenu )
	{
		MenuItem.m_uFlags &= ~ITEM_POPUP;
		MenuItem.m_pPopupHSMenu->m_pParent = NULL;
		MenuItem.m_pPopupHSMenu->SetState( MENU_CHILD, FALSE );
	}

	if ( pPopupMenu )
	{
		MenuItem.m_uFlags |= ITEM_POPUP;
		pPopupMenu->m_pParent = this;
		pPopupMenu->SetState( MENU_CHILD, TRUE );
	}

	MenuItem.m_pPopupHSMenu = pPopupMenu;
	return TRUE;
}

// Set addition data for a item
BOOL CHSMenu::SetMenuData(int nItem, ULONG ulData, UINT uFlag)
{
	if ( ( nItem = GetItemIndex( nItem, uFlag ) ) == FINDNONE )
		return FALSE;

	m_qMenuItem[nItem].m_ulData = ulData;
	return TRUE;
}

// Get menu item text
BOOL CHSMenu::GetMenuString(int nItem, LPTSTR lpsName, int nCount, UINT uFlag) const
{
	if ( ( nItem = GetItemIndex( nItem, uFlag ) ) == FINDNONE )
		return FALSE;

	return ( lstrcpyn( lpsName, m_qMenuItem[nItem].m_strName.c_str(), nCount ) != NULL );
}

// Set menu item text
BOOL CHSMenu::GetMenuString(int nItem, CString &strName, UINT uFlag) const
{
	if ( ( nItem = GetItemIndex( nItem, uFlag ) ) == FINDNONE )
		return FALSE;

	strName = m_qMenuItem[nItem].m_strName.c_str();
	return TRUE;
}

// Set Menu Item Text
BOOL CHSMenu::SetMenuString(int nItem, LPCTSTR lpszNewName, UINT uFlag)
{
	if ( ( nItem = GetItemIndex( nItem, uFlag ) ) == FINDNONE )
		return FALSE;

	m_qMenuItem[nItem].m_strName = lpszNewName ? lpszNewName : "( Empty )";

	return TRUE;
}

// Get addition item date
BOOL CHSMenu::GetMenuData(int nItem, ULONG *pulData, UINT uFlag) const
{
	if ( ( nItem = GetItemIndex( nItem, uFlag ) ) == FINDNONE )
		return FALSE;

	*pulData = m_qMenuItem[nItem].m_ulData;
	return TRUE;
}

BOOL CHSMenu::GetMenuItemRect(int nItem, RECT *prcItem, UINT uFlag) const
{
	if ( ( nItem = GetItemIndex( nItem, uFlag ) ) == FINDNONE )
		return FALSE;

	const HSITEM& MenuItem = m_qMenuItem[nItem];

	prcItem->left	= m_nMenuEdge;
	prcItem->top	= MenuItem.m_nTop;
	prcItem->right	= m_nMenuWidth - m_nMenuEdge;
	prcItem->bottom = MenuItem.m_nTop + MenuItem.m_nHeight;

	return TRUE;
}

// Get Menu item Flags
UINT CHSMenu::GetMenuState(int nItem, UINT uFlag) const
{
	if ( ( nItem = GetItemIndex( nItem, uFlag ) ) == FINDNONE )
		return 0;

	return ( m_qMenuItem[nItem].m_uFlags );
}


BOOL CHSMenu::SetMenuState(int nItem, UINT uFlags, UINT uFlag)
{
	if ( ( nItem = GetItemIndex( nItem, uFlag ) ) == FINDNONE )
		return FALSE;

	m_qMenuItem[nItem].m_uFlags = (  uFlags & ITEM_X );

	return TRUE;
}

BOOL CHSMenu::ModifyMenu(int nItem, UINT uID, ULONG ulData, UINT uFlags, UINT uFlag)
{
	if ( ( nItem = GetItemIndex( nItem, uFlag ) ) == FINDNONE )
		return FALSE;

	HSITEM& MenuItem  = m_qMenuItem[nItem];
	MenuItem.m_uID    = uID;
	MenuItem.m_ulData  = ulData;
	MenuItem.m_uFlags = ( uFlags & ITEM_X );

	return TRUE;
}

// Set menu item ID
BOOL CHSMenu::SetMenuID(int nItem, UINT uID, UINT uFlag)
{
	if ( ( nItem = GetItemIndex( nItem, uFlag ) ) == FINDNONE )
		return FALSE;

	m_qMenuItem[nItem].m_uID = uID;
	return TRUE;
}

⌨️ 快捷键说明

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