bcgmenubar.cpp
来自「用bcg库编写的java IDE 源码」· C++ 代码 · 共 1,479 行 · 第 1/3 页
CPP
1,479 行
//*******************************************************************************
// COPYRIGHT NOTES
// ---------------
// This source code is a part of BCGControlBar library.
// You may use, compile or redistribute it as part of your application
// for free. You cannot redistribute it as a part of a software development
// library without the agreement of the author. If the sources are
// distributed along with the application, you should leave the original
// copyright notes in the source code without any changes.
// This code can be used WITHOUT ANY WARRANTIES on your own risk.
//
// Stas Levin <stas@iet.co.il>
//*******************************************************************************
// BCGMenuBar.cpp : implementation file
//
#include "stdafx.h"
#include "globals.h"
#include "BCGMenuBar.h"
#include "BCGToolbarButton.h"
#include "BCGToolbarMenuButton.h"
#include "BCGToolbarSystemMenuButton.h"
#include "BCGToolbarMenuButtonsButton.h"
#include "BCGPopupMenu.h"
#include "MenuHash.h"
#include "bcgbarres.h"
#include "bcglocalres.h"
#include "BCGMDIFrameWnd.h"
#include "BCGFrameWnd.h"
#include "BCGOleIPFrameWnd.h"
#include "BCGMultiDocTemplate.h"
#include "BCGDockBar.h"
#include "RegPath.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
IMPLEMENT_SERIAL(CBCGMenuBar, CBCGToolBar, VERSIONABLE_SCHEMA | 1)
HHOOK CBCGMenuBar::m_hookMouseDrag = NULL;
CBCGMenuBar* CBCGMenuBar::m_pDraggedMenuBar = NULL;
BOOL CBCGMenuBar::m_bShowAllCommands = FALSE;
BOOL CBCGMenuBar::m_bRecentlyUsedMenus = TRUE;
BOOL CBCGMenuBar::m_bShowAllMenusDelay = TRUE;
BOOL CBCGMenuBar::m_bMenuShadows = TRUE;
static const UINT uiShowAllItemsTimerId = 1;
static const int iShowAllItemsTimerFreq = 5000; // 5 sec
static const CString strMenuProfile = _T("BCGMenuBar");
/////////////////////////////////////////////////////////////////////////////
// CBCGMenuBar
CBCGMenuBar::CBCGMenuBar()
{
m_bMaximizeMode = FALSE;
m_bActualMaximizeMode = FALSE;
m_hMenu = NULL;
m_hDefaultMenu = NULL;
m_hSysMenu = NULL;
m_hSysIcon = NULL;
m_uiDefMenuResId = 0;
m_nSystemButtonsNum = 0;
m_nSystemButtonsNumSaved = 0;
m_bHaveButtons = FALSE;
m_szSystemButton = CSize (0, 0);
m_bAutoDocMenus = TRUE;
m_bMenuBar = TRUE;
}
CBCGMenuBar::~CBCGMenuBar()
{
SetDragMode (FALSE);
::DestroyMenu (m_hMenu);
}
BEGIN_MESSAGE_MAP(CBCGMenuBar, CBCGToolBar)
//{{AFX_MSG_MAP(CBCGMenuBar)
ON_WM_CREATE()
ON_WM_LBUTTONDOWN()
ON_WM_KILLFOCUS()
ON_WM_SETFOCUS()
ON_WM_WINDOWPOSCHANGED()
ON_WM_TIMER()
ON_WM_LBUTTONDBLCLK()
ON_WM_SETTINGCHANGE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CBCGMenuBar message handlers
void CBCGMenuBar::CreateFromMenu (HMENU hMenu, BOOL bDefaultMenu)
{
if (GetFocus () == this)
{
GetParentFrame()->SetFocus ();
}
g_menuHash.SaveMenuBar (m_hMenu, this);
BOOL bMaximizeMode = m_bMaximizeMode;
m_bMaximizeMode = FALSE;
m_hMenu = hMenu;
if (bDefaultMenu)
{
m_hDefaultMenu = hMenu;
}
if (!g_menuHash.LoadMenuBar (hMenu, this))
{
CMenu* pMenu = CMenu::FromHandle (hMenu);
if (pMenu == NULL)
{
return;
}
RemoveAllButtons ();
int iCount = (int) pMenu->GetMenuItemCount ();
for (int i = 0; i < iCount; i ++)
{
UINT uiID = pMenu->GetMenuItemID (i);
CString strText;
pMenu->GetMenuString (i, strText, MF_BYPOSITION);
switch (uiID)
{
case -1: // Pop-up menu
{
CMenu* pPopupMenu = pMenu->GetSubMenu (i);
ASSERT (pPopupMenu != NULL);
CBCGToolbarMenuButton button (
0, pPopupMenu->GetSafeHmenu (), -1, strText);
button.m_bText = TRUE;
button.m_bImage = FALSE;
InsertButton (button);
}
break;
case 0: // Separator
InsertSeparator ();
break;
default: // Regular command
{
CBCGToolbarButton button (uiID, -1, strText);
button.m_bText = TRUE;
button.m_bImage = FALSE;
InsertButton (button);
}
break;
}
}
}
if (bMaximizeMode)
{
CMDIFrameWnd* pParentFrame = DYNAMIC_DOWNCAST (CMDIFrameWnd, m_pParentWnd);
if (pParentFrame != NULL)
{
SetMaximizeMode (TRUE, pParentFrame->MDIGetActive ());
}
}
if (GetSafeHwnd () != NULL)
{
AdjustLayout ();
}
RebuildAccelerationKeys ();
}
//***************************************************************************************
CSize CBCGMenuBar::CalcDynamicLayout (int nLength, DWORD dwMode)
{
return CalcLayout(dwMode, nLength);
}
//**********************************************************************************
CSize CBCGMenuBar::CalcLayout(DWORD dwMode, int nLength)
{
OnChangeHot (-1);
//------------------------------------------
// Is menu bar have the buttons with images?
//------------------------------------------
m_bHaveButtons = FALSE;
for (POSITION pos = m_Buttons.GetHeadPosition (); pos != NULL;)
{
CBCGToolbarButton* pButton = (CBCGToolbarButton*) m_Buttons.GetNext (pos);
ASSERT_VALID (pButton);
if (!pButton->IsKindOf (RUNTIME_CLASS (CBCGToolbarMenuButtonsButton)) &&
!pButton->IsKindOf (RUNTIME_CLASS (CBCGToolbarSystemMenuButton)) &&
pButton->m_bImage && pButton->IsDrawImage ())
{
m_bHaveButtons = TRUE;
break;
}
}
if (m_pDockContext != NULL &&
m_pDockContext->m_bDragging)
{
SetDragMode (TRUE);
}
if ((dwMode == (LM_HORZ | LM_MRUWIDTH)) ||
(m_pDockContext != NULL && !m_pDockContext->m_bDragging &&
IsFloating ()))
{
return CBCGToolBar::CalcLayout (dwMode, nLength);
}
BOOL bVert = (dwMode & LM_VERTDOCK) || ((dwMode & LM_HORZ) == 0);
CRect rect; rect.SetRectEmpty ();
if (m_pDockBar != NULL)
{
rect = ((CBCGDockBar*) m_pDockBar)->m_rectLayout;
}
if (rect.IsRectEmpty ())
{
CWnd* pFrame = GetOwner ();
pFrame->GetClientRect(&rect);
}
CSize size;
CRect rectClient;
rectClient.SetRectEmpty();
CalcInsideRect (rectClient, (dwMode & LM_HORZ));
if (!bVert)
{
WrapToolBar (rect.Width ());
//-------------------------------------
// Calculate size again after wrapping:
//-------------------------------------
size = CalcSize (FALSE);
size.cx = rect.Width () - rectClient.Width() / 2;
size.cy -= rectClient.Height();
}
else
{
//-------------------------------------
// Calculate size again after wrapping:
//-------------------------------------
size = CalcSize (TRUE);
size.cy = rect.Height () - rectClient.Height() / 2;
size.cx -= rectClient.Width();
}
//--------------------------------------------------
// Something may changed, rebuild acceleration keys:
//--------------------------------------------------
RebuildAccelerationKeys ();
return size;
}
//***************************************************************************************
void CBCGMenuBar::SetMaximizeMode (BOOL bMax, CWnd* pWnd)
{
if (m_bMaximizeMode == bMax ||
(bMax && IsCustomizeMode ()))
{
return;
}
if (bMax)
{
if (pWnd == NULL)
{
bMax = FALSE;
}
else
{
// get the sys menu.
m_hSysMenu = pWnd->GetSystemMenu (FALSE)->GetSafeHmenu ();
// If we have a system menu, then add a system menu button.
if (m_hSysMenu != NULL)
{
m_hSysIcon = pWnd->GetIcon (FALSE);
if (m_hSysIcon == NULL)
{
m_hSysIcon = (HICON) GetClassLong (*pWnd, GCL_HICONSM);
}
InsertButton (CBCGToolbarSystemMenuButton (m_hSysMenu, m_hSysIcon), 0);
}
LONG style = ::GetWindowLong(*pWnd, GWL_STYLE);
// Assume no buttons.
m_nSystemButtonsNum = 0;
// Add a minimize box if required.
if (style & WS_MINIMIZEBOX)
{
InsertButton (CBCGToolbarMenuButtonsButton (SC_MINIMIZE));
m_nSystemButtonsNum++;
}
// Add a restore box if required.
if (style & WS_MAXIMIZEBOX)
{
InsertButton (CBCGToolbarMenuButtonsButton (SC_RESTORE));
m_nSystemButtonsNum++;
}
// Add a close box if required.
if (m_hSysMenu != NULL)
{
//--------------------------------------------------------------
// Jan Vasina: check if the maximized window has its system menu
// with the close button enabled:
//--------------------------------------------------------------
CBCGToolbarMenuButtonsButton closeButton (SC_CLOSE);
MENUITEMINFO menuInfo;
ZeroMemory(&menuInfo,sizeof(MENUITEMINFO));
menuInfo.cbSize = sizeof(MENUITEMINFO);
menuInfo.fMask = MIIM_STATE;
::GetMenuItemInfo(m_hSysMenu, SC_CLOSE, FALSE, &menuInfo);
if ((menuInfo.fState & MFS_GRAYED) ||
(menuInfo.fState & MFS_DISABLED))
{
closeButton.m_nStyle |= TBBS_DISABLED;
}
InsertButton (closeButton);
m_nSystemButtonsNum++;
}
}
}
else
{
m_nSystemButtonsNumSaved = m_nSystemButtonsNum; // By Jon Wang
// Remove first button if a system menu was added.
if (m_hSysMenu != NULL)
{
RemoveButton (0);
}
for (int i = 0; i < m_nSystemButtonsNum; i ++)
{
CBCGToolbarMenuButtonsButton* pButton =
(CBCGToolbarMenuButtonsButton*) m_Buttons.RemoveTail ();
ASSERT_KINDOF (CBCGToolbarMenuButtonsButton, pButton);
delete pButton;
}
// Now we habe no system buttons on the menu.
m_nSystemButtonsNum = 0;
}
m_bMaximizeMode = bMax;
AdjustLayout ();
}
//***************************************************************************************
void CBCGMenuBar::RestoreMaximizeMode ()
{
if (m_bMaximizeMode)
{
return;
}
CBCGToolbarSystemMenuButton button (m_hSysMenu, m_hSysIcon);
InsertButton (button, 0);
InsertButton (CBCGToolbarMenuButtonsButton (SC_MINIMIZE));
InsertButton (CBCGToolbarMenuButtonsButton (SC_RESTORE));
InsertButton (CBCGToolbarMenuButtonsButton (SC_CLOSE));
m_bMaximizeMode = TRUE;
m_nSystemButtonsNum = m_nSystemButtonsNumSaved;
GetParentFrame ()->RecalcLayout ();
Invalidate ();
UpdateWindow ();
}
//***************************************************************************************
void CBCGMenuBar::AdjustLocations ()
{
CBCGToolBar::AdjustLocations ();
if (!m_bMaximizeMode)
{
return;
}
CRect rectClient;
GetClientRect (&rectClient);
BOOL bHorz = m_dwStyle & CBRS_ORIENT_HORZ ? TRUE : FALSE;
int iButtonWidth = m_szSystemButton.cx;
int iButtonHeight = m_szSystemButton.cy;
POSITION pos = m_Buttons.GetTailPosition ();
CRect rect = rectClient;
rectClient.SetRectEmpty ();
CalcInsideRect (rectClient, bHorz);
if (!bHorz)
{
rect.bottom += rectClient.Height ();
}
rect.left = rect.right - iButtonWidth;
rect.top = rect.bottom - iButtonHeight;
for (int i = 0; i < m_nSystemButtonsNum; i ++)
{
ASSERT (pos != NULL);
CBCGToolbarMenuButtonsButton* pButton =
(CBCGToolbarMenuButtonsButton*) m_Buttons.GetPrev (pos);
ASSERT_KINDOF (CBCGToolbarMenuButtonsButton, pButton);
pButton->SetRect (rect);
if (bHorz)
{
rect.OffsetRect (-iButtonWidth - 1, 0);
}
else
{
rect.OffsetRect (0, -iButtonHeight - 1);
}
}
}
//***************************************************************************************
BOOL CBCGMenuBar::OnSendCommand (const CBCGToolbarButton* pButton)
{
CBCGToolbarMenuButtonsButton* pSysButton =
DYNAMIC_DOWNCAST (CBCGToolbarMenuButtonsButton, pButton);
if (pSysButton == NULL)
{
return FALSE;
}
if (pSysButton->m_uiSystemCommand != SC_CLOSE &&
pSysButton->m_uiSystemCommand != SC_MINIMIZE &&
pSysButton->m_uiSystemCommand != SC_RESTORE)
{
ASSERT (FALSE);
return TRUE;
}
CMDIFrameWnd* pParentFrame =
DYNAMIC_DOWNCAST (CMDIFrameWnd, m_pParentWnd);
if (pParentFrame == NULL)
{
MessageBeep ((UINT) -1);
return TRUE;
}
CMDIChildWnd* pChild = pParentFrame->MDIGetActive ();
ASSERT_VALID (pChild);
pChild->SendMessage (WM_SYSCOMMAND, pSysButton->m_uiSystemCommand);
return TRUE;
}
//*************************************************************************************
int CBCGMenuBar::OnToolHitTest(CPoint point, TOOLINFO* pTI) const
{
ASSERT_VALID(this);
int nHit = ((CBCGMenuBar*)this)->HitTest(point);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?