📄 bcgppopupmenu.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.
//*******************************************************************************
// BCGPPopupMenu.cpp : implementation file
//
#include "stdafx.h"
#pragma warning (disable : 4706)
#ifdef _AFXDLL
#define COMPILE_MULTIMON_STUBS
#endif // _AFXDLL
#include "multimon.h"
#pragma warning (default : 4706)
#include "BCGPPopupMenu.h"
#include "BCGPMenuBar.h"
#include "BCGGlobals.h"
#include "BCGPToolbarMenuButton.h"
#include "BCGPMDIFrameWnd.h"
#include "BCGPFrameWnd.h"
#include "BCGPOleIPFrameWnd.h"
#include "BCGPOleDocIPFrameWnd.h"
#include "BCGPMenuBar.h"
#include "BCGPMenuPage.h"
#include "MenuHash.h"
#include "MenuImages.h"
#include "BCGPShowAllButton.h"
#include "BCGPUserToolsManager.h"
#include "BCGPTearOffManager.h"
#include "BCGPUserTool.h"
#include "BCGPSound.h"
#include "bcgprores.h"
#include "BCGPLocalResource.h"
#include "BCGPDialog.h"
#include "BCGPPropertyPage.h"
#include "BCGPVisualManager.h"
#include "BCGPDrawManager.h"
#include "BCGPCommandManager.h"
#include "BCGPControlBar.h"
#include "BCGPMiniFrameWnd.h"
#include "BCGPCustomizeMenuButton.h"
#include "BCGPCaptionMenuButton.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CBCGPPopupMenu
static const int iFadeStep = 10;
static const int iAnimTimerId = 1;
static const int iScrollTimerId = 2;
static const int iScrollTimerDuration = 80;
static const int iMenuBarId = 1;
static const int iTearOffBarHeight = 10;
CBCGPPopupMenu::ANIMATION_TYPE CBCGPPopupMenu::m_AnimationType = NO_ANIMATION;
UINT CBCGPPopupMenu::m_AnimationSpeed = 30;
CBCGPPopupMenu* CBCGPPopupMenu::m_pActivePopupMenu = NULL;
BOOL CBCGPPopupMenu::m_bForceShadow = FALSE;
BOOL CBCGPPopupMenu::m_bForceMenuFocus = TRUE;
BOOL CBCGPPopupMenu::m_bMenuSound = TRUE;
static clock_t nLastAnimTime = 0;
IMPLEMENT_SERIAL(CBCGPPopupMenu, CMiniFrameWnd, VERSIONABLE_SCHEMA | 1)
CBCGPPopupMenu::CBCGPPopupMenu() :
m_pMenuCustomizationPage (NULL)
{
Initialize ();
}
//****************************************************************************************
CBCGPPopupMenu::CBCGPPopupMenu(CBCGPMenuPage* pCustPage, LPCTSTR lpszTitle) :
m_pMenuCustomizationPage (pCustPage),
m_strCaption (lpszTitle)
{
Initialize ();
}
//****************************************************************************************
void CBCGPPopupMenu::Initialize ()
{
m_hMenu = NULL;
m_ptLocation = CPoint (0, 0);
m_ptLocationInitial = CPoint (0, 0);
m_pParentBtn = NULL;
m_bAutoDestroyParent = TRUE;
m_bAutoDestroy = TRUE;
m_FinalSize = CSize (0, 0);
m_AnimSize = CSize (0, 0);
m_nMenuBarHeight = 0;
m_bAnimationIsDone = (m_AnimationType == NO_ANIMATION);
m_bScrollable = FALSE;
m_bTobeDstroyed = FALSE;
m_bShown = FALSE;
m_iMaxWidth = -1;
m_iLogoWidth = 0;
m_nLogoLocation = MENU_LOGO_LEFT;
m_rectScrollUp.SetRectEmpty ();
m_rectScrollDn.SetRectEmpty ();
m_iScrollBtnHeight = CMenuImages::Size ().cy + 2 *
CBCGPVisualManager::GetInstance ()->GetPopupMenuBorderSize ();
m_iScrollMode = 0;
m_bIsAnimRight = TRUE;
m_bIsAnimDown = TRUE;
m_iShadowSize = CBCGPMenuBar::IsMenuShadows () &&
!CBCGPToolBar::IsCustomizeMode () &&
globalData.m_nBitsPerPixel > 8 ? // Don't draw shadows in 256 colors or less
CBCGPVisualManager::GetInstance ()->GetMenuShadowDepth () : 0;
m_iFadePercent = 0;
if (m_AnimationType == FADE && globalData.m_nBitsPerPixel <= 8)
{
m_AnimationType = NO_ANIMATION;
m_bAnimationIsDone = TRUE;
}
m_bTearOffTracking = FALSE;
m_bIsTearOffCaptionActive = FALSE;
m_rectTearOffCaption.SetRectEmpty ();
m_DropDirection = DROP_DIRECTION_NONE;
m_pMessageWnd = NULL;
m_bTrackMode = FALSE;
m_bRightAlign = FALSE;
m_bQuickCusomize = FALSE;
m_QuickType = QUICK_CUSTOMIZE_NONE;
}
//****************************************************************************************
CBCGPPopupMenu::~CBCGPPopupMenu()
{
if (m_bAutoDestroy && m_hMenu != NULL)
{
::DestroyMenu (m_hMenu);
}
}
BEGIN_MESSAGE_MAP(CBCGPPopupMenu, CMiniFrameWnd)
//{{AFX_MSG_MAP(CBCGPPopupMenu)
ON_WM_CREATE()
ON_WM_SIZE()
ON_WM_PAINT()
ON_WM_MOUSEACTIVATE()
ON_WM_DESTROY()
ON_WM_KEYDOWN()
ON_WM_ERASEBKGND()
ON_WM_TIMER()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_SHOWWINDOW()
ON_WM_SETCURSOR()
//}}AFX_MSG_MAP
ON_WM_ACTIVATEAPP()
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CBCGPPopupMenu message handlers
BOOL CBCGPPopupMenu::Create (CWnd* pWndParent, int x, int y, HMENU hMenu, BOOL bLocked, BOOL bOwnMessage)
{
BCGPlaySystemSound (BCGSOUND_MENU_POPUP);
ASSERT (pWndParent != NULL);
CString strClassName = ::AfxRegisterWndClass (
CS_SAVEBITS,
::LoadCursor(NULL, IDC_ARROW),
(HBRUSH)(COLOR_BTNFACE + 1), NULL);
m_hMenu = hMenu;
if (x == -1 && y == -1) // Undefined position
{
if (pWndParent != NULL)
{
CRect rectParent;
pWndParent->GetClientRect (&rectParent);
pWndParent->ClientToScreen (&rectParent);
m_ptLocation = CPoint (rectParent.left + 5, rectParent.top + 5);
}
else
{
m_ptLocation = CPoint (0, 0);
}
}
else
{
m_ptLocation = CPoint (x, y);
}
m_ptLocationInitial = m_ptLocation;
DWORD dwStyle = WS_POPUP;
if (m_pMenuCustomizationPage != NULL)
{
dwStyle |= (WS_CAPTION | WS_SYSMENU);
}
BOOL bIsAnimate = (m_AnimationType != NO_ANIMATION) &&
!CBCGPToolBar::IsCustomizeMode ();
CBCGPPopupMenu* pParentMenu = GetParentPopupMenu ();
if (pParentMenu != NULL)
{
m_bTrackMode = pParentMenu->m_bTrackMode;
}
if (bOwnMessage)
{
m_pMessageWnd = pWndParent;
}
else if (pParentMenu != NULL)
{
m_pMessageWnd = pParentMenu->GetMessageWnd ();
}
// ---------------------------
CRect rect (x, y, x, y);
BOOL bCreated = CMiniFrameWnd::CreateEx (
0,
strClassName, m_strCaption,
dwStyle, rect,
pWndParent->GetOwner () == NULL ?
pWndParent : pWndParent->GetOwner ());
if (!bCreated)
{
return FALSE;
}
if (m_bRightAlign)
{
m_ptLocation.x -= m_FinalSize.cx - 1;
m_ptLocationInitial = m_ptLocation;
RecalcLayout ();
}
CBCGPPopupMenuBar* pMenuBar = GetMenuBar ();
ASSERT_VALID (pMenuBar);
pMenuBar->m_bLocked = bLocked;
if (bIsAnimate)
{
//--------------------------
// Adjust initial menu size:
//--------------------------
m_AnimSize = m_FinalSize + CSize (m_iShadowSize, m_iShadowSize);
switch (m_AnimationType)
{
case UNFOLD:
m_AnimSize.cx = pMenuBar->GetColumnWidth ();
case SLIDE:
m_AnimSize.cy = pMenuBar->GetRowHeight ();
break;
}
if (pMenuBar->IsWindowVisible ())
{
pMenuBar->ShowWindow (SW_HIDE);
}
SetTimer (iAnimTimerId, m_AnimationSpeed, NULL);
nLastAnimTime = clock ();
}
//--------------------------------------
// Update windows covered by the shadow:
//--------------------------------------
UpdateBottomWindows ();
if (m_iShadowSize == 0 && m_AnimationType == FADE)
{
m_AnimSize = m_FinalSize;
}
SetWindowPos (&wndTop, -1, -1, -1, -1,
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
if (CBCGPToolBar::IsCustomizeMode ())
{
pMenuBar->Invalidate ();
pMenuBar->UpdateWindow ();
}
return TRUE;
}
//****************************************************************************************
//-----------------------------------------------------
// My "classic " trick - how I can access to protected
// member m_pRecentFileList?
//-----------------------------------------------------
class CBCGPApp : public CWinApp
{
friend class CBCGPPopupMenu;
};
int CBCGPPopupMenu::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CMiniFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
DWORD toolbarStyle = dwDefaultToolbarStyle;
if (m_AnimationType != NO_ANIMATION && !CBCGPToolBar::IsCustomizeMode ())
{
toolbarStyle &= ~WS_VISIBLE;
}
CBCGPPopupMenuBar* pMenuBar = GetMenuBar ();
ASSERT_VALID (pMenuBar);
pMenuBar->m_bTrackMode = m_bTrackMode;
if (m_pParentBtn != NULL && m_pParentBtn->IsMenuPaletteMode ())
{
pMenuBar->m_bPaletteMode = TRUE;
pMenuBar->m_bDisableSideBarInXPMode = TRUE;
pMenuBar->m_bPaletteRows = m_pParentBtn->GetPaletteRows ();
}
if (!pMenuBar->Create (this, toolbarStyle | CBRS_TOOLTIPS | CBRS_FLYBY, iMenuBarId))
{
TRACE(_T("Can't create popup menu bar\n"));
return FALSE;
}
CBCGPPopupMenu* pParentPopupMenu = GetParentPopupMenu ();
if (pParentPopupMenu != NULL)
{
m_iMaxWidth = pParentPopupMenu->m_iMaxWidth;
}
pMenuBar->m_iMaxWidth = m_iMaxWidth;
pMenuBar->SetOwner (GetParent ());
return InitMenuBar()? 0 : 1;
}
//****************************************************************************************
void CBCGPPopupMenu::OnSize(UINT nType, int cx, int cy)
{
CMiniFrameWnd::OnSize(nType, cx, cy);
CBCGPPopupMenuBar* pMenuBar = GetMenuBar ();
ASSERT_VALID (pMenuBar);
if (pMenuBar->GetSafeHwnd () != NULL)
{
AdjustScroll (TRUE /*bForceMenuBarResize*/);
}
const int nBorderSize = CBCGPVisualManager::GetInstance ()->GetPopupMenuBorderSize ();
if (m_iLogoWidth > 0)
{
CRect rectLogo;
GetClientRect (rectLogo);
switch (m_nLogoLocation)
{
case MENU_LOGO_LEFT:
rectLogo.right = rectLogo.left + nBorderSize + m_iLogoWidth;
break;
case MENU_LOGO_RIGHT:
rectLogo.left = rectLogo.right - nBorderSize - m_iLogoWidth;
break;
case MENU_LOGO_TOP:
rectLogo.bottom = rectLogo.top + nBorderSize + m_iLogoWidth;
break;
case MENU_LOGO_BOTTOM:
rectLogo.top = rectLogo.bottom - nBorderSize - m_iLogoWidth;
break;
}
InvalidateRect (rectLogo);
UpdateWindow ();
}
}
//****************************************************************************************
void CBCGPPopupMenu::OnPaint()
{
CPaintDC dc(this); // device context for painting
if (!m_bAnimationIsDone && !CBCGPToolBar::IsCustomizeMode ())
{
DrawFade (&dc);
}
else
{
DoPaint (&dc);
}
}
//****************************************************************************************
int CBCGPPopupMenu::OnMouseActivate(CWnd* /*pDesktopWnd*/, UINT /*nHitTest*/, UINT /*message*/)
{
return MA_NOACTIVATE;
}
//****************************************************************************************
void CBCGPPopupMenu::RecalcLayout (BOOL /*bNotify*/)
{
#ifdef _DEBUG
if (m_pParentBtn != NULL)
{
ASSERT_VALID (m_pParentBtn);
ASSERT (m_pParentBtn->m_pPopupMenu == this);
}
#endif // _DEBUG
CBCGPPopupMenuBar* pMenuBar = GetMenuBar ();
ASSERT_VALID (pMenuBar);
if (!::IsWindow (m_hWnd) ||
pMenuBar == NULL ||
!::IsWindow (pMenuBar->m_hWnd))
{
return;
}
//-------------------------
// Set tear-off attributes:
//-------------------------
BOOL bIsTearOff = (m_pParentBtn != NULL && m_pParentBtn->IsTearOffMenu () &&
!CBCGPToolBar::IsCustomizeMode ());
CRect rectScreen;
MONITORINFO mi;
mi.cbSize = sizeof (MONITORINFO);
if (GetMonitorInfo (MonitorFromPoint (m_ptLocation, MONITOR_DEFAULTTONEAREST),
&mi))
{
rectScreen = mi.rcWork;
}
else
{
::SystemParametersInfo (SPI_GETWORKAREA, 0, &rectScreen, 0);
}
//---------------------------------------
// Normalize location in the screen area:
//---------------------------------------
m_ptLocation.x = max (rectScreen.left, min (m_ptLocation.x, rectScreen.right));
m_ptLocation.y = max (rectScreen.top, min (m_ptLocation.y, rectScreen.bottom));
CSize size = pMenuBar->CalcSize (TRUE);
const int nBorderSize = CBCGPVisualManager::GetInstance ()->GetPopupMenuBorderSize ();
size.cx += nBorderSize * 2;
size.cy += nBorderSize * 2;
switch (m_nLogoLocation)
{
case MENU_LOGO_LEFT:
case MENU_LOGO_RIGHT:
size.cx += m_iLogoWidth;
break;
case MENU_LOGO_TOP:
case MENU_LOGO_BOTTOM:
size.cy += m_iLogoWidth;
break;
}
if (m_pMenuCustomizationPage != NULL)
{
size.cy += ::GetSystemMetrics (SM_CYSMCAPTION);
size.cy += 2 * ::GetSystemMetrics (SM_CYBORDER) + 5;
}
else if (bIsTearOff)
{
m_rectTearOffCaption = CRect (CPoint (nBorderSize, nBorderSize),
CSize (size.cx - 2 * nBorderSize, iTearOffBarHeight));
size.cy += iTearOffBarHeight;
if (!CBCGPToolBar::IsCustomizeMode () && m_wndToolTip.GetSafeHwnd () == NULL)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -