📄 menuex.cpp
字号:
#include "stdafx.h"
#include "MenuEx.h"
IMPLEMENT_DYNAMIC( CMenuEx, CMenu )
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CMenuEx::CMenuEx()
{
m_bPopupMenu=FALSE; // initialize this menu flag
// FALSE indicate this menu is top-level menu
// TRUE means this menu is popupmenu
m_nSeparator = 10; // separator menu item 's height
// initialize color attribute
m_crBackground = ::GetSysColor(COLOR_MENU);
m_crText =::GetSysColor(COLOR_MENUTEXT);
m_crTextSelected =::GetSysColor(COLOR_MENUTEXT);
m_crLeft=RGB(236,233,216);
m_crSelectedBroder=RGB(49,106,197);
m_crSelectedFill=RGB(200,220,253);
// no normal imagelist
m_pImageList=NULL;
m_pDisabledImageList=NULL;
m_pHotImageList=NULL;
// default menu image size
m_szImage=CSize(20,20);
}
/////////////////////////////////////////////////////////////////////////////
CMenuEx::~CMenuEx()
{
// destroy menu and free all variable
DestroyMenu();
}
/////////////////////////////////////////////////////////////////////////////
BOOL CMenuEx::DestroyMenu()
{
// delete all imagelist
if(m_pImageList!=NULL)
m_pImageList->DeleteImageList();
if(m_pDisabledImageList!=NULL)
m_pDisabledImageList->DeleteImageList();
if(m_pHotImageList!=NULL)
m_pHotImageList->DeleteImageList();
for(int i = 0; i < m_MenuItemArr.GetSize(); i++)
{
MENUITEM *pMenuItem = m_MenuItemArr.GetAt(i);
// destroy submenu
if(pMenuItem->bIsSubMenu)
pMenuItem->pSubMenu->DestroyMenu();
// remove menu item from array
m_MenuItemArr.RemoveAt(i);
// free menuitem struct
delete pMenuItem;
}
return CMenu::DestroyMenu();
}
/////////////////////////////////////////////////////////////////////////////
BOOL CMenuEx::LoadMenu(UINT nIDResource)
{
// load menu from menu editor created resouce
CMenu Menu;
Menu.LoadMenu(nIDResource);
// empty all variable
if(m_hMenu!=NULL)
DestroyMenu();
if(m_bPopupMenu)
{
// create popupmenu
if(!CreatePopupMenu())
return FALSE;
}
else
{
// create top-level menu
if(!CreateMenu())
return FALSE;
}
return LoadMenu(Menu);
}
/////////////////////////////////////////////////////////////////////////////
BOOL CMenuEx::LoadMenu(HMENU hMenu)
{
// load menu from global HMENU handle
CMenu Menu;
Menu.Attach(hMenu);
// empty all variable
if(m_hMenu!=NULL)
DestroyMenu();
if(m_bPopupMenu)
{
// create popupmenu
if(!CreatePopupMenu())
return FALSE;
}
else
{
// create top-level menu
if(!CreateMenu())
return FALSE;
}
return LoadMenu(Menu);
}
/////////////////////////////////////////////////////////////////////////////
BOOL CMenuEx::LoadMenu(LPCTSTR lpszResourceName)
{
// load menu from resource string
CMenu Menu;
Menu.LoadMenu(lpszResourceName);
// empty all variable
if(m_hMenu!=NULL)
DestroyMenu();
if(m_bPopupMenu)
{
// create popupmenu
if(!CreatePopupMenu())
return FALSE;
}
else
{
// create top-level menu
if(!CreateMenu())
return FALSE;
}
return LoadMenu(Menu);
}
/////////////////////////////////////////////////////////////////////////////
BOOL CMenuEx::LoadMenu(CMenu& Menu)
{
UINT nID;
UINT nIndex;
UINT nState;
CString strMenu;
// fill this menu use temp menu
for(nIndex = 0; nIndex < Menu.GetMenuItemCount(); nIndex++)
{
nID=Menu.GetMenuItemID(nIndex); // get menu ID
nState=Menu.GetMenuState(nIndex,MF_BYPOSITION); // get menu state
Menu.GetMenuString(nIndex,strMenu,MF_BYPOSITION);// get menu name
if(nID==0)
{
// insert separator
if(!AppendMenu(MF_SEPARATOR))
return FALSE;
}
else if(nID==-1)
{
// bypass popupmenu's item number
nState&=0x00FFL;
// insert popupmenu
if(!AppendMenu(MF_POPUP|nState,(UINT)Menu.GetSubMenu(nIndex)->Detach(),strMenu))
return FALSE;
}
else
{
// insert normal menu item
if(!AppendMenu(MF_STRING|nState,nID,strMenu))
return FALSE;
}
}
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
BOOL CMenuEx::AppendMenu(UINT nFlags, UINT nIDNewItem, LPCTSTR lpszNewItem )
{
// append ownerdrawn style menu item to this menu
// get last position of this menu
UINT nIndex=m_MenuItemArr.GetSize();
// insert menu item to last position
// means append menu item
return InsertMenu(nIndex,nFlags|MF_BYPOSITION,nIDNewItem,lpszNewItem);
}
/////////////////////////////////////////////////////////////////////////////
BOOL CMenuEx::InsertMenu(UINT nPosition, UINT nFlags, UINT nIDNewItem , LPCTSTR lpszNewItem )
{
// insert menu item to specific position or command ID
LPMENUITEM pMenuItem;
UINT nIndex;
CSize size;
// mainframe's device context,use to get text size
CDC *pDC =AfxGetMainWnd()->GetDC();
if(nFlags & MF_BYPOSITION)
{
// insert menu item by position
pMenuItem=new MENUITEM;
if(nFlags&MF_SEPARATOR)
{
// insert separator
pMenuItem->strText = ""; // no name
pMenuItem->nID = 0; // separator's ID
pMenuItem->itemSize=CSize(0,m_nSeparator); // separator's default size
pMenuItem->pImageList=NULL; // separator has no image
pMenuItem->pDisabledImageList=NULL;
pMenuItem->pHotImageList=NULL;
pMenuItem->nImageIndex=-1;
pMenuItem->bIsSubMenu=FALSE; // separator must not be popupmenu
pMenuItem->pSubMenu=NULL;
// insert menu item to this menu
if(!CMenu::InsertMenu(nPosition,nFlags,nIDNewItem,lpszNewItem))
{
delete pMenuItem;
AfxGetMainWnd()->ReleaseDC(pDC);
return FALSE;
}
if(m_bPopupMenu)
{
// modify menu item to ownerdrawn style
// if this menu is not a top-level menu
if(!CMenu::ModifyMenu(nPosition,MF_SEPARATOR|MF_BYPOSITION|MF_OWNERDRAW,0,(LPCTSTR)pMenuItem))
{
delete pMenuItem;
AfxGetMainWnd()->ReleaseDC(pDC);
return FALSE;
}
}
// insert menu item to array
m_MenuItemArr.InsertAt(nPosition,pMenuItem);
}
else if(nFlags&MF_POPUP)
{
// insert popupmenu
CMenuEx* pSubMenu=new CMenuEx;
// create new popupmenu
pSubMenu->SetPopupMenu(TRUE);
// load popupmenu from specific handle
pSubMenu->LoadMenu((HMENU)nIDNewItem);
size=pDC->GetTextExtent(lpszNewItem);
pMenuItem->strText = lpszNewItem;
pMenuItem->nID = -1;
// specified menu item size,do not include image's size
pMenuItem->itemSize.cx=size.cx+25;
pMenuItem->itemSize.cy=2;
// specified all imagelist for new menu item
pMenuItem->pImageList=m_pImageList;
pMenuItem->pDisabledImageList=m_pDisabledImageList;
pMenuItem->pHotImageList=m_pHotImageList;
pMenuItem->nImageIndex=-1;
pMenuItem->bIsSubMenu=TRUE;
pMenuItem->pSubMenu=pSubMenu; // popupmenu's pointor
if(!CMenu::InsertMenu(nPosition,nFlags,(UINT)(pSubMenu->m_hMenu),lpszNewItem))
{
delete pMenuItem;
AfxGetMainWnd()->ReleaseDC(pDC);
return FALSE;
}
if(m_bPopupMenu)
{
if(!CMenu::ModifyMenu(nPosition,nFlags|MF_POPUP|MF_BYPOSITION|MF_OWNERDRAW,(UINT)(pSubMenu->m_hMenu),(LPCTSTR)pMenuItem))
{
delete pMenuItem;
AfxGetMainWnd()->ReleaseDC(pDC);
return FALSE;
}
}
m_MenuItemArr.InsertAt(nPosition,pMenuItem);
}
else // if(nFlags & MF_STRING)
{
// insert normal menu item
size=pDC->GetTextExtent(lpszNewItem);
pMenuItem->strText = lpszNewItem;
pMenuItem->nID = nIDNewItem;
pMenuItem->itemSize.cx=size.cx+10;
pMenuItem->itemSize.cy=2;
pMenuItem->pImageList=m_pImageList;
pMenuItem->pDisabledImageList=m_pDisabledImageList;
pMenuItem->pHotImageList=m_pHotImageList;
pMenuItem->nImageIndex=-1;
pMenuItem->bIsSubMenu=FALSE;
pMenuItem->pSubMenu=NULL;
if(!CMenu::InsertMenu(nPosition,nFlags,nIDNewItem,lpszNewItem))
{
delete pMenuItem;
AfxGetMainWnd()->ReleaseDC(pDC);
return FALSE;
}
if(m_bPopupMenu)
{
if(!CMenu::ModifyMenu(nPosition,MF_BYPOSITION|MF_OWNERDRAW,nIDNewItem,(LPCTSTR)pMenuItem))
{
delete pMenuItem;
AfxGetMainWnd()->ReleaseDC(pDC);
return FALSE;
}
}
m_MenuItemArr.InsertAt(nPosition,pMenuItem);
}
return TRUE;
}
else if(nFlags & MF_BYCOMMAND) // insert menu item by command ID
{
for(nIndex = 0; nIndex < (UINT)m_MenuItemArr.GetSize(); nIndex++)
{
pMenuItem=m_MenuItemArr.GetAt(nIndex);
// insert menu item with position
// if the position match command ID
if(pMenuItem->nID == nPosition)
return InsertMenu(nIndex,MF_BYPOSITION,nIDNewItem,lpszNewItem);
}
// do not found menu item in this menu
CMenuEx* pSubMenu=FindPopupMenuFromID(nPosition);
if(pSubMenu==NULL)
{
// not found
AfxGetMainWnd()->ReleaseDC(pDC);
return FALSE;
}
else
{
// insert menu item to submenu
return pSubMenu->InsertMenu(nPosition,nFlags,nIDNewItem ,lpszNewItem);
}
}
AfxGetMainWnd()->ReleaseDC(pDC);
return FALSE;
}
/////////////////////////////////////////////////////////////////////////////
BOOL CMenuEx::RemoveMenu(UINT nPosition, UINT nFlags)
{
UINT nIndex;
LPMENUITEM pMenuItem;
// remove menu item by position
if(nFlags & MF_BYPOSITION)
{
// position out of range of menu item array
if(nPosition>(UINT)(m_MenuItemArr.GetSize()-1))
return FALSE;
// remove menu item from menu item array
m_MenuItemArr.RemoveAt(nPosition);
// remvoe menu item from this menu
if(!CMenu::RemoveMenu(nPosition,nFlags))
return FALSE;
}
else if(nFlags & MF_BYCOMMAND)
{
// remove menu item by command ID
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -