📄 bcgppopupmenubar.cpp
字号:
//*******************************************************************************
// COPYRIGHT NOTES
// ---------------
// This is a part of the BCGControlBar Library
// Copyright (C) 1998-2000 BCGSoft Ltd.
// All rights reserved.
//
// This source code can be used, distributed or modified
// only under terms and conditions
// of the accompanying license agreement.
//*******************************************************************************
// BCGPPopupMenuBar.cpp : implementation file
//
#include "stdafx.h"
#include <afxpriv.h>
#pragma warning (disable : 4201)
#include "mmsystem.h"
#pragma warning (default : 4201)
#include "BCGPPopupMenuBar.h"
#include "BCGPToolbarButton.h"
#include "BCGPToolbarMenuButton.h"
#include "BCGPPopupMenu.h"
#include "BCGPCommandManager.h"
#include "BCGPTearOffManager.h"
#include "BCGGlobals.h"
#include "BCGPToolbarMenuButton.h"
#include "bcgprores.h"
#include "BCGPLocalResource.h"
#include "BCGPMenuBar.h"
#include "BCGPToolbarComboBoxButton.h"
#include "BCGPUserToolsManager.h"
#include "BCGPRegistry.h"
#include "BCGPKeyboardManager.h"
#include "BCGPSound.h"
#include "BCGPFrameImpl.h"
#include "MenuHash.h"
#include "BCGPVisualManager.h"
#include "BCGPDrawManager.h"
#include "BCGPContextMenuManager.h"
#include "BCGPShowAllButton.h"
#include "BCGPCustomizeMenuButton.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
static const int iVertMargin = 1;
static const int iHorzMargin = 1;
static const int iSeparatorHeight = 8;
static const int iMinTabSpace = 10;
static const int iEmptyMenuWidth = 50;
static const int iEmptyMenuHeight = 20;
static const int uiPopupTimerEvent = 1;
static const int uiRemovePopupTimerEvent = 2;
UINT CBCGPPopupMenuBar::m_uiPopupTimerDelay = (UINT) -1;
int CBCGPPopupMenuBar::m_nLastCommandIndex = -1;
/////////////////////////////////////////////////////////////////////////////
// CBCGPPopupMenuBar
IMPLEMENT_SERIAL(CBCGPPopupMenuBar, CBCGPToolBar, 1)
CBCGPPopupMenuBar::CBCGPPopupMenuBar() :
m_uiDefaultMenuCmdId (0),
m_pDelayedPopupMenuButton (NULL),
m_pDelayedClosePopupMenuButton (NULL),
m_bFirstClick (TRUE),
m_bFirstMove (TRUE),
m_iOffset (0),
m_xSeparatorOffsetLeft (0),
m_xSeparatorOffsetRight (0),
m_iMaxWidth (-1),
m_bAreAllCommandsShown (TRUE),
m_bInCommand (FALSE),
m_bTrackMode (FALSE)
{
m_bMenuMode = TRUE;
m_bIsClickOutsideItem = TRUE;
m_bEnableIDChecking = FALSE;
m_bDisableSideBarInXPMode = FALSE;
m_bPaletteMode = FALSE;
m_bPaletteRows = 1;
}
CBCGPPopupMenuBar::~CBCGPPopupMenuBar()
{
}
BEGIN_MESSAGE_MAP(CBCGPPopupMenuBar, CBCGPToolBar)
//{{AFX_MSG_MAP(CBCGPPopupMenuBar)
ON_WM_NCPAINT()
ON_WM_NCCALCSIZE()
ON_WM_DESTROY()
ON_WM_TIMER()
ON_WM_LBUTTONUP()
ON_WM_LBUTTONDOWN()
ON_WM_MOUSEMOVE()
ON_WM_CREATE()
ON_MESSAGE(WM_IDLEUPDATECMDUI, OnIdleUpdateCmdUI)
ON_COMMAND(ID_BCGBARRES_TOOLBAR_IMAGE_AND_TEXT, OnToolbarImageAndText)
ON_COMMAND(ID_BCGBARRES_TOOLBAR_TEXT, OnToolbarText)
ON_WM_LBUTTONDBLCLK()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CBCGPPopupMenuBar message handlers
BOOL CBCGPPopupMenuBar::OnSendCommand (const CBCGPToolbarButton* pButton)
{
ASSERT_VALID (pButton);
CBCGPCustomizeMenuButton* pCustomMenuButton =
DYNAMIC_DOWNCAST (CBCGPCustomizeMenuButton, pButton);
if ((pCustomMenuButton != NULL) &&
((pButton->m_nStyle & TBBS_DISABLED) != 0 ))
{
pCustomMenuButton->OnClickMenuItem ();
return TRUE;
}
if ((pButton->m_nStyle & TBBS_DISABLED) != 0 ||
pButton->m_nID < 0 || pButton->m_nID == (UINT)-1)
{
return FALSE;
}
CBCGPToolbarMenuButton* pMenuButton =
DYNAMIC_DOWNCAST (CBCGPToolbarMenuButton, pButton);
if (pMenuButton != NULL && pMenuButton->m_pPopupMenu != NULL)
{
return FALSE;
}
if (pMenuButton != NULL && pMenuButton->OnClickMenuItem ())
{
return TRUE;
}
if (pMenuButton != NULL && pMenuButton->IsKindOf (RUNTIME_CLASS (CBCGPShowAllButton)))
{
pMenuButton->OnClick (this, FALSE);
return TRUE;
}
InvokeMenuCommand (pButton->m_nID, pButton);
return TRUE;
}
//**************************************************************************************
void CBCGPPopupMenuBar::InvokeMenuCommand (UINT uiCmdId, const CBCGPToolbarButton* pMenuItem)
{
ASSERT (uiCmdId != (UINT) -1);
CBCGPPopupMenu* pParentMenu = DYNAMIC_DOWNCAST (CBCGPPopupMenu, GetParent ());
if (pParentMenu != NULL && pParentMenu->GetMessageWnd () != NULL)
{
pParentMenu->GetMessageWnd()->SendMessage
(WM_SETMESSAGESTRING, AFX_IDS_IDLEMESSAGE);
}
else
{
GetOwner()->SendMessage(WM_SETMESSAGESTRING, AFX_IDS_IDLEMESSAGE);
}
//--------------------
// Deactivate menubar:
//--------------------
if (pParentMenu != NULL)
{
CBCGPToolBar* pToolBar = NULL;
for (CBCGPPopupMenu* pMenu = pParentMenu; pMenu != NULL;
pMenu = pMenu->GetParentPopupMenu ())
{
CBCGPToolbarMenuButton* pParentButton = pMenu->GetParentButton ();
if (pParentButton == NULL)
{
break;
}
pToolBar =
DYNAMIC_DOWNCAST (CBCGPToolBar, pParentButton->GetParentWnd ());
}
if (pToolBar != NULL)
{
pToolBar->Deactivate ();
}
}
CFrameWnd* pParentFrame = BCGPGetParentFrame (this);
ASSERT_VALID (pParentFrame);
if (uiCmdId != 0)
{
SetInCommand ();
BCGPlaySystemSound (BCGSOUND_MENU_COMMAND);
if (!m_bTrackMode)
{
//----------------------------------
// Send command to the parent frame:
//----------------------------------
AddCommandUsage (uiCmdId);
if (!pParentMenu->PostCommand (uiCmdId) && // Alex Corazzin (2)
(g_pUserToolsManager == NULL ||
!g_pUserToolsManager->InvokeTool (uiCmdId)))
{
GetOwner()->PostMessage (WM_COMMAND, uiCmdId);
}
}
else
{
if (g_pContextMenuManager == NULL)
{
ASSERT (FALSE);
}
else
{
g_pContextMenuManager->m_nLastCommandID = uiCmdId;
}
}
}
m_nLastCommandIndex = pMenuItem == NULL ? -1 : ButtonToIndex (pMenuItem);
if (m_bPaletteMode)
{
CBCGPPopupMenu* pParentMenu = DYNAMIC_DOWNCAST (CBCGPPopupMenu, GetParent ());
if (pParentMenu != NULL)
{
ASSERT_VALID (pParentMenu);
CBCGPToolbarMenuButton* pParentButton = pParentMenu->GetParentButton ();
if (pParentButton != NULL && pParentButton->GetParentWnd () != NULL)
{
ASSERT_VALID (pParentButton);
pParentButton->SetImage (CImageHash::GetImageOfCommand (uiCmdId));
CRect rectImage;
pParentButton->GetImageRect (rectImage);
pParentButton->GetParentWnd ()->InvalidateRect (rectImage);
pParentButton->GetParentWnd ()->UpdateWindow ();
}
}
}
SetInCommand (FALSE);
pParentFrame->DestroyWindow ();
}
//***************************************************************
void CBCGPPopupMenuBar::AdjustLocations ()
{
if (GetSafeHwnd () == NULL ||
!::IsWindow (m_hWnd))
{
return;
}
if (m_bPaletteMode)
{
CBCGPToolBar::AdjustLocations ();
UpdateTooltips ();
return;
}
ASSERT_VALID(this);
if (m_xSeparatorOffsetLeft == 0)
{
//-----------------------------------------------------------
// To enable MS Office 2000 look, we'll draw the separators
// bellow the menu text only (in the previous versions
// separator has been drawn on the whole menu row). Ask
// menu button about text area offsets:
//-----------------------------------------------------------
CBCGPToolbarMenuButton::GetTextHorzOffsets (
m_xSeparatorOffsetLeft,
m_xSeparatorOffsetRight);
}
CRect rectClient; // Client area rectangle
GetClientRect (&rectClient);
CClientDC dc (this);
CFont* pOldFont = (CFont*) dc.SelectObject (&globalData.fontRegular);
ASSERT (pOldFont != NULL);
int y = rectClient.top + iVertMargin - m_iOffset * GetRowHeight ();
/// support for the menu with breaks:
int origy = y;
int x = rectClient.left;
int right = (m_arColumns.GetSize() == 0 ||
CBCGPToolBar::IsCustomizeMode ()) ?
rectClient.Width() :
m_arColumns [0];
int nColumn = 0;
/////////
CSize sizeMenuButton = GetMenuImageSize ();
sizeMenuButton += CSize (2 * iHorzMargin, 2 * iVertMargin);
sizeMenuButton.cy = max (sizeMenuButton.cy,
globalData.GetTextHeight ());
for (POSITION pos = m_Buttons.GetHeadPosition (); pos != NULL;)
{
CBCGPToolbarButton* pButton = (CBCGPToolbarButton*) m_Buttons.GetNext (pos);
ASSERT (pButton != NULL);
/// support for the menu with breaks:
if ((pButton->m_nStyle & TBBS_BREAK) && (y != origy) &&
!CBCGPToolBar::IsCustomizeMode ())
{
y = origy;
nColumn ++;
x = right + iHorzMargin;
right = m_arColumns [nColumn];
}
////////////////////
CRect rectButton;
rectButton.top = y;
if (pButton->m_nStyle & TBBS_SEPARATOR)
{
rectButton.left = x + m_xSeparatorOffsetLeft;
rectButton.right = right + rectClient.left - m_xSeparatorOffsetRight;
rectButton.bottom = rectButton.top + iSeparatorHeight;
}
else
{
CSize sizeButton = pButton->OnCalculateSize (&dc,
sizeMenuButton, TRUE);
rectButton.left = x;
rectButton.right = right + rectClient.left;
rectButton.bottom = rectButton.top + sizeButton.cy;
}
pButton->SetRect (rectButton);
y += rectButton.Height ();
}
dc.SelectObject (pOldFont);
//--------------------------------------------------
// Something may changed, rebuild acceleration keys:
//--------------------------------------------------
RebuildAccelerationKeys ();
CPoint ptCursor;
::GetCursorPos (&ptCursor);
ScreenToClient (&ptCursor);
if (HitTest (ptCursor) >= 0)
{
m_bIsClickOutsideItem = FALSE;
}
UpdateTooltips ();
}
//***************************************************************************************
void CBCGPPopupMenuBar::DrawSeparator (CDC* pDC, const CRect& rect, BOOL /*bHorz*/)
{
CBCGPVisualManager::GetInstance ()->OnDrawSeparator (pDC, this, rect, FALSE);
}
//***************************************************************************************
CSize CBCGPPopupMenuBar::CalcSize (BOOL /*bVertDock*/)
{
if (m_bPaletteMode)
{
return CBCGPToolBar::CalcSize (FALSE);
}
CSize size (0, 0);
CClientDC dc (this);
CFont* pOldFont = (CFont*) dc.SelectObject (&globalData.fontRegular);
ASSERT (pOldFont != NULL);
if (m_Buttons.IsEmpty ())
{
size = CSize (iEmptyMenuWidth, iEmptyMenuHeight);
}
else
{
//support for the menu with breaks:
CSize column (0, 0);
m_arColumns.RemoveAll ();
//////////////////////////
CSize sizeMenuButton = GetMenuImageSize ();
sizeMenuButton += CSize (2 * iHorzMargin, 2 * iVertMargin);
sizeMenuButton.cy = max (sizeMenuButton.cy,
globalData.GetTextHeight ());
for (POSITION pos = m_Buttons.GetHeadPosition (); pos != NULL;)
{
CBCGPToolbarButton* pButton = (CBCGPToolbarButton*) m_Buttons.GetNext (pos);
ASSERT (pButton != NULL);
BOOL bRestoreFont = FALSE;
if (m_uiDefaultMenuCmdId != 0 &&
pButton->m_nID == m_uiDefaultMenuCmdId)
{
dc.SelectObject (&globalData.fontBold);
bRestoreFont = TRUE;
}
CSize sizeButton = pButton->OnCalculateSize (&dc,
sizeMenuButton, TRUE);
// support for the menu with breaks:
if ((pButton->m_nStyle & TBBS_BREAK) &&
!CBCGPToolBar::IsCustomizeMode ())
{
if ((column.cx != 0) && (column.cy != 0))
{
size.cy = max (column.cy, size.cy);
size.cx += column.cx + iHorzMargin;
m_arColumns.Add (size.cx);
}
column.cx = column.cy = 0;
}
///////////////////////////////
int iHeight = sizeButton.cy;
if (pButton->m_nStyle & TBBS_SEPARATOR)
{
iHeight = iSeparatorHeight;
}
else
{
if (pButton->IsDrawText () &&
pButton->m_strText.Find (_T('\t')) > 0)
{
sizeButton.cx += iMinTabSpace;
}
pButton->m_bWholeText =
(m_iMaxWidth <= 0 ||
sizeButton.cx <= m_iMaxWidth - 2 * iHorzMargin);
column.cx = max (sizeButton.cx, column.cx);
}
column.cy += iHeight;
if (bRestoreFont)
{
dc.SelectObject (&globalData.fontRegular);
}
}
size.cy = max (column.cy, size.cy);
size.cx += column.cx;
}
size.cy += 2 * iVertMargin;
size.cx += 2 * iHorzMargin;
if (m_iMaxWidth > 0 && size.cx > m_iMaxWidth)
{
size.cx = m_iMaxWidth;
}
m_arColumns.Add (size.cx);
dc.SelectObject (pOldFont);
return size;
}
//***************************************************************************************
void CBCGPPopupMenuBar::OnNcPaint()
{
//--------------------------------------
// Disable gripper and borders painting!
//--------------------------------------
}
//***************************************************************************************
void CBCGPPopupMenuBar::OnNcCalcSize(BOOL /*bCalcValidRects*/, NCCALCSIZE_PARAMS FAR* /*lpncsp*/)
{
//-----------------------------------------------
// Don't leave space for the gripper and borders!
//-----------------------------------------------
}
//****************************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -