📄 menubar.cpp
字号:
return;
}
CToolBar::OnLButtonUp( nFlags, point );
}
void CMenuBar::OnMouseMove( UINT nFlags, CPoint point )
{
if ( m_bItemTracking )
{
if ( m_bItemDropped && ( m_ptMouseLast == point ) )
{
return; // mouse has not actually moved
}
if ( IsOverChevron( point ) )
{
ShowChevronMenu( -1 );
return;
}
CPoint ptScreen( point );
ClientToScreen( &ptScreen );
if ( WindowFromPoint( ptScreen ) != this )
{
return;
}
}
m_ptMouseLast = point;
if ( !m_bItemTracking && m_bButtonCapture )
{
// Are we over any of the sys-buttons?
for ( int nIndex = 0; nIndex <= m_aMenuBarButtons.GetUpperBound(); nIndex++ )
{
CMenuBarButton* pButton = m_aMenuBarButtons[ nIndex ];
bool bPush = pButton->IsEnabled() && pButton->HitTest( point );
if ( bPush != pButton->PushButton( bPush ) )
{
RedrawWindow( pButton->GetButtonRect(), 0,
RDW_INVALIDATE | RDW_ERASE ); // visual feedback
}
}
return;
}
CToolBar::OnMouseMove( nFlags, point );
}
void CMenuBar::OnLButtonDblClk( UINT nFlags, CPoint point )
{
CRect rcSysMenu;
GetItemRect( 0, rcSysMenu );
// If we are over sys-menu button, send Close command
if ( rcSysMenu.PtInRect( point ) )
{
::PostMessage( m_hWndMDIChild, WM_SYSCOMMAND, SC_CLOSE, 0 );
return;
}
CToolBar::OnLButtonDblClk( nFlags, point );
}
void CMenuBar::OnCaptureChanged( CWnd* pWnd )
{
if ( m_bButtonCapture && ( pWnd != this ) )
{
for ( int nIndex = 0; nIndex <= m_aMenuBarButtons.GetUpperBound(); nIndex++ )
{
CMenuBarButton* pButton = m_aMenuBarButtons[ nIndex ];
if ( pButton->PushButton( false ) )
{
RedrawWindow( pButton->GetButtonRect(), 0,
RDW_INVALIDATE | RDW_ERASE );
}
}
m_bButtonCapture = false;
}
CToolBar::OnCaptureChanged( pWnd );
}
void CMenuBar::OnKeyDown( UINT nChar, UINT nRepCnt, UINT nFlags )
{
if ( m_bItemTracking )
{
switch ( nChar )
{
case VK_SPACE:
ExitTrackingMode();
GetParentFrame()->PostMessage( WM_SYSCOMMAND, SC_KEYMENU, 32 );
return;
case VK_ESCAPE:
ExitTrackingMode();
return;
default:
break;
}
}
CToolBar::OnKeyDown( nChar, nRepCnt, nFlags );
}
void CMenuBar::OnSysKeyDown( UINT /*nChar*/, UINT /*nRepCnt*/, UINT /*nFlags*/ )
{
ExitTrackingMode();
// CToolBar::OnSysKeyDown( nChar, nRepCnt, nFlags );
}
void CMenuBar::OnKillFocus( CWnd* pNewWnd )
{
CToolBar::OnKillFocus( pNewWnd );
if ( m_bItemTracking )
{
ExitTrackingMode();
}
}
UINT CMenuBar::OnGetDlgCode()
{
return ( CToolBar::OnGetDlgCode() | ( m_bItemTracking ? DLGC_WANTALLKEYS : 0 ) );
}
void CMenuBar::OnSettingChange( UINT uFlags, LPCTSTR lpszSection )
{
CToolBar::OnSettingChange( uFlags, lpszSection );
UpdateMenuBar();
}
LRESULT CMenuBar::OnShowPopupMenu( WPARAM wParam, LPARAM lParam )
{
int nItem = ( int )wParam;
bool bSelectFirst = ( LOWORD( lParam ) != 0 );
bool bCheckClipped = ( HIWORD( lParam ) != 0 );
// If item is clipped, show chevron menu
if ( bCheckClipped && IsItemClipped( nItem ) )
{
ShowChevronMenu( nItem );
}
// otherwise, track "normal" popup menu
else
{
EnterTrackingMode( nItem );
m_nItem = nItem;
m_bSelectFirst = bSelectFirst;
m_bContinue = true;
m_bEscape = false;
TrackPopupMenu();
// If menu was closed by pressing Esc, stay in tracking mode
if ( m_bEscape )
{
SetCapture();
SendMessage( WM_SETCURSOR, ( WPARAM )m_hWnd, MAKELPARAM( HTCLIENT, 0 ) );
}
// otherwise, exit tracking mode
else
{
ExitTrackingMode();
}
}
return 0L;
}
LRESULT CMenuBar::OnReBarChildSize( WPARAM /*wParam*/, LPARAM lParam )
{
// CRect rcBand ( ( LPCRECT )wParam );
CRect rcChild( ( LPCRECT )lParam );
rcChild.OffsetRect( -rcChild.TopLeft() );
RepositionSysButtons( rcChild );
return 0L;
}
LRESULT CMenuBar::OnReBarChevronPushed( WPARAM wParam, LPARAM lParam )
{
CRect rcChevron( ( LPCRECT )wParam );
int nItem = ( int )lParam - 1;
TrackChevronMenu( rcChevron, nItem );
return 0L;
}
void CMenuBar::OnUpdateCommandUI( CCmdUI* pCmdUI )
{
// Do not disable menu buttons
if ( ( pCmdUI->m_nID < IDBUTTON_FIRST ) || ( pCmdUI->m_nID > IDBUTTON_LAST ) )
{
pCmdUI->ContinueRouting();
}
}
void CMenuBar::OnDropDown( NMHDR* pNMHDR, LRESULT* pResult )
{
NMTOOLBAR* pNMToolBar = ( NMTOOLBAR* )pNMHDR;
if ( !m_bItemDropped )
{
int nItem = CommandToIndex( pNMToolBar->iItem );
bool bLButtonDown = ( ::GetKeyState( VK_LBUTTON ) < 0 );
PostMessage( WM_MB_SHOWPOPUPMENU, nItem,
MAKELPARAM( bLButtonDown ? FALSE : TRUE, bLButtonDown ? FALSE : TRUE ) );
}
*pResult = TBDDRET_DEFAULT;
}
void CMenuBar::OnHotItemChange( NMHDR* pNMHDR, LRESULT* pResult )
{
NMTBHOTITEM* pNMTBHotItem = ( NMTBHOTITEM* )pNMHDR;
if ( m_bItemTracking)
{
// Is it really new hot item?
int nItem = ( pNMTBHotItem->dwFlags & HICF_LEAVING ) ? -1 : CommandToIndex( ( UINT )pNMTBHotItem->idNew );
if ( m_nItem != nItem )
{
// Was it changed not by SetHotItem()?
if ( pNMTBHotItem->dwFlags & ( HICF_ACCELERATOR | HICF_ARROWKEYS | HICF_DUPACCEL | HICF_MOUSE ) )
{
// There should be always hot item in tracking mode
if ( nItem == -1)
{
*pResult = 1;
return;
}
// If item is clipped, show chevron menu
if ( IsItemClipped( nItem ) )
{
ShowChevronMenu( nItem );
}
// If we are tracking popup menu, track new one, associated with hot item
else if ( m_bItemDropped )
{
ContinueTracking( !( pNMTBHotItem->dwFlags & HICF_MOUSE ) );
}
}
m_nItem = nItem; // remember last hot item
}
}
*pResult = 0;
}
void CMenuBar::OnCustomDraw( NMHDR* pNMHDR, LRESULT* pResult )
{
LPNMTBCUSTOMDRAW lpNMCustomDraw = ( LPNMTBCUSTOMDRAW )pNMHDR;
switch ( lpNMCustomDraw->nmcd.dwDrawStage )
{
case CDDS_PREERASE:
*pResult = CDRF_NOTIFYPOSTERASE;
break;
case CDDS_POSTERASE:
{
CDC* pDC = CDC::FromHandle( lpNMCustomDraw->nmcd.hdc );
// Draw the sys-buttons
for ( int nIndex = 0; nIndex <= m_aMenuBarButtons.GetUpperBound(); nIndex++ )
{
m_aMenuBarButtons[ nIndex ]->DrawButton( pDC );
}
*pResult = CDRF_DODEFAULT;
break;
}
case CDDS_PREPAINT:
*pResult = CDRF_NOTIFYITEMDRAW;
break;
case CDDS_ITEMPREPAINT:
{
NMCUSTOMDRAW& nmcd = lpNMCustomDraw->nmcd;
CDC* pDC = CDC::FromHandle( nmcd.hdc );
UINT nID = nmcd.dwItemSpec;
switch ( nID )
{
case IDBUTTON_SYSMENU: // draw sys-menu button
{
HICON hIcon = ( HICON )::GetClassLong( m_hWndMDIChild, GCL_HICONSM );
if ( hIcon != 0 )
{
// Icon has 2 pixel border on left, 1 pixel on top/bottom, 0 right
CSize sz( CMenuBarButton::GetButtonSize() );
sz.cx -= 2;
sz.cy -= 2;
CRect rc( &nmcd.rc );
rc.left += 2;
rc.top += ( rc.Height() - sz.cy ) / 2;
rc.right = rc.left + sz.cx;
rc.bottom = rc.top + sz.cy;
/*
CImageList imageList;
VERIFY( imageList.Create( sz.cx, sz.cy, ILC_COLOR | ILC_MASK, 1, 0 ) );
VERIFY( imageList.Draw( pDC, imageList.Add( hIcon ), rc.TopLeft(),
( nmcd.uItemState & CDIS_HOT ) ? ILD_BLEND25 : ILD_NORMAL ) );
*/
VERIFY( ::DrawIconEx( pDC->GetSafeHdc(), rc.left, rc.top, hIcon,
rc.Width(), rc.Height(), 0, 0, DI_NORMAL ) );
}
*pResult = CDRF_SKIPDEFAULT;
break;
}
default:
if ( CWinAppEx::GetInstance()->IsWin98_2K() && GetToolBarCtrl().IsButtonEnabled( nID ) )
{
// If main frame is not active, gray buttons
lpNMCustomDraw->clrText = ::GetSysColor(
m_bFrameActive ? COLOR_MENUTEXT : COLOR_3DSHADOW );
}
*pResult = CDRF_DODEFAULT;
break;
}
break;
}
default:
*pResult = CDRF_DODEFAULT;
break;
}
}
/////////////////////////////////////////////////////////////////////////////
// Implementation
void CMenuBar::HookMessageProc( UINT message, WPARAM wParam, LPARAM lParam )
{
switch ( message )
{
case WM_MOUSEMOVE:
case WM_LBUTTONDBLCLK:
{
CPoint pt( LOWORD( lParam ), HIWORD( lParam ) );
ScreenToClient( &pt );
SendMessage( message, wParam, MAKELPARAM( pt.x, pt.y ) );
break;
}
case WM_KEYDOWN:
{
UINT nChar = ( UINT )wParam;
bool bForward = false; // by default
switch ( nChar )
{
case VK_LEFT:
bForward = m_bPrimaryMenu;
break;
case VK_RIGHT:
bForward = !m_bSubmenuItem;
break;
case VK_ESCAPE:
m_bEscape = m_bPrimaryMenu;
break;
}
// Should we forward this message to the menu bar?
if ( bForward )
{
SendMessage( message, wParam, lParam );
}
break;
}
default:
break;
}
}
LRESULT CALLBACK CMenuBar::MessageProc( int code, WPARAM wParam, LPARAM lParam )
{
ASSERT( m_pMenuBar != 0 );
if ( code == MSGF_MENU )
{
MSG* pMsg = ( MSG* )lParam;
m_pMenuBar->HookMessageProc( pMsg->message, pMsg->wParam, pMsg->lParam );
}
return ::CallNextHookEx( m_hMsgHook, code, wParam, lParam );
}
bool CMenuBar::FrameOnSysCommand( UINT nID, LPARAM lParam )
{
if ( IsVisible() && ( ( nID & 0xFFF0 ) == SC_KEYMENU ) && ( lParam == 0 ) )
{
if ( IsItemClipped( 1 ) )
{
ShowChevronMenu( -1 );
}
else
{
EnterTrackingMode( 1 );
}
return true;
}
return false;
}
bool CMenuBar::FrameOnMenuChar( UINT nChar, UINT nFlags, CMenu* /*pMenu*/ )
{
if ( IsVisible() && ( nFlags & MF_SYSMENU ) )
{
UINT nID;
if ( GetToolBarCtrl().MapAccelerator( ( TCHAR )nChar, &nID ) )
{
PostMessage( WM_MB_SHOWPOPUPMENU, CommandToIndex( nID ), MAKELPARAM( TRUE, TRUE ) );
return true;
}
}
return false;
}
void CMenuBar::FrameOnNcActivate( BOOL bActive )
{
m_bFrameActive = ( bActive == TRUE );
Invalidate();
UpdateWindow();
}
void CMenuBar::FrameOnInitMenuPopup( CMenu* pPopupMenu, UINT nIndex, BOOL /*bSysMenu*/ )
{
if ( m_hMenuTracking != 0 )
{
HMENU hMenu = pPopupMenu->GetSafeHmenu();
// We should know if it is primary menu and whether or not selected
// item is submenu item to handle Esc/Left/Right keys correctly
m_bPrimaryMenu = ( hMenu == m_hMenuTracking );
m_bSubmenuItem = ( ::GetSubMenu( hMenu, nIndex ) != 0 );
}
}
void CMenuBar::FrameOnMenuSelect( UINT /*nItemID*/, UINT nFlags, HMENU hSysMenu )
{
if ( m_hMenuTracking != 0 )
{
// We should know if it is primary menu and whether or not selected
// item is submenu item to handle Esc/Left/Right keys correctly
m_bPrimaryMenu = ( hSysMenu == m_hMenuTracking );
m_bSubmenuItem = ( nFlags & MF_POPUP ) != 0;//( ::GetSubMenu( hSysMenu, nItemID ) != 0 );
}
}
void CMenuBar::OnUpdateMenuButton(CCmdUI* pCmdUI)
{
ASSERT_VALID(this);
if ((pCmdUI->m_nID>=IDBUTTON_FIRST)&&(pCmdUI->m_nID<=IDBUTTON_LAST))
pCmdUI->Enable(TRUE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -