📄 newmenu.cpp
字号:
{
CObject::AssertValid();
}
void CNewMenuItemData::Dump(CDumpContext& dc) const
{
CObject::Dump(dc);
dc << _T("MenuItem: ") << m_szMenuText << _T("\n");
}
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
IMPLEMENT_DYNAMIC(CNewMenu,CMenu);
// Stores list of all sub-menus
CTypedPtrArray<CPtrArray, HMENU> CNewMenu::m_AllSubMenus;
// actual selectet menu-draw mode
CMenuTheme* CNewMenu::m_pActMenuDrawing = NULL;
// one instance of the hook for menu-subclassing
static CNewMenuHook MyNewMenuHookInstance;
// color for drawing menubar
int CNewMenu::cCOLOR_MENUBAR = COLOR_MENU;
// how the menu's are drawn in winXP
BOOL CNewMenu::m_bSelectDisable=TRUE;
static Win32Type g_Shell=IsShellType();
CNewMenu::CNewMenu(HMENU hParent)
: m_hParentMenu(hParent),
m_bIsPopupMenu(FALSE),
m_dwOpenMenu(NULL),
m_LastActiveMenuRect(0,0,0,0)
{
// O.S. - no dynamic icons by default
m_bDynIcons = FALSE;
// Icon sizes default to 16 x 16
m_iconX = 16;
m_iconY = 15;
m_selectcheck = -1;
m_unselectcheck = -1;
checkmaps=NULL;
checkmapsshare=FALSE;
CMenuButton* m_pBar=NULL;
// set the color used for the transparent background in all bitmaps
m_bitmapBackground = CLR_DEFAULT;
}
CNewMenu::~CNewMenu()
{
DestroyMenu();
}
void CNewMenu::SetLastMenuRect(HDC hDC, LPRECT pRect)
{
if(!m_bIsPopupMenu)
{
HWND hWnd = WindowFromDC(hDC);
if(hWnd && pRect)
{
CRect Temp;
GetWindowRect(hWnd,Temp);
m_LastActiveMenuRect = *pRect;
m_LastActiveMenuRect.OffsetRect(Temp.TopLeft());
}
}
}
BOOL CNewMenu::IsNewShell ()
{
return (g_Shell>=Win95);
}
BOOL CNewMenu::OnMeasureItem(const MSG* pMsg)
{
if(pMsg->message==WM_MEASUREITEM)
{
LPMEASUREITEMSTRUCT lpMIS = (LPMEASUREITEMSTRUCT)pMsg->lParam;
if(lpMIS->CtlType==ODT_MENU)
{
CMenu* pMenu=NULL;
if(::IsMenu(UIntToHMenu(lpMIS->itemID)) )
{
pMenu = CMenu::FromHandlePermanent(UIntToHMenu(lpMIS->itemID) );
}
else
{
_AFX_THREAD_STATE* pThreadState = AfxGetThreadState ();
if (pThreadState->m_hTrackingWindow == pMsg->hwnd)
{
// start from popup
pMenu = FindPopupMenuFromIDData(pThreadState->m_hTrackingMenu,lpMIS->itemID,lpMIS->itemData);
}
if(pMenu==NULL)
{
// start from menubar
pMenu = FindPopupMenuFromIDData(::GetMenu(pMsg->hwnd),lpMIS->itemID,lpMIS->itemData);
if(pMenu==NULL)
{
// finaly start from system menu.
pMenu = FindPopupMenuFromIDData(::GetSystemMenu(pMsg->hwnd,FALSE),lpMIS->itemID,lpMIS->itemData);
}
}
}
if(pMenu!=NULL)
{
pMenu->MeasureItem(lpMIS);
return TRUE;
}
}
}
return FALSE;
}
CMenu* CNewMenu::FindPopupMenuFromID(HMENU hMenu, UINT nID)
{
// check for a valid menu-handle
if ( ::IsMenu(hMenu))
{
CMenu *pMenu = CMenu::FromHandlePermanent(hMenu);
if(pMenu)
{
return FindPopupMenuFromID(pMenu,nID);
}
}
return NULL;
}
CMenu* CNewMenu::FindPopupMenuFromIDData(HMENU hMenu, UINT nID, ULONG_PTR pData)
{
// check for a valid menu-handle
if ( ::IsMenu(hMenu))
{
CMenu *pMenu = CMenu::FromHandlePermanent(hMenu);
if(pMenu)
{
return FindPopupMenuFromIDData(pMenu,nID,pData);
}
}
return NULL;
}
CMenu* CNewMenu::FindPopupMenuFromIDData(CMenu* pMenu, UINT nID, ULONG_PTR pData)
{
ASSERT_VALID(pMenu);
// walk through all items, looking for ID match
UINT nItems = pMenu->GetMenuItemCount();
for (int iItem = 0; iItem < (int)nItems; iItem++)
{
CMenu* pPopup = pMenu->GetSubMenu(iItem);
if (pPopup != NULL)
{
// recurse to child popup
pPopup = FindPopupMenuFromIDData(pPopup, nID, pData);
// check popups on this popup
if (pPopup != NULL)
return pPopup;
}
else if (pMenu->GetMenuItemID(iItem) == nID)
{
MENUITEMINFO MenuItemInfo;
::ZeroMemory(&MenuItemInfo,sizeof(MenuItemInfo));
MenuItemInfo.cbSize = sizeof(MenuItemInfo);
MenuItemInfo.fMask = MIIM_DATA;
if(pMenu->GetMenuItemInfo(iItem,&MenuItemInfo,TRUE))
{
if(MenuItemInfo.dwItemData==pData)
{
// it is a normal item inside our popup
return pMenu;
}
}
}
}
// not found
return NULL;
}
CMenu* CNewMenu::FindPopupMenuFromID(CMenu* pMenu, UINT nID)
{
ASSERT_VALID(pMenu);
// walk through all items, looking for ID match
UINT nItems = pMenu->GetMenuItemCount();
for (int iItem = 0; iItem < (int)nItems; iItem++)
{
CMenu* pPopup = pMenu->GetSubMenu(iItem);
if (pPopup != NULL)
{
// recurse to child popup
pPopup = FindPopupMenuFromID(pPopup, nID);
// check popups on this popup
if (pPopup != NULL)
return pPopup;
}
else if (pMenu->GetMenuItemID(iItem) == nID)
{
// it is a normal item inside our popup
return pMenu;
}
}
// not found
return NULL;
}
BOOL CNewMenu::DestroyMenu()
{
// Destroy Sub menus:
int m,n;
int numAllSubMenus = (int)m_AllSubMenus.GetUpperBound();
for(n = numAllSubMenus; n>= 0; n--)
{
if(m_AllSubMenus[n]==this->m_hMenu)
m_AllSubMenus.RemoveAt(n);
}
int numSubMenus = (int)m_SubMenus.GetUpperBound();
for(m = numSubMenus; m >= 0; m--)
{
numAllSubMenus = (int)m_AllSubMenus.GetUpperBound();
for(n = numAllSubMenus; n>= 0; n--)
{
if(m_AllSubMenus[n]==m_SubMenus[m])
m_AllSubMenus.RemoveAt(n);
}
delete((CNewMenu *)FromHandle(m_SubMenus[m]));
}
m_SubMenus.RemoveAll();
// Destroy menu data
int numItems = (int)m_MenuList.GetUpperBound();
for(m = 0; m <= numItems; m++)
{
delete(m_MenuList[m]);
}
m_MenuList.RemoveAll();
if(checkmaps&&!checkmapsshare)
{
delete checkmaps;
checkmaps=NULL;
}
// Call base-class implementation last:
return(CMenu::DestroyMenu());
};
int CNewMenu::GetMenuDrawMode()
{
ASSERT(m_pActMenuDrawing);
return m_pActMenuDrawing->m_dwThemeId;
}
void CNewMenu::SetMenuDrawMode(UINT mode)
{
CMenuTheme* pTheme = CNewMenuHook::FindTheme(mode);
if(pTheme)
{
m_pActMenuDrawing = pTheme;
}
}
HMENU CNewMenu::GetParent()
{
return m_hParentMenu;
}
BOOL CNewMenu::IsPopup()
{
return m_bIsPopupMenu;
}
BOOL CNewMenu::SetSelectDisableMode(BOOL mode)
{
BOOL bOldMode = m_bSelectDisable;
m_bSelectDisable=mode;
return bOldMode;
}
BOOL CNewMenu::GetSelectDisableMode()
{
return m_bSelectDisable;
}
void CNewMenu::MeasureItem( LPMEASUREITEMSTRUCT lpMIS )
{
ASSERT(m_pActMenuDrawing);
BOOL bIsMenuBar = IsMenuBar(UIntToHMenu(lpMIS->itemID));
((*this).*m_pActMenuDrawing->m_pMeasureItem)(lpMIS,bIsMenuBar);
}
void CNewMenu::DrawItem (LPDRAWITEMSTRUCT lpDIS)
{
ASSERT(m_pActMenuDrawing);
BOOL bIsMenuBar = m_hParentMenu ? FALSE: ((m_bIsPopupMenu)?FALSE:TRUE);
(this->*m_pActMenuDrawing->m_pDrawItem)(lpDIS,bIsMenuBar);
}
// Erase the Background of the menu
BOOL CNewMenu::EraseBkgnd(HWND hWnd, HDC hDC)
{
CDC* pDC = CDC::FromHandle (hDC);
CRect Rect;
// Get the size of the menu...
GetClientRect(hWnd, Rect );
pDC->FillSolidRect (Rect,GetSysColor(cCOLOR_MENUBAR));
return TRUE;
}
void CNewMenu::DrawTitle(LPDRAWITEMSTRUCT lpDIS,BOOL bIsMenuBar)
{
ASSERT(m_pActMenuDrawing);
(this->*m_pActMenuDrawing->m_pDrawTitle)(lpDIS,bIsMenuBar);
}
void CNewMenu::DrawMenuTitle(LPDRAWITEMSTRUCT lpDIS, BOOL bIsMenuBar)
{
UNREFERENCED_PARAMETER(bIsMenuBar);
CDC* pDC = CDC::FromHandle(lpDIS->hDC);
CNewMenuItemData* pMenuData = (CNewMenuItemData*)(lpDIS->itemData);
ASSERT(pMenuData);
COLORREF ColA = GetSysColor(COLOR_WINDOW);
COLORREF ColB = GetSysColor(cCOLOR_MENUBAR);
COLORREF colorMenu = MixedColor(ColA,ColB);
CRect rcClipBox;
pDC->GetClipBox(rcClipBox);
// draw the title bar
CRect rect = lpDIS->rcItem;
CPoint TextPoint;
CFont Font;
if(pMenuData->m_nTitleFlags&MFT_SIDE_TITLE)
{
rect.top = rcClipBox.top;
rect.bottom = rcClipBox.bottom;
rect.right += GetSystemMetrics(SM_CXMENUCHECK);
Font.CreateFont(16, 0, 900, 900, FW_BOLD,
0, 0, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
DEFAULT_PITCH,_T("Arial"));
TextPoint = CPoint(rect.left+2, rect.bottom-4);
// DrawGradient(pDC,rect,colorMenu,::GetSysColor(COLOR_ACTIVECAPTION),false);
}
else
{
Font.CreateFont(16, 0, 0, 0, FW_BOLD,
0, 0, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
DEFAULT_PITCH,_T("Arial"));
TextPoint = CPoint(rect.left+2, rect.top);
// DrawGradient(pDC,rect,::GetSysColor(COLOR_ACTIVECAPTION),colorMenu,true);
}
if(pMenuData->m_nTitleFlags&MFT_GRADIENT)
{
if(pMenuData->m_nTitleFlags&MFT_SIDE_TITLE)
{
DrawGradient(pDC,rect,colorMenu,::GetSysColor(COLOR_ACTIVECAPTION),false);
}
else
{
DrawGradient(pDC,rect,::GetSysColor(COLOR_ACTIVECAPTION),colorMenu,true);
}
}
else
{
if(pMenuData->m_nTitleFlags&MFT_ROUND)
{
if(pMenuData->m_nTitleFlags&MFT_SIDE_TITLE)
{
TextPoint.y-=2;
rect.right = rect.left+21;
}
else
{
TextPoint.x+=10;
}
CBrush brush(GetSysColor(COLOR_ACTIVECAPTION));
CPen* pOldPen = (CPen*)pDC->SelectStockObject(WHITE_PEN);
CBrush* pOldBrush = pDC->SelectObject(&brush);
pDC->RoundRect(rect,CPoint(10,10));
pDC->SelectObject(pOldBrush);
pDC->SelectObject(pOldPen);
}
else
{
pDC->FillSolidRect(rect,GetSysColor(COLOR_ACTIVECAPTION));
}
}
if (pMenuData->m_nTitleFlags&MFT_SUNKEN)
{
pDC->Draw3dRect(rect,GetSysColor(COLOR_3DSHADOW),GetSysColor(COLOR_3DHILIGHT));
}
CFont *pOldFont = pDC->SelectObject(&Font);
COLORREF oldColor = pDC->SetTextColor(::GetSysColor(COLOR_CAPTIONTEXT));
int OldMode = pDC->SetBkMode(TRANSPARENT);
if (pMenuData->m_nTitleFlags&MFT_CENTER)
{
SIZE size;
VERIFY(::GetTextExtentPoint32(pDC->m_hDC,pMenuData->m_szMenuText,pMenuData->m_szMenuText.GetLength(),&size));
if (pMenuData->m_nTitleFlags&MFT_SIDE_TITLE)
{
TextPoint.y = rect.bottom - ((rect.Height()-size.cx)>>1);
}
else
{
TextPoint.x = rect.left + ((rect.Width()-size.cx)>>1);
}
}
pDC->TextOut(TextPoint.x,TextPoint.y, pMenuData->GetString());
if(pMenuData->m_nTitleFlags&MFT_LINE)
{
if(pMenuData->m_nTitleFlags&MFT_SIDE_TITLE)
{
CRect rect2(rect.left+20,rect.top+5,rect.left+22,rect.bottom-5);
pDC->Draw3dRect(rect2,GetSysColor(COLOR_3DSHADOW),GetSysColor(COLOR_3DHILIGHT));
rect2.OffsetRect(3,0);
rect2.InflateRect(0,-10);
pDC->Draw3dRect(rect2,GetSysColor(COLOR_3DSHADOW),GetSysColor(COLOR_3DHILIGHT));
}
else
{
CRect rect2(rect.left+2,rect.bottom-7,rect.right-2,rect.bottom-5);
pDC->Draw3dRect(rect2,GetSysColor(COLOR_3DHILIGHT),GetSysColor(COLOR_3DSHADOW));
rect2.OffsetRect(0,3);
rect2.InflateRect(-10,0);
pDC->Draw3dRect(rect2,GetSysColor(COLOR_3DSHADOW),GetSysColor(COLOR_3DHILIGHT));
}
}
pDC->SetBkMode(OldMode);
pDC->SetTextColor(oldColor);
pDC->SelectObject(pOldFont);
}
void CNewMenu::DrawItem_WinXP(LPDRAWITEMSTRUCT lpDIS, BOOL bIsMenuBar)
{
ASSERT(lpDIS != NULL);
CDC* pDC = CDC::FromHandle(lpDIS->hDC);
CRect rect;
CNewMenuItemData* pMenuData = (CNewMenuItemData*)(lpDIS->itemData);
ASSERT(pMenuData);
UINT state = pMenuData->m_nFlags;
COLORREF ColA = GetSysColor(COLOR_WINDOW);
COLORREF ColB = GetSysColor(cCOLOR_MENUBAR);
COLORREF colorMenu = MixedColor(ColA,ColB);
COLORREF colorBitmap = MixedColor(ColB,ColA);
COLORREF colorSel = MidColor(ColA,GetSysColor(COLOR_HIGHLIGHT));
CPen Pen(PS_SOLID,0,GetSysColor(COLOR_HIGHLIGHT));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -