📄 rtmenu.cpp
字号:
///////////////////////////////////////////////////////////////////////////////
//
// MenuXP.cpp : implementation file
//
///////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "RTMenu.h"
#include "RTTools.h"
#include "RTDraw.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#ifndef DWORD_PTR
typedef ULONG DWORD_PTR;
typedef long LONG_PTR;
#endif
#ifndef ODS_HOTLIGHT
#define ODS_HOTLIGHT 0x0040
#endif
#ifndef ODS_INACTIVE
#define ODS_INACTIVE 0x0080
#endif
#ifndef ODS_NOACCEL
#define ODS_NOACCEL 0x0100
#endif
#ifndef DT_HIDEPREFIX
#define DT_HIDEPREFIX 0x00100000
#endif
#ifndef SPI_GETKEYBOARDCUES
#define SPI_GETKEYBOARDCUES 0x100A
#endif
// From <winuser.h>
#ifndef OBM_CHECK
#define OBM_CHECK 32760
#endif
#define IMGWIDTH 16
#define IMGHEIGHT 16
#define IMGPADDING 6
#define TEXTPADDING 8
#define TEXTPADDING_MNUBR 4
#define SM_CXSHADOW 4
const TCHAR _WndPropName_OldProc[] = _T("XPWndProp_OldProc");
const TCHAR _WndPropName_MenuXP[] = _T("XPWndProp_MenuXP");
///////////////////////////////////////////////////////////////////////////////
// Menu item management class
//
class CRTMenuItem
{
protected:
MENUITEMINFO m_miInfo;
CString m_sCaption;
CImgDesc m_ImgDesc;
HIMAGELIST m_hImgList;
int m_nIndex;
public:
CRTMenuItem ();
CRTMenuItem (HMENU hMenu, UINT uItem, bool fByPosition = true);
~CRTMenuItem ();
// Properties
public:
int GetCaption (CString& sCaption) const;
int GetShortCut (CString& sShortCut) const;
bool GetSeparator () const;
bool GetChecked () const;
bool GetRadio () const;
bool GetDisabled () const;
bool GetDefault () const;
HMENU GetPopup () const;
UINT GetID () const;
// Methods
public:
int GetCaptionWidth (CDC* pDC) const;
int GetShortCutWidth (CDC* pDC) const;
int GetHeight (CDC* pDC) const;
bool Draw (CDC* pDC, LPCRECT pRect, bool bSelected, bool bMenuBar = false, bool bHotLight = false, bool bInactive = false, bool bNoAccel = false) const;
public:
static BYTE ms_nCheck;
static CRect ms_rcMRUMenuBarItem;
};
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
BYTE CRTMenuItem::ms_nCheck = 0;
CRect CRTMenuItem::ms_rcMRUMenuBarItem (0, 0, 0, 0);
///////////////////////////////////////////////////////////////////////////////
CRTMenuItem::CRTMenuItem ()
{
memset (&m_miInfo, 0, sizeof(MENUITEMINFO));
}
///////////////////////////////////////////////////////////////////////////////
CRTMenuItem::CRTMenuItem (HMENU hMenu, UINT uItem, bool fByPosition)
{
memset (&m_miInfo, 0, sizeof(MENUITEMINFO));
m_miInfo.cbSize = sizeof(MENUITEMINFO);
m_miInfo.fMask = MIIM_STATE|MIIM_SUBMENU|MIIM_TYPE|MIIM_DATA|MIIM_ID;
VERIFY (::GetMenuItemInfo (hMenu, uItem, fByPosition, &m_miInfo));
if ( !(m_miInfo.fType & MFT_SEPARATOR) )
{
if ( m_miInfo.hSubMenu != NULL )
{
CRTMenu::ms_sSubMenuCaptions.Lookup (m_miInfo.hSubMenu, m_sCaption);
CRTMenu::ms_SubMenuImages.Lookup (m_miInfo.hSubMenu, m_ImgDesc);
}
else
{
CRTMenu::ms_sCaptions.Lookup (m_miInfo.wID, m_sCaption);
CRTMenu::ms_Images.Lookup (m_miInfo.wID, m_ImgDesc);
}
}
}
///////////////////////////////////////////////////////////////////////////////
CRTMenuItem::~CRTMenuItem ()
{
}
///////////////////////////////////////////////////////////////////////////////
int CRTMenuItem::GetCaption (CString& sCaption) const
{
ASSERT(m_miInfo.fMask & MIIM_TYPE);
sCaption = m_sCaption;
int nShortCutPos = sCaption.Find ('\t');
if ( nShortCutPos == -1 )
{
return sCaption.GetLength();
}
sCaption = sCaption.Left (nShortCutPos);
return nShortCutPos-1;
}
///////////////////////////////////////////////////////////////////////////////
int CRTMenuItem::GetShortCut (CString& sShortCut) const
{
ASSERT(m_miInfo.fMask & MIIM_TYPE);
CString sCaption = m_sCaption;
int nShortCutPos = sCaption.Find ('\t');
if ( nShortCutPos == -1 )
{
sShortCut = "";
return 0;
}
int nLength = sCaption.GetLength()-nShortCutPos-1;
sShortCut = sCaption.Right (nLength);
return nLength;
}
///////////////////////////////////////////////////////////////////////////////
bool CRTMenuItem::GetSeparator () const
{
ASSERT(m_miInfo.fMask & MIIM_TYPE);
return (m_miInfo.fType & MFT_SEPARATOR) == MFT_SEPARATOR;
}
///////////////////////////////////////////////////////////////////////////////
bool CRTMenuItem::GetChecked () const
{
ASSERT(m_miInfo.fMask & MIIM_STATE);
return (m_miInfo.fState & MFS_CHECKED) == MFS_CHECKED;
}
///////////////////////////////////////////////////////////////////////////////
bool CRTMenuItem::GetRadio () const
{
ASSERT(m_miInfo.fMask & MIIM_TYPE);
return (m_miInfo.fType & MFT_RADIOCHECK) == MFT_RADIOCHECK;
}
///////////////////////////////////////////////////////////////////////////////
bool CRTMenuItem::GetDisabled () const
{
ASSERT(m_miInfo.fMask & MIIM_STATE);
return (m_miInfo.fState & MFS_GRAYED) == MFS_GRAYED;
}
///////////////////////////////////////////////////////////////////////////////
bool CRTMenuItem::GetDefault () const
{
ASSERT(m_miInfo.fMask & MIIM_STATE);
return (m_miInfo.fState & MFS_DEFAULT) == MFS_DEFAULT;
}
///////////////////////////////////////////////////////////////////////////////
HMENU CRTMenuItem::GetPopup () const
{
ASSERT(m_miInfo.fMask & MIIM_SUBMENU);
return m_miInfo.hSubMenu;
}
///////////////////////////////////////////////////////////////////////////////
UINT CRTMenuItem::GetID () const
{
ASSERT(m_miInfo.fMask & MIIM_ID);
return m_miInfo.wID;
}
///////////////////////////////////////////////////////////////////////////////
int CRTMenuItem::GetCaptionWidth (CDC* pDC) const
{
if ( GetSeparator() )
{
return 0;
}
CString sCaption;
int nLength = 0;
if ( GetCaption (sCaption) > 0 )
{
int nPos = sCaption.Find ('&');
CBoldDC bold (*pDC, GetDefault());
if ( nPos >= 0 )
{
sCaption = sCaption.Left (nPos) + sCaption.Right (sCaption.GetLength()-nPos-1);
}
nLength = pDC->GetTextExtent (sCaption).cx;
}
return nLength;
}
///////////////////////////////////////////////////////////////////////////////
int CRTMenuItem::GetShortCutWidth (CDC* pDC) const
{
if ( GetSeparator() )
{
return 0;
}
CString sShortCut;
int nLength = 0;
if ( GetShortCut (sShortCut) > 0 )
{
CBoldDC bold (*pDC, GetDefault());
nLength = pDC->GetTextExtent (sShortCut).cx;
}
return nLength;
}
///////////////////////////////////////////////////////////////////////////////
int CRTMenuItem::GetHeight (CDC* pDC) const
{
TEXTMETRIC tm;
pDC->GetTextMetrics (&tm);
return GetSeparator() ? tm.tmHeight/2+2 : tm.tmHeight+4;
}
///////////////////////////////////////////////////////////////////////////////
bool CRTMenuItem::Draw (CDC* pDC, LPCRECT pRect, bool bSelected,bool bMenuBar, bool bHotLight, bool bInactive, bool bNoAccel) const
{
COLORREF crBackImg = CLR_NONE;
bool bMenuBarItemSelected = false;
if ( bMenuBar && bSelected )
{
if(CRTMenu::m_MenuBarBitmap[BMP_DOWN] != NULL && CRTMenu::m_bEnableSkin)
{
CRTDraw::RTDrawBitmap(pDC,pRect,CRTMenu::m_MenuBarBitmap[BMP_DOWN],CRTMenu::m_MenuBarBitmapDrawMode[BMP_DOWN]);
}
else
{
CRect rc (pRect);
CPenDC pen (*pDC, ::GetSysColor (COLOR_3DDKSHADOW));
CBrushDC brush (*pDC, HLS_TRANSFORM (::GetSysColor (COLOR_3DFACE), +20, 0));
rc.right -= TEXTPADDING_MNUBR;
ms_rcMRUMenuBarItem = rc;
bMenuBarItemSelected = true;
pDC->Rectangle (rc);
rc.left = rc.right;
rc.right += TEXTPADDING_MNUBR;
pDC->FillSolidRect (rc, ::GetSysColor (COLOR_3DFACE));
for ( int x = 0; x < SM_CXSHADOW; x++ )
{
for ( int y = ( x < 2 ) ? 2-x : 0; y < rc.Height()-x-((x>0)?1:2); y++ )
{
int nMakeSpec = 78+(3-(y==0?0:(y==1?(x<2?0:1):(y==2?(x<2?x:2):x))))*5;
COLORREF cr = pDC->GetPixel (rc.right-x-1, rc.top+y+SM_CXSHADOW);
COLORREF cr2 = RGB(((nMakeSpec * int(GetRValue(cr))) / 100),
((nMakeSpec * int(GetGValue(cr))) / 100),
((nMakeSpec * int(GetBValue(cr))) / 100));
pDC->SetPixel (rc.right-x-1, rc.top+y+SM_CXSHADOW, cr2);
}
}
}
}
else if ( bSelected || (bHotLight && !bInactive) )
{
COLORREF crHighLight = ::GetSysColor (COLOR_HIGHLIGHT);
CPenDC pen (*pDC, crHighLight);
CBrushDC brush (*pDC, crBackImg = GetDisabled() ? HLS_TRANSFORM (::GetSysColor (COLOR_3DFACE), +73, 0) : HLS_TRANSFORM (crHighLight, +70, -57));
if ( bMenuBar )
{
if(CRTMenu::m_MenuBarBitmap[BMP_FOCUS] != NULL && CRTMenu::m_bEnableSkin)
{
CRTDraw::RTDrawBitmap(pDC,pRect,CRTMenu::m_MenuBarBitmap[BMP_FOCUS],CRTMenu::m_MenuBarBitmapDrawMode[BMP_FOCUS]);
}
else
{
CRect rc (pRect);
rc.right -= TEXTPADDING_MNUBR;
pDC->Rectangle (rc);
rc.left = rc.right;
rc.right += TEXTPADDING_MNUBR;
pDC->FillSolidRect (rc, ::GetSysColor (COLOR_3DFACE));
}
}
else
{
if(CRTMenu::m_MenuItemBitmap[BMP_FOCUS] != NULL && CRTMenu::m_bEnableSkin)
{
CRect rc (pRect);
rc.right = IMGWIDTH+IMGPADDING;
CRTDraw::RTDrawBitmap(pDC,&rc,CRTMenu::m_MenuItemBitmap[BMP_SLIDER],CRTMenu::m_MenuItemBitmapDrawMode[BMP_SLIDER]);
rc.left = rc.right;
rc.right = pRect->right;
CRTDraw::RTDrawBitmap(pDC,&rc,CRTMenu::m_MenuItemBitmap[BMP_FOCUS],CRTMenu::m_MenuItemBitmapDrawMode[BMP_FOCUS]);
}
else
{
pDC->Rectangle (pRect);
}
}
}
else if ( !bMenuBar )
{
CRect rc (pRect);
rc.right = IMGWIDTH+IMGPADDING;
if(CRTMenu::m_MenuItemBitmap[BMP_SLIDER] != NULL && CRTMenu::m_bEnableSkin)
{
CRTDraw::RTDrawBitmap(pDC,&rc,CRTMenu::m_MenuItemBitmap[BMP_SLIDER],CRTMenu::m_MenuItemBitmapDrawMode[BMP_SLIDER]);
}
else
{
pDC->FillSolidRect (rc, HLS_TRANSFORM (::GetSysColor (COLOR_3DFACE), +20, 0));
}
rc.left = rc.right;
rc.right = pRect->right;
if(CRTMenu::m_MenuItemBitmap[BMP_NORMAL] != NULL && CRTMenu::m_bEnableSkin)
{
CRTDraw::RTDrawBitmap(pDC,&rc,CRTMenu::m_MenuItemBitmap[BMP_NORMAL],CRTMenu::m_MenuItemBitmapDrawMode[BMP_NORMAL]);
}
else
{
pDC->FillSolidRect (rc, HLS_TRANSFORM (::GetSysColor (COLOR_3DFACE), +75, 0));
}
}
else//MenuBar
{
if(CRTMenu::m_MenuBarBitmap[BMP_NORMAL] != NULL && CRTMenu::m_bEnableSkin)
{
CRTDraw::RTDrawBitmap(pDC,pRect,CRTMenu::m_MenuBarBitmap[BMP_NORMAL],CRTMenu::m_MenuBarBitmapDrawMode[BMP_NORMAL]);
}
else
{
pDC->FillSolidRect (pRect, ::GetSysColor (COLOR_3DFACE));
}
}
if ( GetSeparator() )
{
CPenDC pen (*pDC, HLS_TRANSFORM (::GetSysColor (COLOR_3DFACE), -18, 0));
pDC->MoveTo (pRect->left+IMGWIDTH+IMGPADDING+TEXTPADDING, (pRect->top+pRect->bottom)/2);
pDC->LineTo (pRect->right-1, (pRect->top+pRect->bottom)/2);
}
else
{
CRect rc (pRect);
CString sCaption;
if ( GetCaption (sCaption) > 0 )
{
pDC->SetTextColor (bInactive ? ::GetSysColor (COLOR_3DSHADOW) : (GetDisabled() ? HLS_TRANSFORM (::GetSysColor (COLOR_3DFACE), -18, 0) : ::GetSysColor (COLOR_MENUTEXT)));
pDC->SetBkMode (TRANSPARENT);
BOOL bKeyboardCues = true;
::SystemParametersInfo (SPI_GETKEYBOARDCUES, 0, &bKeyboardCues, 0);
DWORD dwHidePrefix = ( bNoAccel && !bKeyboardCues ) ? DT_HIDEPREFIX : 0;
if ( bMenuBar )
{
rc.right -= TEXTPADDING_MNUBR;
pDC->DrawText (sCaption, rc, DT_SINGLELINE|DT_VCENTER|DT_CENTER|dwHidePrefix);
}
else
{
CBoldDC bold (*pDC, GetDefault());
rc.left = IMGWIDTH+IMGPADDING+TEXTPADDING;
pDC->DrawText (sCaption, rc, DT_SINGLELINE|DT_VCENTER|DT_LEFT|dwHidePrefix);
CString sShortCut;
if ( GetShortCut (sShortCut) > 0 )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -