📄 hsmenu.cpp
字号:
}
void CHSMenu::DrawItemAnimation(LPDRAWITEMSTRUCTPRO lpdisp )
{
if ( ( lpdisp->uFlags & MENU_SELECTED ) && !( lpdisp->uFlags & ITEM_SEPARATOR ) )
{
int nWidth = lpdisp->rect.right - lpdisp->rect.left;
int nHeight = lpdisp->rect.bottom- lpdisp->rect.top;
HDC hdcMem = ::CreateCompatibleDC( lpdisp->hDC );
HBITMAP hbmpMem = ::CreateCompatibleBitmap( lpdisp->hDC, nWidth, nHeight );
HGDIOBJ hobjOld = ::SelectObject( hdcMem, hbmpMem );
::BitBlt( hdcMem, 0, 0, nWidth, nHeight, lpdisp->hDC, lpdisp->rect.left, lpdisp->rect.top, SRCCOPY );
//------------------------------------------------------------------------------------------
DRAWITEMSTRUCTPRO disp;
disp.hDC = hdcMem;
disp.lpcStr = lpdisp->lpcStr;
disp.ulData = lpdisp->ulData;
disp.uFlags = lpdisp->uFlags;
disp.rect.left = 0;
disp.rect.top = 0;
disp.rect.right = nWidth;
disp.rect.bottom = nHeight;
DrawItem( &disp );
//------------------------------------------------------------------------------------------
DrawAnimateMenuItem( &lpdisp->rect, lpdisp->hDC, disp.hDC, m_nItemAniType, m_nItemAniStep, m_nItemAniDelay );
::SelectObject( hdcMem, hobjOld );
::DeleteObject( hbmpMem );
::DeleteDC( hdcMem );
}
else
{
DrawItem( lpdisp );
}
}
// Draw the menu item which you want
void CHSMenu::DrawItem(LPDRAWITEMSTRUCTPRO lpdisp)
{
// Draw a separator
if ( lpdisp->uFlags & ITEM_SEPARATOR )
{
DrawItemBkgnd( lpdisp );
DrawItemSpr( lpdisp );
return;
}
// Draw or Clear Select Background
DrawItemBkgnd( lpdisp );
// Draw the Menu item Text
DrawItemText( lpdisp );
// if this Item has son, then Graphics arrowhead
if ( lpdisp->uFlags & ITEM_POPUP )
DrawItemArrow( lpdisp );
}
// Draw(Selected) or Clear(Leave) the item Background
void CHSMenu::DrawItemBkgnd(LPDRAWITEMSTRUCTPRO lpdisp)
{
int nClrBorder, nClrBk;
RECT& rect = lpdisp->rect;
HRGN hrgnItem = NULL;
if ( GetState( MENU_SELECTED ) && !( lpdisp->uFlags & ITEM_SEPARATOR ) )
{
nClrBk = CLR_BKGNDSEL;
nClrBorder = CLR_BORDERSEL;
}
else
{
nClrBk = CLR_BKGNDMENU;
nClrBorder = CLR_BKGNDMENU;
}
if ( m_pfnCustomMenuItem )
hrgnItem = (HRGN)m_pfnCustomMenuItem( &rect );
if ( hrgnItem == NULL )
{
DrawRect( lpdisp->hDC,
m_clrMenu[nClrBorder],
m_clrMenu[nClrBk],
rect.left,
rect.top,
rect.right,
rect.bottom );
}
else
{
DrawRgn(lpdisp->hDC, m_clrMenu[nClrBorder], m_clrMenu[nClrBk], hrgnItem );
::DeleteObject( hrgnItem );
}
}
// Draw Menu Item's Name
void CHSMenu::DrawItemText(LPDRAWITEMSTRUCTPRO lpdisp)
{
HGDIOBJ hfntOld;
COLORREF clrText;
RECT rect;
RECT& rectT = lpdisp->rect;
rect.left = rectT.left + 20;
rect.top = ( rectT.top + rectT.bottom - m_nFontHeight ) / 2;
rect.right = 1000;
rect.bottom = 100;
if ( lpdisp->uFlags & ITEM_GRAY )
clrText = GetSysColor( COLOR_GRAYTEXT );
else
clrText = m_clrMenu[GetState( MENU_SELECTED ) ? CLR_TEXTSEL : CLR_TEXTNORMAL];
SetTextColor( lpdisp->hDC, clrText );
SetBkMode( lpdisp->hDC, TRANSPARENT );
hfntOld = SelectObject( lpdisp->hDC, m_hFont );
DrawText( lpdisp->hDC, lpdisp->lpcStr, -1, &rect, DT_NOCLIP|DT_LEFT );
SelectObject( lpdisp->hDC, hfntOld );
}
// Draw Separator Item
void CHSMenu::DrawItemSpr(LPDRAWITEMSTRUCTPRO lpdisp)
{
POINT pt[2];
RECT& rect = lpdisp->rect;
pt[0].x = rect.left + 8;
pt[1].x = rect.right - 8;
pt[0].y = pt[1].y = ( rect.top + rect.bottom ) / 2;
DrawPolyline( lpdisp->hDC, m_clrMenu[CLR_BORDERSPR], pt, 2 );
}
// Draw Item Arrow ( Only Popup Item has )
void CHSMenu::DrawItemArrow(LPDRAWITEMSTRUCTPRO lpdisp)
{
RECT& rect = lpdisp->rect;
int clrArrow;
if ( lpdisp->uFlags & ITEM_GRAY )
clrArrow = GetSysColor( COLOR_GRAYTEXT );
else
clrArrow = m_clrMenu[GetState( MENU_SELECTED ) ? CLR_ARROWSEL : CLR_TEXTNORMAL];
DrawArrow( lpdisp->hDC, clrArrow, rect.right-8, (rect.top+rect.bottom)/2, 4 );
}
BOOL CHSMenu::IsEffectItem()
{
if ( m_nCurSel == SELNONE ) return FALSE;
UINT uFlag = m_qMenuItem[m_nCurSel].m_uFlags;
return ( ( uFlag & ITEM_POPUP ) == 0 &&
( uFlag & ITEM_DISABLE ) == 0 &&
( uFlag & ITEM_GRAY ) == 0 &&
( uFlag & ITEM_SEPARATOR ) == 0
);
}
BOOL CHSMenu::PointInMenu(short x, short y)
{
if ( x>0 && x<m_nMenuWidth && y>0 && y<m_nMenuHeight )
{
HRGN hrgnMenu = ::CreateRectRgn( 0, 0, 0, 0 );
::GetWindowRgn( m_hMenu, hrgnMenu );
BOOL bInMenu = ::PtInRegion( hrgnMenu, x, y );
::DeleteObject( hrgnMenu );
return bInMenu;
}
return FALSE;
}
/*void CHSMenu::OnEraseBkgnd(HWND hWnd, HDC hDC)
{
}
*/
void CHSMenu::DrawMenuBkgnd(HWND hWnd, HDC hDC)
{
HRGN hrgnMenu = ::CreateRectRgn( 0, 0, 0, 0 );
::GetWindowRgn( hWnd, hrgnMenu );
DrawRgn( hDC, m_clrMenu[CLR_BORDERMENU], m_clrMenu[CLR_BKGNDMENU], hrgnMenu );
::DeleteObject( hrgnMenu );
}
void CHSMenu::DrawAnimateMenu( RECT *pRect, HDC hDC, HDC hDCMem, int nType, int nStep, int nTimeDelay)
{
DrawAnimation( pRect, hDC, hDCMem, nType, nStep, nTimeDelay );
/*
int nWidth = pRect->right - pRect->left;
int nHeight = pRect->bottom - pRect->top;
::BitBlt( hDC, pRect->left, pRect->top, nWidth, nHeight, hDCMem, 0, 0, SRCCOPY );
*/
}
void CHSMenu::OnPaint(HWND hWnd, HDC hDC)
{
//------------------------------------------------------------------------------------------
if ( !GetState( MENU_SELECTED ) && m_nCurPop == SELNONE && m_nCurSel == SELNONE && m_qMenuItem.size() )
{
RECT rect;
rect.left = rect.top = 0;
rect.right = m_nMenuWidth;
rect.bottom = m_nMenuHeight;
HDC hdcMem = ::CreateCompatibleDC( hDC );
HBITMAP hbmpMem = ::CreateCompatibleBitmap( hDC, m_nMenuWidth, m_nMenuHeight );
HGDIOBJ hobjOld = ::SelectObject( hdcMem, hbmpMem );
::BitBlt( hdcMem, 0, 0, m_nMenuWidth, m_nMenuHeight, hDC, 0, 0, SRCCOPY );
SetState( MENU_SELECTED, TRUE );
OnPaint( hWnd, hdcMem );
DrawAnimateMenu( &rect, hDC, hdcMem, m_nMenuAniType, m_nMenuAniStep, m_nMenuAniDelay );
::SelectObject( hdcMem, hobjOld );
::DeleteObject( hbmpMem );
::DeleteDC( hdcMem );
return;
}
//------------------------------------------------------------------------------------------
SetState( MENU_SELECTED, FALSE );
DrawMenuBkgnd( hWnd, hDC );
DRAWITEMSTRUCTPRO disp;
DEQUEITEM::const_iterator it, itend = m_qMenuItem.end();
disp.hDC = hDC;
disp.rect.left = m_nMenuEdge;
disp.rect.right = m_nMenuWidth - m_nMenuEdge;
for ( it = m_qMenuItem.begin(); it != itend; it++ )
{
disp.ulData = it->m_ulData;
disp.uFlags = it->m_uFlags | m_uMenuFlag;
disp.lpcStr = it->m_strName.c_str();
disp.rect.top = it->m_nTop;
disp.rect.bottom = it->m_nTop + it->m_nHeight;
DrawItemAnimation( &disp );
}
if ( m_nCurPop != SELNONE )
{
SetState( MENU_SELECTED, TRUE );
HSITEM& MenuItem = m_qMenuItem[m_nCurPop];
disp.ulData = MenuItem.m_ulData;
disp.uFlags = MenuItem.m_uFlags | m_uMenuFlag;
disp.lpcStr = MenuItem.m_strName.c_str();
disp.rect.top = MenuItem.m_nTop;
disp.rect.bottom = MenuItem.m_nTop + MenuItem.m_nHeight;
DrawItemAnimation( &disp );
}
}
#define ID_HSMENU_RENAME 1000
#define ID_HSMENU_PROPERTIY 1001
void CHSMenu::OnLButtonDown(HWND hWnd, short x, short y)
{
if ( !PointInMenu( x, y ) )
DestroyAllMenu();
}
void CHSMenu::OnLButtonUp(HWND hWnd, short x, short y)
{
if ( PointInMenu( x, y ) && IsEffectItem() )
{
DestroyAllMenu();
// ::SendMessage( m_hWndParent, WM_COMMAND, MAKEWORD( m_qMenuItem[m_nCurSel].m_uID, 0 ),0 );
::SendMessage( m_hWndParent, WM_COMMAND, m_qMenuItem[m_nCurSel].m_uID, 0 );
}
}
void CHSMenu::OnRButtonDown(HWND hWnd, short x, short y)
{
if ( !PointInMenu( x, y ) )
DestroyAllMenu();
}
void CHSMenu::OnRButtonUp(HWND hWnd, short x, short y)
{
/* if ( ::IsWindow( m_hMenu ) && PointInMenu( x, y ) )
{
CHSMenu* pHSMenu = new CHSMenu;
pHSMenu->CreateMenu();
pHSMenu->AppendMenu( "Rename", ID_HSMENU_RENAME );
pHSMenu->AppendMenu( "Propertiy", ID_HSMENU_PROPERTIY );
POINT pt;
pt.x = x;
pt.y = y;
::ClientToScreen( m_hMenu, &pt );
UINT uID = pHSMenu->TrackPopMenu( pt.x, pt.y, m_hWndParent );
delete pHSMenu;
switch( uID )
{
case ID_HSMENU_RENAME:
AfxMessageBox( "Rename" );
break;
case ID_HSMENU_PROPERTIY:
break;
default:;
}
::ReleaseCapture();
::SetCapture( hWnd );
}
*/
}
// this function cycle destroy all the popup item's son
void CHSMenu::DestroyAllPop( void )
{
if ( m_nCurPop == SELNONE ) return;
int nCurPop;
CHSMenu *pDel, *pNext;
pNext = m_qMenuItem[m_nCurPop].m_pPopupHSMenu;
::SetActiveWindow( m_hMenu );
do
{
pDel = pNext;
nCurPop = pDel->m_nCurPop;
if ( nCurPop != SELNONE )
pNext = pDel->m_qMenuItem[nCurPop].m_pPopupHSMenu;
else pNext = NULL;
pDel->DestroyMenu();
} while ( pNext );
m_nCurPop = SELNONE;
SetState( MENU_POPUPED, FALSE );
}
// Deatroy All Menu Window
void CHSMenu::DestroyAllMenu()
{
CHSMenu *pDel = this;
DestroyAllPop();
do
{
pDel->DestroyMenu();
pDel = pDel->m_pParent;
} while ( pDel );
}
inline void CHSMenu::DestroyMenu()
{
if ( m_hMenu )
{
SetState( MENU_SELECTED, FALSE );
SetState( MENU_POPUPED, FALSE );
::DestroyWindow( m_hMenu );
m_hMenu = NULL;
}
}
static LRESULT CALLBACK lpfnWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
CHSMenu *pHSMenu = (CHSMenu *)( GetWindowLong( hWnd, GWL_USERDATA ) );
static nn=0;
switch ( uMsg )
{
case WM_MOUSEMOVE:
pHSMenu->OnMouseMove( hWnd, LOWORD(lParam), HIWORD(lParam) );
break;
case WM_TIMER:
pHSMenu->OnTimer( hWnd, wParam );
break;
case WM_LBUTTONDOWN:
pHSMenu->OnLButtonDown( hWnd, LOWORD(lParam), HIWORD(lParam) );
break;
case WM_LBUTTONUP:
pHSMenu->OnLButtonUp( hWnd, LOWORD(lParam), HIWORD(lParam) );
break;
case WM_RBUTTONDOWN:
pHSMenu->OnRButtonDown( hWnd, LOWORD(lParam), HIWORD(lParam) );
break;
case WM_RBUTTONUP:
pHSMenu->OnRButtonUp( hWnd, LOWORD(lParam), HIWORD(lParam) );
break;
// case WM_ERASEBKGND:
// pHSMenu->OnEraseBkgnd( hWnd, (HDC)wParam );
// break;
case WM_PAINT:
{
PAINTSTRUCT ps;
BeginPaint( hWnd, &ps );
pHSMenu->OnPaint( hWnd, ps.hdc );
EndPaint( hWnd, &ps );
}
break;
// case WM_MOUSEWHEEL:
// break;
case WM_MBUTTONDOWN:
pHSMenu->OnRButtonDown( hWnd, LOWORD(lParam), HIWORD(lParam) );
break;
case WM_KEYDOWN:
pHSMenu->OnKeyDown( hWnd, (UINT)wParam, HIWORD(lParam), LOWORD(lParam));
break;
// case WM_KEYUP:
// pHSMenu->OnKeyUp( hWnd, (UINT)wParam, HIWORD(lParam), LOWORD(lParam));
// break;
// case WM_CHAR:
// pHSMenu->OnChar( hWnd, (char)wParam );
// break;
case WM_SYSKEYDOWN:
pHSMenu->DestroyAllMenu();
break;
case WM_ACTIVATE:
{
if ( LOWORD(wParam) == WA_INACTIVE && pHSMenu->m_hWndParent != (HWND)lParam )
{
TCHAR sClassName[50];
GetClassName( (HWND)lParam, sClassName, sizeof(sClassName)/sizeof(TCHAR) );
if ( lstrcmp( sClassName, "HSMENU_PRODUCT_BY_HANSONG" ) )
pHSMenu->DestroyAllMenu();
}
} break;
// case WM_CAPTURECHANGED:
// break;
case WM_CREATE:
SetWindowLong( hWnd, GWL_USERDATA, (long)( (LPCREATESTRUCT)lParam )->lpCreateParams );
break;
// case WM_DESTROY:
// pHSMenu->OnDestroy( hWnd );
// break;
default:
return DefWindowProc( hWnd, uMsg, wParam, lParam );
}
return 0;
}
DWORD CustomMenu(HWND hMenu)
{
HRGN hRgn;
RECT rect;
::GetWindowRect( hMenu, &rect );
int nMenuWidth = rect.right - rect.left;
int nMenuHeight = rect.bottom - rect.top ;
// hRgn = CreateRoundRectRgn( 0, 0, nMenuWidth, nMenuHeight, 20, 20 );
int nRate = 9;
POINT ptSel[6];
ptSel[0].x = nRate;
ptSel[0].y = 0;
ptSel[1].x = nMenuWidth;
ptSel[1].y = 0;
ptSel[2].x = nMenuWidth;
ptSel[2].y = nMenuHeight - nRate;
ptSel[3].x = nMenuWidth - nRate;
ptSel[3].y = nMenuHeight;
ptSel[4].x = 0;
ptSel[4].y = nMenuHeight;
ptSel[5].x = 0;
ptSel[5].y = nRate;
hRgn = ::CreatePolygonRgn( ptSel, 6, WINDING );
::SetWindowRgn( hMenu, hRgn, true );
::DeleteObject( hRgn );
//-----------------------------------------------------------------------------------
/*
// Translucence window
// Only active on platform windows2000/xp
// win98/me do not support.
// Do not enable that code when the animate stype of class 'CHSMenu' is turn on
// unless the performance of your CPU is excellent !
SetWindowLong( hMenu, GWL_EXSTYLE, GetWindowLong( hMenu, GWL_EXSTYLE ) | 0x80000 );
HINSTANCE instance = LoadLibrary( "User32.dll" );
if ( instance )
{
typedef BOOL ( WINAPI *PSETLAYEREDWINDOWATTRIBUTES )( HWND, COLORREF, BYTE, DWORD );
PSETLAYEREDWINDOWATTRIBUTES pSetLayeredWindowAttributes = NULL;
pSetLayeredWindowAttributes = (PSETLAYEREDWINDOWATTRIBUTES)GetProcAddress( instance, "SetLayeredWindowAttributes" );
if ( pSetLayeredWindowAttributes )
pSetLayeredWindowAttributes( hMenu, 0, 231, 2 );
FreeLibrary( instance );
}
*/
//-----------------------------------------------------------------------------------
return DWORD(0);
}
DWORD CustomMenuItem( const RECT *prcItem )
{
// return CreateRoundRectRgn( prcItem->left, prcItem->top, prcItem->right, prcItem->bottom,18,18 );
/*
{
HRGN hRgnRect, hRgnElliptic;
hrgnBk = CreateRectRgn( 0, 0, 0, 0 );
hRgnRect = CreateRectRgn( prcItem->left, prcItem->top, prcItem->right, prcItem->bottom );
hRgnElliptic = CreateEllipticRgn( prcItem->left-20, prcItem->top, prcItem->left+30, prcItem->bottom );
CombineRgn( hrgnBk, hRgnRect, hRgnElliptic, RGN_DIFF );
hrgnBk = CreateRectRgn( prcItem->left, prcItem->top, prcItem->right, prcItem->bottom );
hrgnBk = CreateRoundRectRgn( prcItem->left, prcItem->top, prcItem->right, prcItem->bottom, 18, 18 );
}
*/
int nRate = 9;
POINT ptSel[6];
ptSel[0].x = prcItem->left + nRate;
ptSel[0].y = prcItem->top;
ptSel[1].x = prcItem->right;
ptSel[1].y = prcItem->top;
ptSel[2].x = prcItem->right;
ptSel[2].y = prcItem->bottom - nRate ;
ptSel[3].x = prcItem->right - nRate;
ptSel[3].y = prcItem->bottom;
ptSel[4].x = prcItem->left;
ptSel[4].y = prcItem->bottom;
ptSel[5].x = prcItem->left;
ptSel[5].y = prcItem->top + nRate;
return (DWORD)CreatePolygonRgn( ptSel, 6, WINDING );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -