📄 hsmenupro.cpp
字号:
// HSMenuPro.cpp: implementation of the CHSMenuPro class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "HSMenuPro.h"
#include "HSGraphics.h"
#include "HSMenu.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
///////////////////////////////////////////////////////////////////////////////////////////////
//$// 作者 : 韩 松
//$//
//$// 程序名称 :CHSMenuPro
//$// 程序类型 :菜单类
//$// 邮箱地址 :hs_china@yahoo.com
//$// QQ号码 :102567329
//$//
//$// 作者声明 :此部分代码全是作者所写,可以随便传播,但要保持
//$// 文件的完整性,如果您有问题或有好的建议、意见请您
//$// 给我来信,非常感谢!
//$//
//$// CHSMenuPro 类的使用细节请您参考附带的说明。
//$//
//////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
/*
_CLR_BKGNDEDGE 0
_CLR_SELSTART 1
_CLR_SELEND 2
_CLR_ICONSHADOW 3
*/
COLORREF CHSMenuPro::m_clrMenu[CLRCOUNT] =
{ RGB( 253, 253, 253 ),
RGB( 255, 174, 174 ),
RGB( 150, 170, 224 ),
RGB( 192, 192, 192 )
};
UINT CHSMenuPro::m_uMenuFlag = ML_NORMAL;
//////////////////////////////////////////////////////////////////////
IMPLEMENT_DYNAMIC( CHSMenuPro, CHSMenu );
CHSMenuPro::CHSMenuPro()
{
Initialize();
}
CHSMenuPro::~CHSMenuPro()
{
int iend = m_qMenuItem.size();
for ( int index=0; index<iend; index++ )
{
HSITEM& MenuItem = m_qMenuItem[index];
if ( MenuItem.m_ulData )
{
::DestroyIcon( (HICON)MenuItem.m_ulData );
MenuItem.m_ulData = NULL;
}
}
}
void CHSMenuPro::AppendMenu(LPCTSTR pszName, UINT uID, int nIconID, UINT uFlags)
{
CHSMenu::AppendMenu( pszName, uID, (ULONG)LoadIcon( nIconID ), uFlags );
}
BOOL CHSMenuPro::AppendPopup(LPCTSTR pszName, CHSMenu *pPopup, UINT uID, int nIconID, UINT uFlags)
{
return CHSMenu::AppendPopup( pszName, pPopup, uID, (ULONG)LoadIcon( nIconID ), uFlags );
}
BOOL CHSMenuPro::InsertMenu(int nItem, LPCTSTR pszName, UINT uID, int nIconID, UINT uFlags, UINT uFlag)
{
return CHSMenu::InsertMenu( nItem, pszName, uID, (ULONG)LoadIcon( nIconID ), uFlags, uFlag );
}
BOOL CHSMenuPro::InsertPopup(int nItem, LPCTSTR pszName, CHSMenu *pPopup, UINT uID, int nIconID, UINT uFlags, UINT uFlag)
{
return CHSMenu::InsertPopup( nItem, pszName, pPopup, uID, (ULONG)LoadIcon( nIconID ), uFlags, uFlag );
}
UINT CHSMenuPro::GetMenuStyle(UINT uMenuLook )
{
return ( m_uMenuFlag & uMenuLook );
}
void CHSMenuPro::SetMenuIconSize(int nSize)
{
m_nIconSize = nSize < 0 ? -nSize : nSize ;
}
void CHSMenuPro::SetMenuStyle(UINT uMenuLook, BOOL bSet)
{
if ( bSet )
m_uMenuFlag |= ( uMenuLook );
else m_uMenuFlag &= ~( uMenuLook );
}
inline void CHSMenuPro::Initialize()
{
m_nIconSize = 16;
int iend = m_qMenuItem.size();
for ( int index=0; index<iend; index++ )
{
HSITEM& MenuItem = m_qMenuItem[index];
if ( MenuItem.m_ulData )
{
::DestroyIcon( (HICON)MenuItem.m_ulData );
MenuItem.m_ulData = 0;
}
}
}
void CHSMenuPro::DrawMenuBkgnd(HWND hWnd, HDC hDC)
{
HRGN hrgnMenu = ::CreateRectRgn( 0, 0, 0, 0 );
::GetWindowRgn( hWnd, hrgnMenu );
if ( GetMenuStyle( ML_BKGNDEDGE ) )
{
DrawPartionRgn( hDC,
CHSMenu::m_clrMenu[CLR_BKGNDMENU],
m_clrMenu[_CLR_BKGNDEDGE],
TRUE,
GetMenuEdge() + m_nIconSize + CX,
hrgnMenu );
}
else DrawRgn( hDC, CHSMenu::m_clrMenu[CLR_BKGNDMENU], hrgnMenu );
if ( GetMenuStyle( ML_MENU3D ) )
{
Draw3DRgnEdge( hDC, 1, hrgnMenu );
}
else
{
DrawFrameRgn( hDC, hrgnMenu, CHSMenu::m_clrMenu[CLR_BORDERMENU], 1, 1 );
}
::DeleteObject( hrgnMenu );
}
void CHSMenuPro::OnLButtonDown(HWND hWnd, short x, short y)
{
if ( GetMenuStyle( ML_CLICK3D ) && IsEffectItem() )
{
RECT rect;
char sName[128];
ULONG ulData = 0;
UINT uFlags = 0;
if ( GetMenuItemRect( m_nCurSel, &rect ) &&
GetMenuString( m_nCurSel, sName, 128 ) &&
GetMenuData( m_nCurSel, &ulData )
)
{
uFlags = GetMenuState( m_nCurSel );
HRGN hrgnBk = NULL;
DRAWITEMSTRUCTPRO disp;
disp.hDC = ::GetDC( hWnd );
disp.lpcStr = sName;
disp.ulData = ulData;
disp.uFlags = uFlags | MENU_SELECTED;
disp.rect.left = rect.left;
disp.rect.top = rect.top;
disp.rect.right = rect.right;
disp.rect.bottom= rect.bottom;
DrawItemBkgnd( &disp );
disp.uFlags &= ~MENU_SELECTED;
disp.rect.left += 1;
disp.rect.top += 1;
disp.rect.right += 1;
disp.rect.bottom += 1;
DrawItemIcon( &disp );
DrawItemText( &disp );
if ( m_pfnCustomMenuItem )
hrgnBk = (HRGN)m_pfnCustomMenuItem( &rect );
if ( hrgnBk == NULL )
hrgnBk = ::CreateRectRgn( rect.left, rect.top, rect.right, rect.bottom );
Draw3DRgnEdge( disp.hDC, FALSE, hrgnBk );
::DeleteObject( hrgnBk );
::ReleaseDC( hWnd, disp.hDC );
}
}
CHSMenu::OnLButtonDown( hWnd, x, y );
}
void CHSMenuPro::DrawItem(LPDRAWITEMSTRUCTPRO lpdisp)
{
// Draw a separator
if ( lpdisp->uFlags & ITEM_SEPARATOR )
{
DrawItemBkgnd( lpdisp );
DrawItemSpr( lpdisp );
return;
}
DrawItemBkgnd( lpdisp );
// Draw the Menu item Text
DrawItemText( lpdisp );
// Draw Icon
DrawItemIcon( lpdisp );
DrawItemArrow( lpdisp );
}
void CHSMenuPro::DrawItemBkgnd(LPDRAWITEMSTRUCTPRO lpdisp)
{
HRGN hrgnBk = NULL;
RECT& rect = lpdisp->rect;
if ( m_pfnCustomMenuItem )
hrgnBk = (HRGN)m_pfnCustomMenuItem( &rect );
if ( hrgnBk == NULL )
hrgnBk = ::CreateRectRgn( rect.left, rect.top, rect.right, rect.bottom );
if ( ( lpdisp->uFlags & MENU_SELECTED ) && !( lpdisp->uFlags & ITEM_SEPARATOR ) )
{
if ( GetMenuStyle( ML_SELGRADIENT ) || GetMenuStyle( ML_SELGRADIENT_V ) )
{
DrawGradientRgn( lpdisp->hDC,
GetMenuStyle( ML_SELGRADIENT_V )!=0,
hrgnBk,
m_clrMenu[_CLR_SELSTART],
m_clrMenu[_CLR_SELEND] );
/* DrawGradientRect( lpdisp->hDC,
GetMenuStyle( ML_SELGRADIENT_V )!=0,
rect,
m_clrMenu[_CLR_SELSTART],
m_clrMenu[_CLR_SELEND] );
*/
}
else
{
DrawRgn( lpdisp->hDC, CHSMenu::m_clrMenu[CLR_BKGNDSEL], hrgnBk );
}
if ( GetMenuStyle( ML_SEL3D ) )
{
Draw3DRgnEdge( lpdisp->hDC, TRUE, hrgnBk );
}
else if ( GetMenuStyle( ML_SELBORDER ) )
{
DrawFrameRgn( lpdisp->hDC, hrgnBk, CHSMenu::m_clrMenu[CLR_BORDERSEL], 1, 1 );
}
}
else // Draw Normal Bk
{
if ( GetMenuStyle( ML_BKGNDEDGE ) )
{
DrawPartionRgn( lpdisp->hDC,
CHSMenu::m_clrMenu[CLR_BKGNDMENU],
m_clrMenu[_CLR_BKGNDEDGE],
TRUE,
m_nIconSize + CX,
hrgnBk );
}
else DrawRgn( lpdisp->hDC, CHSMenu::m_clrMenu[CLR_BKGNDMENU], hrgnBk );
}
DeleteObject( hrgnBk );
}
void CHSMenuPro::DrawItemSpr(LPDRAWITEMSTRUCTPRO lpdisp)
{
POINT pt[2];
RECT& rect = lpdisp->rect;
pt[1].x = rect.right - 8;
pt[0].y = pt[1].y = ( rect.top + rect.bottom ) / 2;
if ( GetMenuStyle( ML_BKGNDEDGE ) )
pt[0].x = rect.left + m_nIconSize + CX + 8;
else
pt[0].x = rect.left + 8;
// 3D Outer
if ( GetMenuStyle( ML_SEPARATOR3D_HEAVE ) )
{
if ( !GetMenuStyle( ML_BKGNDEDGE ) )
pt[0].y = ( pt[1].y -= 1 );
Draw3DLine( lpdisp->hDC, TRUE, pt[0], pt[1] );
}
else
if ( GetMenuStyle( ML_SEPARATOR3D_CONCAVE ) )
{
if ( GetMenuStyle( ML_BKGNDEDGE ) )
pt[0].y = ( pt[1].y -= 1 );
Draw3DLine( lpdisp->hDC, FALSE, pt[0], pt[1] );
}
else // Normal Line
DrawPolyline( lpdisp->hDC, CHSMenu::m_clrMenu[CLR_BORDERSPR], pt, 2 );
}
void CHSMenuPro::DrawItemArrow(LPDRAWITEMSTRUCTPRO lpdisp)
{
if ( ( lpdisp->uFlags & ITEM_POPUP ) == NULL ) return;
if ( GetMenuStyle( ML_ARROWROUND ) )
{
RECT& rect = lpdisp->rect;
COLORREF clrBorder, clrBkgnd;
if ( lpdisp->uFlags & ITEM_GRAY )
{
clrBorder = GetSysColor( COLOR_GRAYTEXT );
clrBkgnd = GetSysColor( COLOR_GRAYTEXT );
}
else
{
if ( lpdisp->uFlags & MENU_SELECTED )
{
clrBkgnd = CHSMenu::m_clrMenu[CLR_ARROWSEL];
clrBorder = CHSMenu::m_clrMenu[CLR_TEXTNORMAL];
}
else
{
clrBkgnd = CHSMenu::m_clrMenu[CLR_TEXTNORMAL];
clrBorder = CHSMenu::m_clrMenu[CLR_ARROWSEL];
}
}
int nLeft = rect.right - 16;
int nTop = rect.top + (rect.bottom-rect.top)/2 - 3;
DrawEllipse( lpdisp->hDC,
clrBorder,
clrBkgnd,
nLeft,
nTop,
nLeft + 6,
nTop + 6 );
}
else
CHSMenu::DrawItemArrow( lpdisp );
}
void CHSMenuPro::DrawItemText(LPDRAWITEMSTRUCTPRO lpdisp)
{
HGDIOBJ hfntOld;
UINT fuFlag = DST_TEXT;
RECT& rect = lpdisp->rect;
int nLeft = rect.left + m_nIconSize + CX + 8;
int nTop = ( rect.top + rect.bottom - m_nFontHeight ) / 2;
// if ( MenuItem.m_uFlags & ITEM_GRAY )
// fuFlag |= DSS_UNION;
if ( lpdisp->uFlags & ITEM_GRAY )
fuFlag |= DSS_DISABLED;
else
SetTextColor( lpdisp->hDC, CHSMenu::GetColor( GetState( MENU_SELECTED ) ? CLR_TEXTSEL : CLR_TEXTNORMAL ) );
SetBkMode( lpdisp->hDC, TRANSPARENT );
hfntOld = SelectObject( lpdisp->hDC, m_hFont );
DrawState( lpdisp->hDC, NULL, NULL, (LPARAM)lpdisp->lpcStr, 0, nLeft, nTop, 800, 70, fuFlag );
SelectObject( lpdisp->hDC, hfntOld );
}
// Draw Item Icon
void CHSMenuPro::DrawItemIcon(LPDRAWITEMSTRUCTPRO lpdisp)
{
if ( lpdisp->ulData == NULL ) return;
RECT& rect = lpdisp->rect;
int x = rect.left + 5;
int y = ( rect.top + rect.bottom - m_nIconSize ) / 2;
if ( lpdisp->uFlags & ITEM_GRAY )
{
DrawShadowIcon( lpdisp->hDC,
x,
y,
(HICON)lpdisp->ulData,
m_nIconSize,
m_nIconSize,
GetSysColor( COLOR_GRAYTEXT ) );
}
else
{
if ( lpdisp->uFlags & MENU_SELECTED )
{
DrawShadowIcon( lpdisp->hDC,
x + 1,
y + 1,
(HICON)lpdisp->ulData,
m_nIconSize,
m_nIconSize,
m_clrMenu[_CLR_ICONSHADOW] );
DrawIconEx( lpdisp->hDC,
x - 1,
y - 1,
(HICON)lpdisp->ulData,
m_nIconSize,
m_nIconSize,
0,
NULL,
DI_NORMAL );
}
else
DrawIconEx( lpdisp->hDC,
x,
y,
(HICON)lpdisp->ulData,
m_nIconSize,
m_nIconSize,
0,
NULL,
DI_NORMAL );
/* DrawFadeIcon( lpdisp->hDC,
x,
y,
(HICON)lpdisp->pulData,
m_nIconSize,
m_nIconSize,
100 );
*/
}
}
COLORREF CHSMenuPro::GetColor(int nIndex)
{
switch ( nIndex )
{
case CLR_BKGNDEDGE:
case CLR_SELSTART:
case CLR_SELEND:
case CLR_ICONSHADOW:
return m_clrMenu[Index( nIndex )];
default :
return CHSMenu::GetColor( nIndex );
}
}
void CHSMenuPro::SetColor(int nIndex, COLORREF clrSet)
{
switch ( nIndex )
{
case CLR_BKGNDEDGE:
case CLR_SELSTART:
case CLR_SELEND:
case CLR_ICONSHADOW:
m_clrMenu[Index( nIndex )] = clrSet;
break;
default:
CHSMenu::SetColor( nIndex, clrSet );
}
}
// Set Menu Item Icon
BOOL CHSMenuPro::SetMenuIcon(UINT nItem, int nIconID, UINT uFlag)
{
HICON hIcon = NULL;
CHSMenu::GetMenuData( nItem, ((ULONG*)&hIcon), uFlag );
if ( hIcon )
::DestroyIcon( hIcon );
return CHSMenu::SetMenuData( nItem, (ULONG)LoadIcon( nIconID ), uFlag );
}
BOOL CHSMenuPro::LoadMenu(UINT uIDResource, int nMenuPos, int nIconPos)
{
CMenu *pMenu = new CMenu;
if ( pMenu->LoadMenu( uIDResource ) )
{
MapMenuFrom( pMenu->GetSubMenu( nMenuPos ), nMenuPos==nIconPos ? NULL : pMenu->GetSubMenu( nIconPos ) );
pMenu->DestroyMenu();
delete pMenu;
return TRUE;
}
delete pMenu;
return FALSE;
}
void CHSMenuPro::MapMenuFrom(CMenu *pMenu, CMenu *pMenuIcon)
{
CString strText;
int nTotalMenu = pMenu->GetMenuItemCount();
CreateMenu();
for ( int nPosition=0; nPosition<nTotalMenu; nPosition++ )
{
pMenu->GetMenuString( nPosition, strText, MF_BYPOSITION );
UINT uID = pMenu->GetMenuItemID( nPosition );
UINT uFlags = pMenu->GetMenuState( nPosition, MF_BYPOSITION );
if ( uID == (UINT)-1 )
{
CMenu *pMenuPop = pMenu->GetSubMenu( nPosition );
if ( pMenuPop )
{
int nIDIcon = 0;
CMenu *pMenuPopIcon = NULL;
if ( pMenuIcon )
{
pMenuPopIcon = pMenuIcon->GetSubMenu( nPosition );
if ( pMenuPopIcon )
{
nIDIcon = pMenuPopIcon->GetMenuItemID( 0 );
pMenuPopIcon->DeleteMenu( 0, MF_BYPOSITION );
}
}
CHSMenuPro *pHSMenuPop = new CHSMenuPro;
pHSMenuPop->MapMenuFrom( pMenuPop, pMenuPopIcon );
AppendPopup( strText, pHSMenuPop, uID, nIDIcon, uFlags );
}
}
else
{
int nIDIcon = pMenuIcon ? pMenuIcon->GetMenuItemID( nPosition ) : 0;
AppendMenu( strText, uID, nIDIcon, uFlags );
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -