📄 bcgptoolbarmenubutton.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.
//*******************************************************************************
// BCGToolbarMenuButton.cpp: implementation of the CBCGPToolbarMenuButton class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "menuhash.h"
#include "BCGCBPro.h"
#include "BCGPToolbarMenuButton.h"
#include "BCGPMenuBar.h"
#include "BCGPPopupMenuBar.h"
#include "BCGPCommandManager.h"
#include "BCGGlobals.h"
#include "BCGPKeyboardManager.h"
#include "BCGPFrameWnd.h"
#include "BCGPMDIFrameWnd.h"
#include "BCGPOleIPFrameWnd.h"
#include "BCGPOleDocIPFrameWnd.h"
#include "MenuImages.h"
#include "BCGPUserToolsManager.h"
#include "BCGPTearOffManager.h"
#include "BCGPUserTool.h"
#include "BCGPRegistry.h"
#include "BCGPWorkspace.h"
#include "BCGPVisualManager.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
static const int SEPARATOR_SIZE = 2;
IMPLEMENT_SERIAL(CBCGPToolbarMenuButton, CBCGPToolbarButton, VERSIONABLE_SCHEMA | 1)
extern CBCGPWorkspace* g_pWorkspace;
BOOL CBCGPToolbarMenuButton::m_bAlwaysCallOwnerDraw = FALSE;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CBCGPToolbarMenuButton::CBCGPToolbarMenuButton()
{
Initialize ();
}
//*****************************************************************************************
CBCGPToolbarMenuButton::CBCGPToolbarMenuButton (UINT uiID, HMENU hMenu,
int iImage, LPCTSTR lpszText, BOOL bUserButton)
{
Initialize ();
m_nID = uiID;
m_bUserButton = bUserButton;
SetImage (iImage);
m_strText = (lpszText == NULL) ? _T("") : lpszText;
CreateFromMenu (hMenu);
}
//*****************************************************************************************
void CBCGPToolbarMenuButton::Initialize ()
{
m_bDrawDownArrow = FALSE;
m_bMenuMode = FALSE;
m_pPopupMenu = NULL;
m_pWndParent = NULL;
m_bDefault = FALSE;
m_bClickedOnMenu = FALSE;
m_bHorz = TRUE;
m_bMenuOnly = FALSE; //JRG
m_bToBeClosed = FALSE;
m_uiTearOffBarID = 0;
m_bIsRadio = FALSE;
m_pWndMessage = NULL;
m_bMenuPaletteMode = FALSE;
m_nPaletteRows = 1;
m_bQuickCustomMode = FALSE;
}
//*****************************************************************************************
CBCGPToolbarMenuButton::CBCGPToolbarMenuButton (const CBCGPToolbarMenuButton& src)
{
m_nID = src.m_nID;
m_nStyle = src.m_nStyle;
m_bUserButton = src.m_bUserButton;
SetImage (src.GetImage ());
m_strText = src.m_strText;
m_bDragFromCollection = FALSE;
m_bText = src.m_bText;
m_bImage = src.m_bImage;
m_bDrawDownArrow = src.m_bDrawDownArrow;
m_bMenuMode = src.m_bMenuMode;
m_bDefault = src.m_bDefault;
m_bMenuOnly = src.m_bMenuOnly;
m_bIsRadio = src.m_bIsRadio;
SetTearOff (src.m_uiTearOffBarID);
HMENU hmenu = src.CreateMenu ();
ASSERT (hmenu != NULL);
CreateFromMenu (hmenu);
::DestroyMenu (hmenu);
m_rect.SetRectEmpty ();
m_pPopupMenu = NULL;
m_pWndParent = NULL;
m_bClickedOnMenu = FALSE;
m_bHorz = TRUE;
m_bMenuPaletteMode = src.m_bMenuPaletteMode;
m_nPaletteRows = src.m_nPaletteRows;
m_bQuickCustomMode = src.m_bQuickCustomMode;
}
//*****************************************************************************************
CBCGPToolbarMenuButton::~CBCGPToolbarMenuButton()
{
if (m_pPopupMenu != NULL)
{
m_pPopupMenu->m_pParentBtn = NULL;
}
while (!m_listCommands.IsEmpty ())
{
delete m_listCommands.RemoveHead ();
}
if (m_uiTearOffBarID != 0 && g_pTearOffMenuManager != NULL)
{
g_pTearOffMenuManager->SetInUse (m_uiTearOffBarID, FALSE);
}
}
//////////////////////////////////////////////////////////////////////
// Overrides:
void CBCGPToolbarMenuButton::CopyFrom (const CBCGPToolbarButton& s)
{
CBCGPToolbarButton::CopyFrom (s);
const CBCGPToolbarMenuButton& src = (const CBCGPToolbarMenuButton&) s;
m_bDefault = src.m_bDefault;
m_bMenuOnly = src.m_bMenuOnly;
m_bIsRadio = src.m_bIsRadio;
m_pWndMessage = src.m_pWndMessage;
m_bMenuPaletteMode = src.m_bMenuPaletteMode;
m_nPaletteRows = src.m_nPaletteRows;
m_bQuickCustomMode = src.m_bQuickCustomMode;
SetTearOff (src.m_uiTearOffBarID);
while (!m_listCommands.IsEmpty ())
{
delete m_listCommands.RemoveHead ();
}
for (POSITION pos = src.m_listCommands.GetHeadPosition (); pos != NULL;)
{
CBCGPToolbarMenuButton* pItem = (CBCGPToolbarMenuButton*) src.m_listCommands.GetNext (pos);
ASSERT (pItem != NULL);
ASSERT_KINDOF (CBCGPToolbarMenuButton, pItem);
CRuntimeClass* pSrcClass = pItem->GetRuntimeClass ();
ASSERT (pSrcClass != NULL);
CBCGPToolbarMenuButton* pNewItem = (CBCGPToolbarMenuButton*) pSrcClass->CreateObject ();
ASSERT (pNewItem != NULL);
ASSERT_KINDOF (CBCGPToolbarMenuButton, pNewItem);
pNewItem->CopyFrom (*pItem);
m_listCommands.AddTail (pNewItem);
}
}
//*****************************************************************************************
void CBCGPToolbarMenuButton::Serialize (CArchive& ar)
{
CBCGPToolbarButton::Serialize (ar);
if (ar.IsLoading ())
{
while (!m_listCommands.IsEmpty ())
{
delete m_listCommands.RemoveHead ();
}
UINT uiTearOffBarID;
ar >> uiTearOffBarID;
SetTearOff (uiTearOffBarID);
if (g_menuHash.IsActive () ||
(g_pWorkspace != NULL &&
(g_pWorkspace->GetDataVersionMajor () == -1 ||
(g_pWorkspace->GetDataVersionMajor () >= 6 &&
g_pWorkspace->GetDataVersionMinor () >= 52))))
{
ar >> m_bMenuPaletteMode;
ar >> m_nPaletteRows;
}
}
else
{
ar << m_uiTearOffBarID;
if (g_menuHash.IsActive () ||
(g_pWorkspace != NULL &&
(g_pWorkspace->GetDataVersionMajor () == -1 ||
(g_pWorkspace->GetDataVersionMajor () >= 6 &&
g_pWorkspace->GetDataVersionMinor () >= 52))))
{
ar << m_bMenuPaletteMode;
ar << m_nPaletteRows;
}
}
m_listCommands.Serialize (ar);
}
//*****************************************************************************************
void CBCGPToolbarMenuButton::OnDraw (CDC* pDC, const CRect& rect, CBCGPToolBarImages* pImages,
BOOL bHorz, BOOL bCustomizeMode, BOOL bHighlight,
BOOL bDrawBorder, BOOL bGrayDisabledButtons)
{
if (m_bMenuMode)
{
DrawMenuItem (pDC, rect, pImages, bCustomizeMode, bHighlight, bGrayDisabledButtons);
return;
}
bool bIsChecked = false;
if (m_bMenuPaletteMode)
{
m_nStyle &= ~TBBS_CHECKED;
}
//----------------------
// Fill button interior:
//----------------------
FillInterior (pDC, rect, bHighlight || IsDroppedDown ());
CSize sizeImage = CMenuImages::Size ();
if (CBCGPToolBar::IsLargeIcons ())
{
sizeImage.cx *= 2;
sizeImage.cy *= 2;
}
CRect rectInternal = rect;
CSize sizeExtra = m_bExtraSize ?
CBCGPVisualManager::GetInstance ()->GetButtonExtraBorder () : CSize (0, 0);
if (sizeExtra != CSize (0, 0))
{
rectInternal.DeflateRect (sizeExtra.cx / 2 + 1, sizeExtra.cy / 2 + 1);
}
CRect rectParent = rect;
CRect rectArrow = rectInternal;
const int nMargin = CBCGPVisualManager::GetInstance ()->GetMenuImageMargin ();
const int xMargin = bHorz ? nMargin : 0;
const int yMargin = bHorz ? 0 : nMargin;
rectParent.DeflateRect (xMargin, yMargin);
if (m_bDrawDownArrow)
{
if (bHorz)
{
rectParent.right -= sizeImage.cx + SEPARATOR_SIZE;
rectArrow.left = rectParent.right - 1;
rectArrow.OffsetRect (-sizeExtra.cx / 2, -sizeExtra.cy / 2);
}
else
{
rectParent.bottom -= sizeImage.cy + SEPARATOR_SIZE;
rectArrow.top = rectParent.bottom - 1;
}
}
UINT uiStyle = m_nStyle;
if (CBCGPVisualManager::GetInstance ()->IsMenuFlatLook ())
{
m_nStyle &= ~(TBBS_PRESSED | TBBS_CHECKED);
}
else
{
if (m_bClickedOnMenu && m_nID != 0 && m_nID != (UINT) -1 && !m_bMenuOnly)
{
m_nStyle &= ~TBBS_PRESSED;
}
else if (m_pPopupMenu != NULL)
{
m_nStyle |= TBBS_PRESSED;
}
}
BOOL bDisableFill = m_bDisableFill;
m_bDisableFill = TRUE;
CBCGPToolbarButton::OnDraw (pDC, rectParent, pImages, bHorz,
bCustomizeMode, bHighlight, bDrawBorder, bGrayDisabledButtons);
m_bDisableFill = bDisableFill;
if (m_bDrawDownArrow)
{
if ((m_nStyle & (TBBS_PRESSED | TBBS_CHECKED)) &&
!CBCGPVisualManager::GetInstance ()->IsMenuFlatLook ())
{
rectArrow.OffsetRect (1, 1);
}
if ((bHighlight || (m_nStyle & TBBS_PRESSED) ||
m_pPopupMenu != NULL) &&
m_nID != 0 && m_nID != (UINT) -1 && !m_bMenuOnly) //JRG
{
//----------------
// Draw separator:
//----------------
CRect rectSeparator = rectArrow;
if (bHorz)
{
rectSeparator.right = rectSeparator.left + SEPARATOR_SIZE;
}
else
{
rectSeparator.bottom = rectSeparator.top + SEPARATOR_SIZE;
}
CBCGPVisualManager::BCGBUTTON_STATE state = CBCGPVisualManager::ButtonsIsRegular;
if (bHighlight || (m_nStyle & (TBBS_PRESSED | TBBS_CHECKED)))
{
//-----------------------
// Pressed in or checked:
//-----------------------
state = CBCGPVisualManager::ButtonsIsPressed;
}
CBCGPVisualManager::GetInstance ()->OnDrawButtonSeparator (pDC,
this, rectSeparator, state, bHorz);
}
BOOL bDisabled = (bCustomizeMode && !IsEditable ()) ||
(!bCustomizeMode && (m_nStyle & TBBS_DISABLED));
int iImage;
if (bHorz && !m_bMenuOnly)
{
iImage = CMenuImages::IdArowDown;
}
else
{
iImage = CMenuImages::IdArowRight;
}
if (m_pPopupMenu != NULL &&
(m_nStyle & (TBBS_PRESSED | TBBS_CHECKED)) == 0 &&
!CBCGPVisualManager::GetInstance ()->IsMenuFlatLook ())
{
rectArrow.OffsetRect (1, 1);
}
CPoint pointImage (
rectArrow.left + (rectArrow.Width () - sizeImage.cx) / 2,
rectArrow.top + (rectArrow.Height () - sizeImage.cy) / 2);
CMenuImages::Draw (pDC, (CMenuImages::IMAGES_IDS) iImage, pointImage,
bDisabled ? CMenuImages::ImageGray : CMenuImages::ImageBlack,
sizeImage);
}
m_nStyle = uiStyle;
if (!bCustomizeMode)
{
if ((m_nStyle & (TBBS_PRESSED | TBBS_CHECKED)) ||
m_pPopupMenu != NULL)
{
//-----------------------
// Pressed in or checked:
//-----------------------
if (!CBCGPVisualManager::GetInstance ()->IsMenuFlatLook () &&
m_bClickedOnMenu && m_nID != 0 && m_nID != (UINT) -1 && !m_bMenuOnly) //JRG
{
CBCGPVisualManager::GetInstance ()->OnDrawButtonBorder (pDC,
this, rectParent, CBCGPVisualManager::ButtonsIsHighlighted);
rectArrow.right --;
rectArrow.bottom --;
CBCGPVisualManager::GetInstance ()->OnDrawButtonBorder (pDC,
this, rectArrow, CBCGPVisualManager::ButtonsIsPressed);
}
else
{
CBCGPVisualManager::GetInstance ()->OnDrawButtonBorder (pDC,
this, rect, CBCGPVisualManager::ButtonsIsPressed);
}
}
else if (bHighlight && !(m_nStyle & TBBS_DISABLED) &&
!(m_nStyle & (TBBS_CHECKED | TBBS_INDETERMINATE)))
{
CBCGPVisualManager::GetInstance ()->OnDrawButtonBorder (pDC,
this, rect, CBCGPVisualManager::ButtonsIsHighlighted);
}
}
if (bIsChecked)
{
m_nStyle |= TBBS_CHECKED;
}
}
//*****************************************************************************************
SIZE CBCGPToolbarMenuButton::OnCalculateSize (CDC* pDC, const CSize& sizeDefault, BOOL bHorz)
{
m_bHorz = bHorz;
if(!IsVisible())
{
return CSize(0,0);
}
int iArrowSize = 0;
if (m_bDrawDownArrow || m_bMenuMode)
{
int nScale = CBCGPToolBar::IsLargeIcons () ? 2 : 1;
iArrowSize = (bHorz) ?
nScale * CMenuImages::Size ().cx + SEPARATOR_SIZE - TEXT_MARGIN :
nScale * CMenuImages::Size ().cy + SEPARATOR_SIZE - TEXT_MARGIN;
}
//--------------------
// Change accelerator:
//--------------------
if (g_pKeyboardManager != NULL &&
m_bMenuMode &&
(m_nID < 0xF000 || m_nID >= 0xF1F0)) // Not system.
{
//-----------------------------------
// Remove standard aceleration label:
//-----------------------------------
int iTabOffset = m_strText.Find (_T('\t'));
if (iTabOffset >= 0)
{
m_strText = m_strText.Left (iTabOffset);
}
//---------------------------------
// Add an actual accelartion label:
//---------------------------------
CString strAccel;
CFrameWnd* pParent = m_pWndParent == NULL ?
DYNAMIC_DOWNCAST (CFrameWnd, AfxGetMainWnd ()) :
BCGCBProGetTopLevelFrame (m_pWndParent);
if (pParent != NULL &&
(CBCGPKeyboardManager::FindDefaultAccelerator (
m_nID, strAccel, pParent, TRUE) ||
CBCGPKeyboardManager::FindDefaultAccelerator (
m_nID, strAccel, pParent->GetActiveFrame (), FALSE)))
{
m_strText += _T('\t');
m_strText += strAccel;
}
}
CSize size = CBCGPToolbarButton::OnCalculateSize (pDC, sizeDefault, bHorz);
if (bHorz)
{
size.cx += iArrowSize;
}
else
{
size.cy += iArrowSize;
}
if (m_bMenuMode)
{
size.cx += sizeDefault.cx + 2 * TEXT_MARGIN;
}
CBCGPPopupMenuBar* pParentMenu =
DYNAMIC_DOWNCAST (CBCGPPopupMenuBar, m_pWndParent);
if (pParentMenu != NULL)
{
size.cy = pParentMenu->GetRowHeight ();
}
if (!m_bMenuMode)
{
const int nMargin = CBCGPVisualManager::GetInstance ()->GetMenuImageMargin ();
if (bHorz)
{
size.cx += nMargin * 2 + TEXT_MARGIN;;
}
else
{
size.cy += nMargin * 2 + TEXT_MARGIN;;
}
}
return size;
}
//*****************************************************************************************
BOOL CBCGPToolbarMenuButton::OnClick (CWnd* pWnd, BOOL bDelay)
{
ASSERT_VALID (pWnd);
m_bClickedOnMenu = FALSE;
if (m_bDrawDownArrow && !bDelay && !m_bMenuMode)
{
if (m_nID == 0 || m_nID == (UINT) -1)
{
m_bClickedOnMenu = TRUE;
}
else
{
CPoint ptMouse;
::GetCursorPos (&ptMouse);
pWnd->ScreenToClient (&ptMouse);
int nScale = CBCGPToolBar::IsLargeIcons () ? 2 : 1;
CRect rectArrow = m_rect;
if (m_bExtraSize)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -