📄 menuex.cpp
字号:
for(nIndex = 0; nIndex < (UINT)m_MenuItemArr.GetSize(); nIndex++)
{
pMenuItem = m_MenuItemArr.GetAt(nIndex);
// remove menu item by position match command ID
if(pMenuItem->nID == nPosition)
return RemoveMenu(nIndex,MF_BYPOSITION);
}
// found menu item from submenu of this menu
CMenuEx* pSubMenu=FindPopupMenuFromID(nPosition);
if(pSubMenu==NULL)
return FALSE; // not found
else
return pSubMenu->RemoveMenu(nIndex,MF_BYPOSITION); // remove menu item from submenu
}
return FALSE;
}
/////////////////////////////////////////////////////////////////////////////
BOOL CMenuEx::ModifyMenu(UINT nPosition, UINT nFlags, UINT nIDNewItem, LPCTSTR lpszNewItem)
{
UINT nIndex;
LPMENUITEM pMenuItem;
CDC *pDC =AfxGetMainWnd()->GetDC();
CSize size;
// modify menu item by position
if(nFlags & MF_BYPOSITION)
{
if(!CMenu::ModifyMenu(nPosition,nFlags,nIDNewItem,lpszNewItem))
{
// fail to modify menu
AfxGetMainWnd()->ReleaseDC(pDC);
return FALSE;
}
pMenuItem=GetMenuItem(nPosition);
if(pMenuItem==NULL)
return FALSE;
if(nFlags&MF_SEPARATOR)
{
// modify menu item to separator
pMenuItem->strText = "";
pMenuItem->nID = 0;
pMenuItem->itemSize=CSize(0,m_nSeparator);
pMenuItem->pImageList=m_pImageList;
pMenuItem->pDisabledImageList=m_pDisabledImageList;
pMenuItem->pHotImageList=m_pHotImageList;
pMenuItem->nImageIndex=-1;
pMenuItem->bIsSubMenu=FALSE;
pMenuItem->pSubMenu=NULL;
}
else if(nFlags&MF_POPUP)
{
// modify menu item to popupmenu item
CMenuEx* pSubMenu=new CMenuEx;
pSubMenu->SetPopupMenu(TRUE);
pSubMenu->LoadMenu((HMENU)nIDNewItem);
pMenuItem->strText = lpszNewItem;
pMenuItem->nID = -1;
size=pDC->GetTextExtent(lpszNewItem);
pMenuItem->itemSize.cx=size.cx+25;
pMenuItem->itemSize.cy=2;
pMenuItem->pImageList=m_pImageList;
pMenuItem->pDisabledImageList=m_pDisabledImageList;
pMenuItem->pHotImageList=m_pHotImageList;
pMenuItem->nImageIndex=-1;
pMenuItem->bIsSubMenu=TRUE;
pMenuItem->pSubMenu=pSubMenu;
}
else // MF_STRING
{
// modify menu item to normal menu item
pMenuItem->strText = lpszNewItem;
pMenuItem->nID = nIDNewItem;
size=pDC->GetTextExtent(lpszNewItem);
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;
}
return TRUE;
}
else if(nFlags & MF_BYCOMMAND)
{
// modify menu item by command ID
for(nIndex = 0; nIndex < (UINT)m_MenuItemArr.GetSize(); nIndex++)
{
pMenuItem=m_MenuItemArr.GetAt(nIndex);
// modify ID matched menu item by position
if(pMenuItem->nID == nPosition)
return ModifyMenu(nIndex,MF_BYPOSITION,nIDNewItem,lpszNewItem);
}
// walk through all items, looking for ID matched popupmenu
CMenuEx* pSubMenu=FindPopupMenuFromID(nPosition);
if(pSubMenu==NULL)
return FALSE; // not found
else
return pSubMenu->ModifyMenu(nPosition,nFlags,nIDNewItem,lpszNewItem);
}
return FALSE;
}
/////////////////////////////////////////////////////////////////////////////
CMenuEx* CMenuEx::GetSubMenu(int nPosition)
{
// get submenu by position based zero
// return NULL if do not exist
if((UINT)nPosition>(m_MenuItemArr.GetSize()-1))
return NULL;
return m_MenuItemArr.GetAt(nPosition)->pSubMenu;
}
/////////////////////////////////////////////////////////////////////////////
CMenuEx* CMenuEx::FindPopupMenuFromID(UINT nID)
{
ASSERT_VALID(this);
// walk through all items, looking for ID match
UINT nItems = GetMenuItemSize();
for (int iItem = 0; iItem < (int)nItems; iItem++)
{
CMenuEx* pPopup = GetSubMenu(iItem);
if (pPopup != NULL)
{
// recurse to child popup
pPopup = FindPopupMenuFromID(nID);
// check popups on this popup
if (pPopup != NULL)
return pPopup;
}
else if (GetMenuItemID(iItem) == nID)
{
// it is a normal item inside this popup
return this;
}
}
// not found
return NULL;
}
/////////////////////////////////////////////////////////////////////////////
void CMenuEx::DrawItem(LPDRAWITEMSTRUCT lpDIS)
{
// chech this is ownerdrawn menu or not
if(lpDIS->CtlType!=ODT_MENU)
return;
// drawn device context for draw menu
CDC* pDC=CDC::FromHandle(lpDIS->hDC);
LPMENUITEM lpMenuItem=(LPMENUITEM)lpDIS->itemData;
// rect region of device context
CRect rect=CRect(lpDIS->rcItem);
// draw background of menu item
DrawBackground(pDC,rect);
// draw selected
DrawSelected(pDC,rect,lpDIS);
// draw menu text
DrawMenuText(pDC,rect,lpDIS);
//draw menu imagelist
DrawMenuImage(pDC,rect,lpDIS);
}
/////////////////////////////////////////////////////////////////////////////
void CMenuEx::DrawBackground(CDC* pDC,CRect rect)
{
CBrush BGBrush(m_crBackground);
CBrush LeftBrush(m_crLeft);
CRect rcLeft=rect;
rcLeft.right = rcLeft.left+m_szImage.cx+2;
pDC->FillRect(rect,&BGBrush);
pDC->FillRect(rcLeft,&LeftBrush);
}
/////////////////////////////////////////////////////////////////////////////
void CMenuEx::DrawMenuImage(CDC *pDC, CRect rect,LPDRAWITEMSTRUCT lpDIS)
{
CRect rcImage=rect;
LPMENUITEM lpMenuItem=(LPMENUITEM)lpDIS->itemData;
rcImage.left+=1;
rcImage.right=rcImage.left+m_szImage.cx;
rcImage.top+=1;
rcImage.bottom=rcImage.top+m_szImage.cy;
// menu item style is checked
// draw "√" instead of image
if(lpDIS->itemState & ODS_CHECKED)
{
CString check("√");
CPen* pBorderPen=new CPen(PS_SOLID,1,m_crSelectedBroder);
CBrush* pFillBrush=new CBrush(m_crSelectedFill);
CPen* pOldPen= pDC->SelectObject(pBorderPen);
CBrush* pOldBrush= pDC->SelectObject(pFillBrush);
pDC->Rectangle(rcImage);
pDC->SelectObject(pOldPen);
pDC->SelectObject(pOldBrush);
CSize size=pDC->GetTextExtent(check);
rcImage.left=rcImage.left+(rcImage.Width()-size.cx)/2;
rcImage.top=rcImage.top+(rcImage.Height()-size.cy)/2-4;
pDC->SetBkMode(TRANSPARENT);
if(lpDIS->itemState & ODS_GRAYED)
{
// draw grayed "√"
pDC->DrawState(rcImage.TopLeft(), rcImage.Size(),check, DSS_DISABLED, TRUE, 0, (HBRUSH)NULL);
}
else
{
// set text color for different text style
if(lpDIS->itemState & ODS_SELECTED)
pDC->SetTextColor(m_crTextSelected);
else
pDC->SetTextColor(m_crText);
// draw normal "√"
pDC->DrawText(check,rcImage,DT_EXPANDTABS|DT_VCENTER|DT_SINGLELINE);
}
pDC->SetBkMode(OPAQUE);
}
else
{
// draw imagelist of menu item
// if menu item has image(nImageIndex!=-1)
if(lpMenuItem->nImageIndex !=-1)
{
CImageList* pImageList=lpMenuItem->pImageList;
if((lpDIS->itemState&ODS_GRAYED)&&(lpMenuItem->pDisabledImageList!=NULL))
{
// draw disabled image
pImageList=lpMenuItem->pDisabledImageList;
}
else if((lpDIS->itemState&ODS_SELECTED)&&(lpMenuItem->pHotImageList!=NULL))
{
// draw selected image
pImageList=lpMenuItem->pHotImageList;
}
// draw NO.nImageIndex image of imagelist
pImageList->Draw(pDC,lpMenuItem->nImageIndex,rcImage.TopLeft(),ILD_TRANSPARENT);
}
}
}
/////////////////////////////////////////////////////////////////////////////
void CMenuEx::DrawMenuText(CDC *pDC, CRect rect,LPDRAWITEMSTRUCT lpDIS)
{
CRect rcText=rect;
LPMENUITEM lpMenuItem=(LPMENUITEM)lpDIS->itemData;
rcText.left = rcText.left+m_szImage.cx+2+8;
// not use background color when draw text
pDC->SetBkMode(TRANSPARENT);
if(lpMenuItem->nID==0)
{
// draw separator
rcText.top =rcText.Height()/2+rcText.top-1;
rcText.bottom =rcText.top +1;
pDC->FillSolidRect(rcText,RGB(197,194,184));
}
else
{
// calculate text position
CSize size=pDC->GetTextExtent(lpMenuItem->strText);
rcText.top=rcText.top+(rcText.Height()-size.cy)/2;
if(lpDIS->itemState & ODS_GRAYED)
{
// draw grayed text
pDC->DrawState(rcText.TopLeft(), rcText.Size(), lpMenuItem->strText, DSS_DISABLED, TRUE, 0, (HBRUSH)NULL);
}
else
{
// set text color
if(lpDIS->itemState & ODS_SELECTED)
pDC->SetTextColor(m_crTextSelected);
else
pDC->SetTextColor(m_crText);
// draw normal text
pDC->DrawText(lpMenuItem->strText,rcText,DT_LEFT | DT_EXPANDTABS | DT_VCENTER);
}
}
pDC->SetBkMode(OPAQUE);
}
/////////////////////////////////////////////////////////////////////////////
void CMenuEx::DrawSelected(CDC *pDC, CRect rect,LPDRAWITEMSTRUCT lpDIS)
{
CRect rcText=rect;
LPMENUITEM lpMenuItem=(LPMENUITEM)lpDIS->itemData;
// separator,grayed menu item,disabled menu item
// can not be selected
if((lpMenuItem->nID==0)||(lpDIS->itemState & ODS_GRAYED)||(lpDIS->itemState & ODS_DISABLED))
return;
// draw selected recatangle use special color
// if current menu item is selected
if(lpDIS->itemState & ODS_SELECTED )
{
CPen* pBorderPen=new CPen(PS_SOLID,1,m_crSelectedBroder);
CBrush* pFillBrush=new CBrush(m_crSelectedFill);
CPen* pOldPen= pDC->SelectObject(pBorderPen);
CBrush* pOldBrush= pDC->SelectObject(pFillBrush);
pDC->Rectangle(rect); // draw selected rectangle
pDC->SelectObject(pOldPen);
pDC->SelectObject(pOldBrush);
}
}
/////////////////////////////////////////////////////////////////////////////
void CMenuEx::SetImageList(CImageList* pImageList)
{
if(pImageList==NULL)
return;
IMAGEINFO info;
LPMENUITEM lpMenuItem;
m_pImageList =pImageList;
// get imagelist size
pImageList->GetImageInfo(0,&info);
m_szImage.cx=info.rcImage.right-info.rcImage.left;
m_szImage.cy=info.rcImage.bottom-info.rcImage.top;
for(int i = 0; i < m_MenuItemArr.GetSize(); i++)
{
lpMenuItem=m_MenuItemArr.GetAt(i);
// set normal imagelist for menu item
lpMenuItem->pImageList=pImageList;
// set submenu imagelist
if(lpMenuItem->bIsSubMenu)
lpMenuItem->pSubMenu->SetImageList(pImageList);
}
}
/////////////////////////////////////////////////////////////////////////////
void CMenuEx::SetDisabledImageList(CImageList* pImageList)
{
if(pImageList==NULL)
return;
LPMENUITEM lpMenuItem;
// update disabled imagelist
m_pDisabledImageList =pImageList;
if(m_pImageList==NULL&&m_pHotImageList==NULL)
{
IMAGEINFO info;
// only set disabled imagelist
// get imagelist size
pImageList->GetImageInfo(0,&info);
m_szImage.cx=info.rcImage.right-info.rcImage.left;
m_szImage.cy=info.rcImage.bottom-info.rcImage.top;
}
for(int i = 0; i < m_MenuItemArr.GetSize(); i++)
{
lpMenuItem=m_MenuItemArr.GetAt(i);
lpMenuItem->pDisabledImageList=pImageList;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -