📄 hsmenu.cpp
字号:
// 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 + -