📄 newmenu.cpp
字号:
CreateSolidBrush(barColor);
}
}
};
CBrush* GetMenuBarBrush()
{
// The brushes will be destroyed at program-end => Not a memory-leak
static CNewBrushList brushList;
static CNewBrush* lastBrush = NULL;
COLORREF menuBarColor;
UINT nMenuDrawMode = CNewMenu::GetMenuDrawMode();
switch(nMenuDrawMode)
{
case CNewMenu::STYLE_XP_2003 :
case CNewMenu::STYLE_XP_2003_NOBORDER :
{
menuBarColor = CNewMenu::GetMenuBarColor2003();
if (NumScreenColors()>=256 && !bHighContrast)
{
nMenuDrawMode = CNewMenu::STYLE_XP_2003;
}
else
{
nMenuDrawMode = CNewMenu::STYLE_XP;
}
}
break;
case CNewMenu::STYLE_XP :
case CNewMenu::STYLE_XP_NOBORDER :
menuBarColor = GetSysColor(COLOR_3DFACE);
nMenuDrawMode = CNewMenu::STYLE_XP;
break;
//case CNewMenu::STYLE_ICY :
//case CNewMenu::STYLE_ICY_NOBORDER :
// menuBarColor = RGB(0,0,255);
// nMenuDrawMode = CNewMenu::STYLE_XP;
// break;
default:
return NULL;
}
// check if the last brush the one which we want
if(lastBrush!=NULL && lastBrush->m_nMenuDrawMode==nMenuDrawMode && lastBrush->m_BarColor==menuBarColor)
{
return lastBrush;
}
// Check if the brush is allready created
POSITION pos = brushList.GetHeadPosition();
while (pos)
{
lastBrush = (CNewBrush*)brushList.GetNext(pos);
if(lastBrush!=NULL &&
lastBrush->m_nMenuDrawMode==nMenuDrawMode &&
lastBrush->m_BarColor==menuBarColor)
{
return lastBrush;
}
}
// create a new one and insert into the list
brushList.AddHead(lastBrush = new CNewBrush(nMenuDrawMode,menuBarColor));
return lastBrush;
}
void UpdateMenuBarColor(HMENU hMenu)
{
CBrush* pBrush = GetMenuBarBrush();
// for WindowsBlind activating it's better for not to change menubar background
if(!pBrush /* || (pIsThemeActive && pIsThemeActive()) */ )
{
// menubackground hasn't been set
return;
}
MENUINFO menuInfo = {0};
menuInfo.cbSize = sizeof(menuInfo);
menuInfo.hbrBack = *pBrush;
menuInfo.fMask = MIM_BACKGROUND;
// Change color only for CNewMenu and derived classes
if(IsMenu(hMenu) && DYNAMIC_DOWNCAST(CNewMenu,CMenu::FromHandlePermanent(hMenu))!=NULL)
{
SetMenuInfo(hMenu,&menuInfo);
}
CWinApp* pWinApp = AfxGetApp();
// Update menu from template
if(pWinApp)
{
CDocManager* pManager = pWinApp->m_pDocManager;
if(pManager)
{
POSITION pos = pManager->GetFirstDocTemplatePosition();
while(pos)
{
CDocTemplate* pTemplate = pManager->GetNextDocTemplate(pos);
CMultiDocTemplate* pMultiTemplate = DYNAMIC_DOWNCAST(CMultiDocTemplate,pTemplate);
if(pMultiTemplate)
{
// Change color only for CNewMenu and derived classes
if(DYNAMIC_DOWNCAST(CNewMenu,CMenu::FromHandlePermanent(pMultiTemplate->m_hMenuShared))!=NULL)
{
// need for correct menubar color
SetMenuInfo(pMultiTemplate->m_hMenuShared,&menuInfo);
}
}
}
}
}
}
BOOL DrawMenubarItem(CWnd* pWnd,CMenu* pMenu, UINT nItemIndex,UINT nState)
{
CRect itemRect;
if (nItemIndex!=UINT(-1) && GetMenuItemRect(pWnd->m_hWnd,pMenu->m_hMenu, nItemIndex, &itemRect))
{
MENUITEMINFO menuInfo = {0};
menuInfo.cbSize = sizeof(menuInfo);
menuInfo.fMask = MIIM_DATA|MIIM_TYPE|MIIM_ID;
if(pMenu->GetMenuItemInfo(nItemIndex,&menuInfo,TRUE))
{
// Only ownerdrawn were allowed
if(menuInfo.fType&MF_OWNERDRAW)
{
CWindowDC dc(pWnd);
CFont fontMenu;
LOGFONT logFontMenu;
#ifdef _NEW_MENU_USER_FONT
logFontMenu = MENU_USER_FONT;
#else
NONCLIENTMETRICS nm = {0};
nm.cbSize = sizeof (NONCLIENTMETRICS);
VERIFY (SystemParametersInfo(SPI_GETNONCLIENTMETRICS,nm.cbSize,&nm,0));
logFontMenu = nm.lfMenuFont;
#endif
fontMenu.CreateFontIndirect (&logFontMenu);
CFont* pOldFont = dc.SelectObject(&fontMenu);
CRect wndRect;
GetWindowRect(*pWnd,wndRect);
itemRect.OffsetRect(-wndRect.TopLeft());
DRAWITEMSTRUCT drwItem = {0};
drwItem.CtlType = ODT_MENU;
drwItem.hwndItem = HMenuToHWnd(pMenu->m_hMenu);
drwItem.itemID = menuInfo.wID;
drwItem.itemData = menuInfo.dwItemData;
drwItem.rcItem = itemRect;
drwItem.hDC = dc.m_hDC;
drwItem.itemState = nState;
drwItem.itemAction = ODA_DRAWENTIRE;
ASSERT(menuInfo.dwItemData);
CNewMenu::m_dwLastActiveItem = (DWORD)menuInfo.dwItemData;
SendMessage(pWnd->GetSafeHwnd(),WM_DRAWITEM,NULL,(LPARAM)&drwItem);
dc.SelectObject(pOldFont);
return TRUE;
}
}
}
return FALSE;
}
Win32Type IsShellType()
{
OSVERSIONINFO osvi = {0};
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
DWORD winVer=GetVersion();
if(winVer<0x80000000)
{/*NT */
if(!GetVersionEx(&osvi))
{
ShowLastError();
}
if(osvi.dwMajorVersion==4L)
{
return WinNT4;
}
else if(osvi.dwMajorVersion==5L && osvi.dwMinorVersion==0L)
{
return Win2000;
}
// thanks to John Zegers
else if(osvi.dwMajorVersion>=5L)// && osvi.dwMinorVersion==1L)
{
return WinXP;
}
return WinNT3;
}
else if (LOBYTE(LOWORD(winVer))<4)
{
return Win32s;
}
if(!GetVersionEx(&osvi))
{
ShowLastError();
}
if(osvi.dwMajorVersion==4L && osvi.dwMinorVersion==10L)
{
return Win98;
}
else if(osvi.dwMajorVersion==4L && osvi.dwMinorVersion==90L)
{
return WinME;
}
return Win95;
}
BOOL IsShadowEnabled()
{
BOOL bEnabled = FALSE;
if(SystemParametersInfo(SPI_GETDROPSHADOW,0,&bEnabled,0))
{
return bEnabled;
}
return FALSE;
}
COLORREF DarkenColorXP(COLORREF color)
{
return RGB( MulDiv(GetRValue(color),7,10),
MulDiv(GetGValue(color),7,10),
MulDiv(GetBValue(color)+55,7,10));
}
// Function splits a color into its RGB components and
// transforms the color using a scale 0..255
COLORREF DarkenColor( long lScale, COLORREF lColor)
{
long red = MulDiv(GetRValue(lColor),(255-lScale),255);
long green = MulDiv(GetGValue(lColor),(255-lScale),255);
long blue = MulDiv(GetBValue(lColor),(255-lScale),255);
return RGB(red, green, blue);
}
COLORREF MixedColor(COLORREF colorA,COLORREF colorB)
{
// ( 86a + 14b ) / 100
int red = MulDiv(86,GetRValue(colorA),100) + MulDiv(14,GetRValue(colorB),100);
int green = MulDiv(86,GetGValue(colorA),100) + MulDiv(14,GetGValue(colorB),100);
int blue = MulDiv(86,GetBValue(colorA),100) + MulDiv(14,GetBValue(colorB),100);
return RGB( red,green,blue);
}
COLORREF MidColor(COLORREF colorA,COLORREF colorB)
{
// (7a + 3b)/10
int red = MulDiv(7,GetRValue(colorA),10) + MulDiv(3,GetRValue(colorB),10);
int green = MulDiv(7,GetGValue(colorA),10) + MulDiv(3,GetGValue(colorB),10);
int blue = MulDiv(7,GetBValue(colorA),10) + MulDiv(3,GetBValue(colorB),10);
return RGB( red, green, blue);
}
COLORREF GetXpHighlightColor()
{
if(bHighContrast)
{
return GetSysColor(COLOR_HIGHLIGHT);
}
if (NumScreenColors() > 256)
{
//return DarkenColor(30,MidColor(GetSysColor(COLOR_WINDOW),GetSysColor(COLOR_HIGHLIGHT)));
return MidColor(GetSysColor(COLOR_WINDOW),GetSysColor(COLOR_HIGHLIGHT));
}
return GetSysColor(COLOR_WINDOW);
}
COLORREF GrayColor(COLORREF crColor)
{
int Gray = (((int)GetRValue(crColor)) + GetGValue(crColor) + GetBValue(crColor))/3;
return RGB( Gray,Gray,Gray);
}
BOOL IsLightColor(COLORREF crColor)
{
return (((int)GetRValue(crColor)) + GetGValue(crColor) + GetBValue(crColor))>(3*128);
}
// Function splits a color into its RGB components and
// transforms the color using a scale 0..255
COLORREF LightenColor( long lScale, COLORREF lColor)
{
long R = MulDiv(255-GetRValue(lColor),lScale,255)+GetRValue(lColor);
long G = MulDiv(255-GetGValue(lColor),lScale,255)+GetGValue(lColor);
long B = MulDiv(255-GetBValue(lColor),lScale,255)+GetBValue(lColor);
return RGB(R, G, B);
}
COLORREF BleachColor(int Add, COLORREF color)
{
return RGB( min (GetRValue(color)+Add, 255),
min (GetGValue(color)+Add, 255),
min (GetBValue(color)+Add, 255));
}
void DrawGradient(CDC* pDC,CRect& Rect,
COLORREF StartColor,COLORREF EndColor,
BOOL bHorizontal,BOOL bUseSolid)
{
int Count = pDC->GetDeviceCaps(NUMCOLORS);
if(Count==-1)
bUseSolid = FALSE;
// for running under win95 and WinNt 4.0 without loading Msimg32.dll
if(!bUseSolid && pGradientFill )
{
TRIVERTEX vert[2] ;
GRADIENT_RECT gRect;
vert [0].y = Rect.top;
vert [0].x = Rect.left;
vert [0].Red = COLOR16(COLOR16(GetRValue(StartColor))<<8);
vert [0].Green = COLOR16(COLOR16(GetGValue(StartColor))<<8);
vert [0].Blue = COLOR16(COLOR16(GetBValue(StartColor))<<8);
vert [0].Alpha = 0x0000;
vert [1].y = Rect.bottom;
vert [1].x = Rect.right;
vert [1].Red = COLOR16(COLOR16(GetRValue(EndColor))<<8);
vert [1].Green = COLOR16(COLOR16(GetGValue(EndColor))<<8);
vert [1].Blue = COLOR16(COLOR16(GetBValue(EndColor))<<8);
vert [1].Alpha = 0x0000;
gRect.UpperLeft = 0;
gRect.LowerRight = 1;
if(bHorizontal)
{
pGradientFill(pDC->m_hDC,vert,2,&gRect,1,GRADIENT_FILL_RECT_H);
}
else
{
pGradientFill(pDC->m_hDC,vert,2,&gRect,1,GRADIENT_FILL_RECT_V);
}
}
else
{
BYTE StartRed = GetRValue(StartColor);
BYTE StartGreen = GetGValue(StartColor);
BYTE StartBlue = GetBValue(StartColor);
BYTE EndRed = GetRValue(EndColor);
BYTE EndGreen = GetGValue(EndColor);
BYTE EndBlue = GetBValue(EndColor);
int n = (bHorizontal)?Rect.Width():Rect.Height();
// only need for the rest, can be optimized
{
if(bUseSolid)
{
// We need a solid brush (can not be doted)
pDC->FillSolidRect(Rect,pDC->GetNearestColor(EndColor));
}
else
{
// We need a brush (can be doted)
CBrush TempBrush(EndColor);
pDC->FillRect(Rect,&TempBrush);
}
}
int dy = 2;
n-=dy;
for(int dn=0;dn<=n;dn+=dy)
{
BYTE ActRed = (BYTE)(MulDiv(int(EndRed)-StartRed,dn,n)+StartRed);
BYTE ActGreen = (BYTE)(MulDiv(int(EndGreen)-StartGreen,dn,n)+StartGreen);
BYTE ActBlue = (BYTE)(MulDiv(int(EndBlue)-StartBlue,dn,n)+StartBlue);
CRect TempRect;
if(bHorizontal)
{
TempRect = CRect(CPoint(Rect.left+dn,Rect.top),CSize(dy,Rect.Height()));
}
else
{
TempRect = CRect(CPoint(Rect.left,Rect.top+dn),CSize(Rect.Width(),dy));
}
if(bUseSolid)
{
pDC->FillSolidRect(TempRect,pDC->GetNearestColor(RGB(ActRed,ActGreen,ActBlue)));
}
else
{
CBrush TempBrush(RGB(ActRed,ActGreen,ActBlue));
pDC->FillRect(TempRect,&TempBrush);
}
}
}
}
/////////////////////////////////////////////////////////////////////////////
// CMenuTheme for drawing border and the rest
typedef void (CNewMenu::*pItemMeasureFkt) (LPMEASUREITEMSTRUCT lpMIS, BOOL bIsMenubar);
typedef void (CNewMenu::*pItemDrawFkt) (LPDRAWITEMSTRUCT lpDIS, BOOL bIsMenubar);
typedef BOOL (CNewMenu::*pEraseBkgndFkt) (HWND hWnd, HDC hDC);
typedef void (CMenuTheme::*pDrawMenuBorder)( HWND hWnd, HDC hDC, CPoint screen);
class CMenuTheme
{
public:
CMenuTheme();
CMenuTheme(DWORD dwThemeId,
pItemMeasureFkt pMeasureItem,
pItemDrawFkt pDrawItem,
pItemDrawFkt pDrawTitle,
DWORD dwFlags=0);
virtual ~CMenuTheme();
virtual BOOL OnInitWnd(HWND hWnd);
virtual BOOL OnUnInitWnd(HWND hWnd);
virtual BOOL DoDrawBorder();
virtual BOOL OnDrawBorder(HWND hWnd, HDC hDC, BOOL bOnlyBorder=FALSE);
virtual BOOL OnEraseBkgnd(HWND hWnd, HDC hDC);
virtual BOOL OnNcCalcSize(HWND hWnd, NCCALCSIZE_PARAMS* pCalc);
virtual BOOL OnWindowPosChanging(HWND hWnd, LPWINDOWPOS pPos);
virtual BOOL OnCalcFrameRect(HWND hWnd,LPRECT pRect);
void DrawShade( HWND hWnd, HDC hDC, CPoint screen);
void DrawSmalBorder( HWND hWnd, HDC hDC);
void DrawFrame(CDC* pDC, CRect rectOuter, CRect rectInner, COLORREF crBorder);
void* SetScreenBitmap(HWND hWnd, HDC hDC);
public:
DWORD m_dwThemeId;
DWORD m_dwFlags;
pItemMeasureFkt m_pMeasureItem;
pItemDrawFkt m_pDrawItem;
pItemDrawFkt m_pDrawTitle;
CSize m_BorderTopLeft;
CSize m_BorderBottomRight;
};
/////////////////////////////////////////////////////////////////////////////
// CMenuThemeXP for drawing border and the rest
class CMenuThemeXP :public CMenuTheme
{
public:
CMenuThemeXP(DWORD dwThemeId,
pItemMeasureFkt pMeasureItem,
pItemDrawFkt pDrawItem,
pItemDrawFkt pDrawTitle,
DWORD dwFlags=0);
virtual BOOL OnDrawBorder(HWND hWnd, HDC hDC, BOOL bOnlyBorder=FALSE);
virtual BOOL OnEraseBkgnd(HWND hWnd, HDC hDC);
};
/////////////////////////////////////////////////////////////////////////////
// CNewMenuHook important class for subclassing menus!
class CNewMenuHook
{
public:
class CMenuHookData
{
public:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -