📄 newmenu.cpp
字号:
/****************************************************************************
* *
* GuiToolKit *
* (MFC extension) *
* Created by Francisco Campos G. www.beyondata.com fcampos@beyondata.com *
*--------------------------------------------------------------------------*
* *
* This program is free software;so you are free to use it any of your *
* applications (Freeware, Shareware, Commercial),but leave this header *
* intact. *
* *
* These files are provided "as is" without warranty of any kind. *
* *
* GuiToolKit is forever FREE CODE !!!!! *
* *
*--------------------------------------------------------------------------*
* Bug Fixes and improvements : (Add your name) *
* -Francisco Campos *
* *
****************************************************************************/
//------------------------------------------------------------------------------
// File : NewMenu.cpp
// Version : 1.0
// Date : Mai 2002
// Author : Bruno Podetti
// Email : Podetti@gmx.net
// Systems : VC6.0 and VC7.0 (Run under (Window 98/ME), Windows Nt 2000/XP)
//
// Bug Fixes and portions of code from previous version supplied by:
//
// Brent Corkum, Ben Ashley, Girish Bharadwaj, Jean-Edouard Lachand-Robert,
// Robert Edward Caldecott, Kenny Goers, Leonardo Zide, Stefan Kuhr,
// Reiner Jung, Martin Vladic, Kim Yoo Chul, Oz Solomonovich, Tongzhe Cui,
// Stephane Clog, Warren Stevens, Damir Valiulin
//
// You are free to use/modify this code but leave this header intact.
// This class is public domain so you are free to use it any of your
// applications (Freeware, Shareware, Commercial).
// All I ask is that you let me know so that if you have a real winner I can
// brag to my buddies that some of my code is in your app. I also wouldn't
// mind if you sent me a copy of your application since I like to play with
// new stuff.
//------------------------------------------------------------------------------
#include "stdafx.h" // Standard windows header file
#include "..\header\NewMenu.h" // CNewMenu class declaration
#include "..\header\GuiDrawLayer.h"
#include "..\header\MenuBar.h"
//#define _TRACE_MENU_
#ifdef _TRACE_MENU_
#include "MyTrace.h"
#endif
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
#endif
#ifndef IS_INTRESOURCE
#define IS_INTRESOURCE(hh) (HIWORD(hh)==NULL)
#endif
#define GAP 2
#ifndef ODS_HOTLIGHT
#define ODS_HOTLIGHT 0x0040
#endif
#ifndef ODS_INACTIVE
#define ODS_INACTIVE 0x0080
#endif
#ifndef COLOR_MENUBAR
#define COLOR_MENUBAR 30
#endif
#ifndef SPI_GETDROPSHADOW
#define SPI_GETDROPSHADOW 0x1024
#endif
#ifndef SPI_GETFLATMENU
#define SPI_GETFLATMENU 0x1022
#endif
extern int gbintHorz; //Horz=0, Vert=1
extern CRect rcMenu; //CRect of button
/////////////////////////////////////////////////////////////////////////////
#include "..\header\GuiDrawLayer.h"
// Helpers for casting
__inline HMENU UIntToHMenu(const unsigned int ui )
{
return( (HMENU)(UINT_PTR)ui );
}
__inline HMENU HWndToHmenu(const HWND hwnd )
{
return( (HMENU)hwnd );
}
__inline UINT HWndToUInt(const HWND hWnd )
{
return( (UINT)(UINT_PTR) hWnd);
}
__inline HWND UIntToHWnd(const UINT hWnd )
{
return( (HWND)(UINT_PTR) hWnd);
}
__inline UINT HMenuToUInt(const HMENU hMenu )
{
return( (UINT)(UINT_PTR) hMenu);
}
//static CMenuBar* pBar=CNewMenu::m_pBar;
CMenuButton* pb;
static void ShowLastError()
{
DWORD error = GetLastError();
if(error)
{
LPVOID lpMsgBuf=NULL;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
error,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL );
if(lpMsgBuf)
{
// Display the string.
MessageBox( NULL, (LPCTSTR)lpMsgBuf, _T("Error"), MB_OK | MB_ICONINFORMATION );
// Free the buffer.
LocalFree( lpMsgBuf );
}
else
{
CString temp;
temp.Format(_T("Error message 0x%lx not found"),error);
// Display the string.
MessageBox( NULL,temp, _T("Error"), MB_OK | MB_ICONINFORMATION );
}
}
}
enum Win32Type
{
Win32s,
WinNT3,
Win95,
Win98,
WinME,
WinNT4,
Win2000,
WinXP
};
Win32Type IsShellType()
{
Win32Type ShellType;
DWORD winVer;
OSVERSIONINFO *osvi;
winVer=GetVersion();
if(winVer<0x80000000)
{/*NT */
ShellType=WinNT3;
osvi= (OSVERSIONINFO *)malloc(sizeof(OSVERSIONINFO));
if (osvi!=NULL)
{
ZeroMemory(osvi,sizeof(OSVERSIONINFO));
osvi->dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
if(!GetVersionEx(osvi))
{
ShowLastError();
}
if(osvi->dwMajorVersion==4L)
{
ShellType=WinNT4;
}
else if(osvi->dwMajorVersion==5L && osvi->dwMinorVersion==0L)
{
ShellType=Win2000;
}
else if(osvi->dwMajorVersion==5L && osvi->dwMinorVersion==1L)
{
ShellType=WinXP;
}
free(osvi);
}
}
else if (LOBYTE(LOWORD(winVer))<4)
{
ShellType=Win32s;
}
else
{
ShellType=Win95;
osvi= (OSVERSIONINFO *)malloc(sizeof(OSVERSIONINFO));
if (osvi!=NULL)
{
memset(osvi,0,sizeof(OSVERSIONINFO));
osvi->dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
GetVersionEx(osvi);
if(osvi->dwMajorVersion==4L&&osvi->dwMinorVersion==10L)
{
ShellType=Win98;
}
else if(osvi->dwMajorVersion==4L&&osvi->dwMinorVersion==90L)
{
ShellType=WinME;
}
free(osvi);
}
}
return ShellType;
}
BOOL IsShadowEnabled()
{
BOOL bEnabled=FALSE;
if(SystemParametersInfo(SPI_GETDROPSHADOW,0,&bEnabled,0))
{
return bEnabled;
}
return FALSE;
}
COLORREF DarkenColorXP(COLORREF ColA)
{
return RGB( MulDiv(GetRValue(ColA),7,10),
MulDiv(GetGValue(ColA),7,10),
MulDiv(GetBValue(ColA)+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 R = MulDiv(GetRValue(lColor),(255-lScale),255);
long G = MulDiv(GetGValue(lColor),(255-lScale),255);
long B = MulDiv(GetBValue(lColor),(255-lScale),255);
return RGB(R, G, B);
}
COLORREF MixedColor(COLORREF ColA,COLORREF ColB)
{
// ( 86a + 14b ) / 100
int Red = MulDiv(86,GetRValue(ColA),100) + MulDiv(14,GetRValue(ColB),100);
int Green = MulDiv(86,GetGValue(ColA),100) + MulDiv(14,GetGValue(ColB),100);
int Blue = MulDiv(86,GetBValue(ColA),100) + MulDiv(14,GetBValue(ColB),100);
return RGB( Red,Green,Blue);
}
COLORREF MidColor(COLORREF ColA,COLORREF ColB)
{
// (7a + 3b)/10
int Red = MulDiv(7,GetRValue(ColA),10) + MulDiv(3,GetRValue(ColB),10);
int Green = MulDiv(7,GetGValue(ColA),10) + MulDiv(3,GetGValue(ColB),10);
int Blue = MulDiv(7,GetBValue(ColA),10) + MulDiv(3,GetBValue(ColB),10);
return RGB( Red,Green,Blue);
}
// used for function gradientfill.
//#pragma comment(lib,"Msimg32.lib")
void DrawGradient(CDC* pDC,CRect& Rect,
COLORREF StartColor,COLORREF EndColor,
BOOL bHorizontal)
{
/*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)
GradientFill(pDC->m_hDC,vert,2,&gRect,1,GRADIENT_FILL_RECT_H);
else
GradientFill(pDC->m_hDC,vert,2,&gRect,1,GRADIENT_FILL_RECT_V);*/
}
/////////////////////////////////////////////////////////////////////////////
// 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);
virtual BOOL OnEraseBkgnd(HWND hWnd, HDC hDC);
virtual BOOL OnNcCalcSize(HWND hWnd, NCCALCSIZE_PARAMS* pCalc);
virtual BOOL OnWindowPosChanging(HWND hWnd, LPWINDOWPOS pPos);
void DrawShade( HWND hWnd, HDC hDC, CPoint screen);
void DrawSmalBorder( 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);
virtual BOOL OnEraseBkgnd(HWND hWnd, HDC hDC);
};
/////////////////////////////////////////////////////////////////////////////
// CNewMenuHook important class for subclassing menus!
class CNewMenuHook
{
public:
class CMenuHookData
{
public:
CMenuHookData(HWND hWnd,BOOL bSpecialWnd)
: m_dwData(bSpecialWnd),m_bDrawBorder(TRUE),m_Point(0,0)
{
// Safe actual menu
m_hMenu = CNewMenuHook::m_hLastMenu;
// Reset for the next menu
CNewMenuHook::m_hLastMenu = NULL;
// Save actual border setting etc.
m_dwStyle = GetWindowLong(hWnd, GWL_STYLE) ;
m_dwExStyle = GetWindowLong(hWnd, GWL_EXSTYLE);
}
DWORD m_dwStyle;
DWORD m_dwExStyle;
CPoint m_Point;
DWORD m_dwData;
BOOL m_bDrawBorder;
HMENU m_hMenu;
};
public:
CNewMenuHook();
~CNewMenuHook();
public:
static CMenuHookData* GetMenuHookData(HWND hWnd);
static BOOL AddTheme(CMenuTheme*);
static CMenuTheme* RemoveTheme(DWORD dwThemeId);
static CMenuTheme* FindTheme(DWORD dwThemeId);
private:
static LRESULT CALLBACK NewMenuHook(int code, WPARAM wParam, LPARAM lParam);
static BOOL CheckSubclassing(HWND hWnd,BOOL bSpecialWnd);
static LRESULT CALLBACK SubClassMenu(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
static void UnsubClassMenu(HWND hWnd);
static BOOL SubClassMenu2(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, DWORD* pResult);
public:
static HMENU m_hLastMenu;
static DWORD m_dwMsgPos;
private:
static HHOOK HookOldMenuCbtFilter;
// an map of actual opened Menu and submenu
static CTypedPtrMap<CMapPtrToPtr,HWND,CMenuHookData*> m_MenuHookData;
// Stores list of all defined Themes
static CTypedPtrList<CPtrList, CMenuTheme*>* m_pRegisteredThemesList;
};
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
IMPLEMENT_DYNAMIC(CNewMenuItemData,CObject);
CNewMenuItemData::CNewMenuItemData()
: m_nTitleFlags(0),
m_nFlags(0),
m_nID(0),
m_nSyncFlag(0),
m_nxOffset(-1),
m_pBitmap(NULL),
m_nMenuIconNormal(-1),
m_pData(NULL)
{
}
CNewMenuItemData::~CNewMenuItemData()
{
if(m_pBitmap)
{
delete m_pBitmap;
m_pBitmap = NULL;
}
}
LPCTSTR CNewMenuItemData::GetString()
{
return m_szMenuText;
}
void CNewMenuItemData::SetString(LPCTSTR szMenuText)
{
m_szMenuText = szMenuText;
}
#if defined(_DEBUG) || defined(_AFXDLL)
// Diagnostic Support
void CNewMenuItemData::AssertValid() const
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -