You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1753 lines
42 KiB
C++

2 years ago
// XTPPopupBar.cpp : implementation of the CXTPPopupBar class.
//
// This file is a part of the XTREME COMMANDBARS MFC class library.
// (c)1998-2012 Codejock Software, All Rights Reserved.
//
// THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
// RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
// CONSENT OF CODEJOCK SOFTWARE.
//
// THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
// IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
// YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
// SINGLE COMPUTER.
//
// CONTACT INFORMATION:
// support@codejock.com
// http://www.codejock.com
//
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Resource.h"
#include "Common/XTPVC80Helpers.h"
#include "Common/XTPDrawHelpers.h"
#include "Common/XTPColorManager.h"
#include "Common/XTPImageManager.h"
#include "Common/XTPToolTipContext.h"
#include "Common/XTPHookManager.h"
#include "Common/XTPSystemHelpers.h"
#include "XTPCommandBarsDefines.h"
#include "XTPCommandBar.h"
#include "XTPPopupBar.h"
#include "XTPToolBar.h"
#include "XTPControls.h"
#include "XTPControl.h"
#include "XTPControlButton.h"
#include "XTPControlPopup.h"
#include "XTPCommandBars.h"
#include "XTPMouseManager.h"
#include "XTPPaintManager.h"
#include "XTPShortcutManager.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
double CXTPPopupBar::m_dMaxWidthDivisor = 1.0/3.0;
#ifndef EVENT_SYSTEM_MENUPOPUPSTART
#define EVENT_SYSTEM_MENUPOPUPSTART 0x0006
#define EVENT_SYSTEM_MENUPOPUPEND 0x0007
#define OBJID_MENU 0xFFFFFFFD
#endif
#define TID_HOVERUP 5001
#define TID_HOVERDOWN 5002
#define TID_TEAROFFSELECTED 5003
#define TID_EXPANDHOVER 5004
class CXTPPopupBar::CControlExpandButton: public CXTPControlButton
{
public:
CControlExpandButton()
{
m_controlType = xtpControlButton;
m_dwFlags = xtpFlagManualUpdate | xtpFlagNoMovable | xtpFlagSkipFocus | xtpFlagShowPopupBarTip;
}
void Draw(CDC* pDC);
virtual void OnExecute();
};
void CXTPPopupBar::CControlExpandButton::Draw(CDC* pDC)
{
GetPaintManager()->DrawSpecialControl(pDC, xtpButtonExpandMenu, this, m_pParent, TRUE, NULL);
}
void CXTPPopupBar::CControlExpandButton::OnExecute()
{
((CXTPPopupBar*)m_pParent)->ExpandBar();
}
IMPLEMENT_XTP_COMMANDBAR(CXTPPopupBar, CXTPCommandBar)
CXTPPopupBar::CXTPPopupBar()
{
m_scrollInfo.Init(this, TID_HOVERUP, TID_HOVERDOWN);
m_barType = xtpBarTypePopup;
m_barPosition = xtpBarPopup;
m_pControlPopup = 0;
m_ptPopup = 0;
m_rcExclude.SetRectEmpty();
m_rcTearOffGripper.SetRectEmpty();
m_rcResizeGripper.SetRectEmpty();
m_bResizable = FALSE;
m_popupFlags = xtpPopupRight;
m_bDynamicLayout = FALSE;
m_bTearOffPopup = FALSE;
m_bTearOffTracking = FALSE;
m_nTearOffID = 0;
m_nTearOffWidth = 0;
m_bShowShadow = TRUE;
m_rcBorders = CRect(2, 4, 2, 4);
m_bExpanding = FALSE;
m_nMRUWidth = 0;
m_bDoubleGripper = FALSE;
m_pTearOffBar = NULL;
m_szTearOffBar = CSize(0, 0);
m_nTearOffTimer = 0;
m_bContextMenu = FALSE;
m_bCollapsed = FALSE;
m_nMaxHeight = 0;
}
CXTPPopupBar* CXTPPopupBar::CreatePopupBar(CXTPCommandBars* pCommandBars)
{
CXTPPopupBar* pPopupBar = (CXTPPopupBar*)CXTPCommandBars::m_pPopupBarClass->CreateObject();
pPopupBar->SetCommandBars(pCommandBars);
return pPopupBar;
}
CXTPPopupBar::~CXTPPopupBar()
{
}
void CXTPPopupBar::SetTearOffPopup(LPCTSTR strCaption, UINT nID, int nWidth)
{
if (nID == 0)
{
m_bTearOffPopup = FALSE;
}
else
{
m_bTearOffPopup = TRUE;
m_strTearOffCaption = strCaption;
m_nTearOffID = nID;
m_nTearOffWidth = nWidth;
}
}
BOOL CXTPPopupBar::IsTearOffPopup(CString& strCaption, UINT& nID, int& nWidth)
{
strCaption = m_strTearOffCaption;
nID = m_nTearOffID;
nWidth = m_nTearOffWidth;
return m_bTearOffPopup;
}
BOOL CXTPPopupBar::IsVisible() const
{
return (m_hWnd != 0) && IsWindowVisible();
}
void CXTPPopupBar::ExpandBar()
{
if (m_bExpanded == FALSE && m_bCollapsed == TRUE)
{
SAFE_CALLPTR(m_pToolTipContext, CancelToolTips());
m_bExpanding = TRUE;
m_bExpanded = TRUE;
SetPopuped(-1);
SetSelected(-1);
OnRecalcLayout();
XTPMouseManager()->SetForceExpanded(TRUE);
XTPMouseManager()->IgnoreLButtonUp();
}
}
BOOL CXTPPopupBar::Create()
{
if (m_hWnd)
return TRUE;
CXTPCommandBars* pCommandBars = GetCommandBars();
UINT nClassStyle = !pCommandBars || pCommandBars->GetCommandBarsOptions()->bUseSystemSaveBitsStyle ? CS_SAVEBITS | CS_DBLCLKS : CS_DBLCLKS;
CWnd* pSite = GetSite();
CXTPDrawHelpers::RegisterWndClass(0, _T("XTPPopupBar"), nClassStyle);
int nLayoutRTL = pCommandBars && pCommandBars->IsLayoutRTL() ? WS_EX_LAYOUTRTL : 0;
if (!pCommandBars && GetImageManager()->IsDrawReverted() == 1) nLayoutRTL = WS_EX_LAYOUTRTL;
if (!pCommandBars && pSite && pSite->GetExStyle() & WS_EX_LAYOUTRTL) nLayoutRTL = WS_EX_LAYOUTRTL;
if (!CreateEx(WS_EX_TOOLWINDOW | nLayoutRTL, _T("XTPPopupBar"), 0, MFS_SYNCACTIVE | WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, CRect(0, 0, 0, 0), pSite, 0))
return FALSE;
SetWindowText(m_strTitle);
return TRUE;
}
#ifndef SPI_GETMENUANIMATION
#define SPI_GETMENUANIMATION 0x1002
#endif
#ifndef SPI_GETMENUFADE
#define SPI_GETMENUFADE 0x1012
#endif
XTPAnimationType CXTPPopupBar::GetAnimationType() const
{
CXTPCommandBars* pCommandBars = GetCommandBars();
if (pCommandBars)
{
if (GetWindow(GW_CHILD))
return xtpAnimateNone;
XTPAnimationType animationType = pCommandBars->GetCommandBarsOptions()->animationType;
switch (animationType)
{
case xtpAnimateWindowsDefault:
{
BOOL bEnabled = FALSE;
if (!SystemParametersInfo(SPI_GETMENUANIMATION, 0, &bEnabled, 0))
return xtpAnimateNone;
if (!bEnabled)
return xtpAnimateNone;
BOOL bFadeAnimation = FALSE;
if (!SystemParametersInfo(SPI_GETMENUFADE, 0, &bFadeAnimation, 0))
return xtpAnimateSlide;
animationType = bFadeAnimation ? xtpAnimateFade : xtpAnimateSlide;
}
break;
// choose any animation based on a random number
case xtpAnimateRandom:
{
switch (RAND_S() % 3)
{
case 0:
animationType = xtpAnimateFade;
break;
case 1:
animationType = xtpAnimateSlide;
break;
default:
animationType = xtpAnimateUnfold;
break;
}
}
break;
}
return animationType;
}
return xtpAnimateNone;
}
void CXTPPopupBar::OnControlsChanged()
{
m_nSelected = -1;
m_nPopuped = -1;
OnRecalcLayout();
}
void CXTPPopupBar::RecalcSizeLayout()
{
if (!m_bDynamicLayout && GetSafeHwnd() && IsTrackingMode())
{
CSize sz = CalcDynamicLayout(0, 0);
CXTPWindowRect rcWindow(this);
BOOL bRTL = GetExStyle() & WS_EX_LAYOUTRTL;
CRect rc = !bRTL ? CRect(CPoint(rcWindow.left, rcWindow.top), sz) : CRect(CPoint(rcWindow.right - sz.cx, rcWindow.top), sz);
if (rc == rcWindow)
{
Redraw();
return;
}
CXTPCommandBars* pCommandBars = GetCommandBars();
BOOL bShowKeyboardTips = IsKeyboardTipsVisible();
if (bShowKeyboardTips && pCommandBars) pCommandBars->HideKeyboardTips();
SetWindowRgn(NULL, FALSE);
CXTPPaintManager* pPaintManager = GetPaintManager();
SetWindowPos(0, rc.left, rc.top, rc.Width(), rc.Height(), SWP_SHOWWINDOW | SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER);
pPaintManager->SetCommandBarRegion(this);
pPaintManager->GetShadowManager()->OffsetShadow(this, rc.Size() - rcWindow.Size());
Redraw();
}
}
void CXTPPopupBar::OnRecalcLayout()
{
if (!m_bDynamicLayout && GetSafeHwnd() && IsTrackingMode())
{
UpdateShortcuts();
UpdateFlags();
CRect rc = CalculatePopupRect(m_ptPopup, CalcDynamicLayout(0, 0));
CXTPWindowRect rcWindow(this);
if (!m_bExpanding && rc == rcWindow)
{
Redraw();
return;
}
CXTPCommandBars* pCommandBars = GetCommandBars();
BOOL bShowKeyboardTips = IsKeyboardTipsVisible();
if (bShowKeyboardTips && pCommandBars) pCommandBars->HideKeyboardTips();
CXTPPaintManager* pPaintManager = GetPaintManager();
pPaintManager->GetShadowManager()->RemoveShadow(this);
BOOL bChanged = FALSE;
if (m_bExpanding)
{
BOOL bExpandDown = rcWindow.bottom < rc.bottom;
XTPAnimationType animationType = GetAnimationType();
if (IsAnimateType(animationType))
{
CDC* pDC = GetDesktopWindow()->GetDC();
CBitmap bmp;
bmp.CreateCompatibleBitmap(pDC, rc.Width(), rc.Height());
CXTPCompatibleDC dcWindow(pDC, &bmp);
dcWindow.BitBlt(0, 0, rc.Width(), rc.Height(), pDC, rc.left, rc.top, SRCCOPY);
GetDesktopWindow()->ReleaseDC(pDC);
ShowWindow(SW_HIDE);
GetSite()->UpdateWindow();
SetWindowPos(0, rc.left, rc.top, rc.Width(), rc.Height(), SWP_SHOWWINDOW | SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOREDRAW);
pPaintManager->SetCommandBarRegion(this);
bChanged = TRUE;
CWindowDC paintDC(this);
CXTPClientRect rcClientPost(this);
BOOL dwLayout = CXTPDrawHelpers::IsContextRTL(&paintDC);
CXTPDrawHelpers::SetContextRTL(&paintDC, FALSE);
paintDC.BitBlt(0, 0, rc.Width(), rc.Height(), &dcWindow, 0, 0, SRCCOPY);
CXTPDrawHelpers::SetContextRTL(&paintDC, dwLayout);
CXTPBufferDC animationDC(paintDC, rcClientPost);
DrawCommandBar(&animationDC, rcClientPost);
// Animation
pPaintManager->AnimateExpanding(this, &paintDC, &animationDC, bExpandDown);
}
XTPSoundManager()->PlaySystemSound(xtpSoundMenuPopup);
}
if (!bChanged)
{
SetWindowPos(0, rc.left, rc.top, rc.Width(), rc.Height(), SWP_SHOWWINDOW | SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER);
pPaintManager->SetCommandBarRegion(this);
}
if (m_barPosition == xtpBarPopup && m_bShowShadow && pPaintManager->m_bShowShadow && !IsCustomizeMode())
pPaintManager->GetShadowManager()->SetShadow(this, m_rcExclude, m_bRecursePopup ? 1 : 0);
if (m_pControlPopup)
m_pControlPopup->UpdateShadow();
Redraw();
if (bShowKeyboardTips)
{
PostMessage(WM_TIMER, XTP_TID_SHOWKEYBOARDTIPS);
}
m_bExpanding = FALSE;
}
}
void CXTPPopupBar::_MakeSameWidth(int nStart, int nLast, int nWidth)
{
for (int i = nStart; i < nLast; i++)
{
CXTPControl* pControl = GetControl(i);
if (!pControl || pControl->GetParent() != this || !pControl->IsVisible())
continue;
CRect rc = pControl->GetRect();
pControl->SetRect(CRect(rc.left, rc.top, rc.left + nWidth, rc.bottom));
}
}
CRect CXTPPopupBar::GetBorders()
{
if (m_barType == xtpBarTypeNormal)
return m_rcBorders;
return GetPaintManager()->GetCommandBarBorders(this);
}
CSize CXTPPopupBar::CalcDynamicLayout(int nLength, DWORD /*nMode*/)
{
m_bDynamicLayout = TRUE;
CClientDC dc(this);
CXTPFontDC font(&dc, GetPaintManager()->GetCommandBarFont(this));
RECT rcWork;
SystemParametersInfo(SPI_GETWORKAREA, NULL, &rcWork, 0);
CRect rcBorders = GetBorders();
CSize szTearOffGripper(0);
if (m_bTearOffPopup)
{
szTearOffGripper = GetPaintManager()->DrawTearOffGripper(&dc, 0, FALSE, FALSE);
rcBorders.top += szTearOffGripper.cy;
}
if (m_barType == xtpBarTypeNormal)
{
UpdateShortcuts();
CSize sz = m_pControls->CalcDynamicSize(&dc, GetWidth(), LM_COMMIT | LM_HORZ | LM_POPUP, rcBorders);
m_rcTearOffGripper.SetRect(rcBorders.left, rcBorders.top - szTearOffGripper.cy, sz.cx - rcBorders.right, rcBorders.top);
m_rcResizeGripper.SetRectEmpty();
m_bDynamicLayout = FALSE;
return sz;
}
CXTPControl* pControlGallery = GetControls()->FindControl(xtpControlGallery, -1, TRUE, FALSE);
m_bResizable = pControlGallery ? pControlGallery->IsCustomizeResizeAllow() : 0;
CSize szResizeGripper(0);
if (m_bResizable)
{
szResizeGripper.cy = m_bResizable != 2 ? 11 : 8;
rcBorders.bottom += szResizeGripper.cy;
}
if (nLength == 0)
{
for (int i = 0; i < GetControlCount(); i++)
{
CXTPControl* pControl = GetControl(i);
if (!pControl || pControl->GetParent() != this)
continue;
pControl->OnCalcDynamicSize(0);
}
UpdateExpandingState();
UpdateShortcuts();
}
CXTPControl* pButtonExpand = m_pControls->FindControl(XTP_ID_POPUPBAR_EXPAND);
CSize szButtonExpand(0);
if (m_bCollapsed)
{
szButtonExpand = GetPaintManager()->DrawSpecialControl(&dc, xtpButtonExpandMenu, NULL, this, FALSE, NULL);
rcBorders.bottom += szButtonExpand.cy;
if (!pButtonExpand)
pButtonExpand = m_pControls->Add(new CControlExpandButton(), XTP_ID_POPUPBAR_EXPAND, _T(""), -1, TRUE);
pButtonExpand->SetHideFlags(xtpHideGeneric);
}
else if (pButtonExpand) pButtonExpand->SetHideFlags(xtpHideGeneric);
CSize sz = m_pControls->CalcPopupSize(&dc, nLength, GetWidth(), rcBorders);
if (m_bCollapsed)
{
pButtonExpand->SetHideFlags(xtpNoHide);
pButtonExpand->SetRect(CRect(rcBorders.left, sz.cy - rcBorders.bottom, sz.cx - rcBorders.right, sz.cy - rcBorders.bottom + szButtonExpand.cy));
}
m_rcTearOffGripper.SetRect(rcBorders.left, rcBorders.top - szTearOffGripper.cy, sz.cx - rcBorders.right, rcBorders.top);
m_rcResizeGripper.SetRect(rcBorders.left, sz.cy - rcBorders.bottom, sz.cx - rcBorders.right, sz.cy - rcBorders.bottom + szResizeGripper.cy);
m_bDynamicLayout = FALSE;
return sz;
}
CRect CXTPPopupBar::CalculatePopupRect(CPoint ptPopup, CSize sz)
{
RECT rcWork = m_rcExclude.IsRectEmpty() ? XTPMultiMonitor()->GetWorkArea(ptPopup) : XTPMultiMonitor()->GetWorkArea(m_rcExclude);
RECT rcScreen = m_rcExclude.IsRectEmpty() ? XTPMultiMonitor()->GetScreenArea(ptPopup) : XTPMultiMonitor()->GetScreenArea(m_rcExclude);
// If point is on the screen, but not in the work area, then the point
// must be inside an AppBar.
if (m_rcExclude.IsRectEmpty() && PtInRect(&rcScreen, ptPopup) && !PtInRect(&rcWork, ptPopup))
{
rcWork = rcScreen;
}
if (!m_rcExclude.IsRectEmpty() && !CRect().IntersectRect(&rcWork, m_rcExclude) && CRect().IntersectRect(&rcScreen, m_rcExclude))
{
rcWork = rcScreen;
}
rcWork.bottom -= 5; // for shadow
CPoint ptCenterRect = m_rcExclude.CenterPoint();
BOOL bScroll = FALSE, bWrap = FALSE;
CXTPCommandBars* pCommandars = GetCommandBars();
BOOL bNoScroll = (pCommandars ? pCommandars->GetCommandBarsOptions()->bWrapLargePopups : FALSE) || m_bMultiLine;
if (m_nMaxHeight && sz.cy > m_nMaxHeight)
{
sz.cy = m_nMaxHeight;
bScroll = TRUE;
}
if (m_rcExclude.Height() == 0 && (m_popupFlags & xtpPopupUp))
ptPopup.y = ptPopup.y - sz.cy;
if (m_rcExclude.Height() == 0 && ptPopup.y > rcWork.bottom)
{
ptPopup.y = ptPopup.y - sz.cy;
}
else if (ptPopup.y + sz.cy > rcWork.bottom)
{
if (m_rcExclude.Height() == 0)
{
ptPopup.y = (ptPopup.y < (rcWork.bottom - rcWork.top)/2 ? rcWork.bottom : ptPopup.y)- sz.cy;
}
else
{
if (m_popupFlags & xtpPopupDown)
{
ptPopup.y = m_rcExclude.top - sz.cy;
if (ptPopup.y < rcWork.top)
{
if (bNoScroll)
{
m_popupFlags &= ~xtpPopupDown;
if (m_pControlPopup && (m_pControlPopup->GetType() != xtpControlComboBox || GetParentCommandBar()->GetType() == xtpBarTypePopup))
{
m_rcExclude = m_pControlPopup->GetRect();
AdjustExcludeRect(m_rcExclude, TRUE);
GetParentCommandBar()->ClientToScreen(m_rcExclude);
}
if (m_popupFlags & xtpPopupLeft)
{
ptPopup.y = rcWork.bottom - sz.cy;
}
else
{
ptPopup.x = m_rcExclude.right;
ptPopup.y = rcWork.bottom - sz.cy;
}
}
else
{
bScroll = TRUE;
if (ptCenterRect.y > (rcWork.bottom - rcWork.top)/2)
{
ptPopup.y = rcWork.top;
sz.cy = m_rcExclude.top - rcWork.top;
}
else
{
ptPopup.y = m_rcExclude.bottom;
sz.cy = rcWork.bottom - ptPopup.y;
}
}
}
}
else
{
ptPopup.y = rcWork.bottom - sz.cy;
}
}
if (ptPopup.y < rcWork.top) ptPopup.y = rcWork.top;
if (ptPopup.y + sz.cy > rcWork.bottom && ptPopup.y == rcWork.top)
{
if (bNoScroll)
{
bWrap = TRUE;
}
else
{
sz.cy = rcWork.bottom - ptPopup.y;
bScroll = TRUE;
}
}
}
if (bWrap && !m_bMultiLine && (GetType() == xtpBarTypePopup))
{
sz = CalcDynamicLayout(rcWork.bottom - rcWork.top, 0);
}
if (m_popupFlags == (xtpPopupLeft | xtpPopupDown) && m_rcExclude.Width() != 0)
ptPopup.x = m_rcExclude.right - sz.cx;
else if (m_popupFlags & xtpPopupLeft && m_rcExclude.Width() != 0)
ptPopup.x = m_rcExclude.left - sz.cx;
else if ((m_popupFlags & xtpPopupLeft) && m_rcExclude.Width() == 0)
ptPopup.x -= sz.cx;
if (ptPopup.x + sz.cx > rcWork.right)
{
if (m_rcExclude.Width() == 0 && ptPopup.x > rcWork.right)
ptPopup.x = ptPopup.x - sz.cx;
else if (m_rcExclude.Width() == 0)
ptPopup.x = rcWork.right - sz.cx;
else
{
ptPopup.x = (m_popupFlags & xtpPopupDown ? rcWork.right : m_rcExclude.left) - sz.cx ;
m_popupFlags |= xtpPopupLeft;
}
if (ptPopup.x < rcWork.left)
ptPopup.x = rcWork.left;
}
else if (ptPopup.x < rcWork.left)
{
if (m_rcExclude.Width() != 0)
{
ptPopup.x = m_popupFlags & xtpPopupDown ? rcWork.left : m_rcExclude.right;
m_popupFlags &= ~xtpPopupLeft;
}
else if (m_popupFlags & xtpPopupLeft)
{
ptPopup.x = rcWork.left;
m_popupFlags &= ~xtpPopupLeft;
}
}
m_scrollInfo.bScroll = bScroll && (GetType() == xtpBarTypePopup && GetPosition() == xtpBarPopup);
if (m_scrollInfo.bScroll)
{
m_scrollInfo.nScrollFirst = 0;
AdjustScrolling(&sz);
}
return CRect(ptPopup, sz);
}
void CXTPPopupBar::UpdateLocation(CSize sz)
{
CRect rc = CalculatePopupRect(m_ptPopup, sz);
SetWindowPos(&CWnd::wndTopMost, rc.left, rc.top, rc.Width(), rc.Height(), SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_SHOWWINDOW | (IsWindowVisible() ? SWP_NOZORDER : 0));
}
void CXTPPopupBar::AdjustScrolling(LPSIZE lpSize, BOOL bDown, BOOL bInvalidate)
{
CSize sz = lpSize ? *lpSize : CXTPWindowRect(this).Size();
m_scrollInfo.btnDown.m_rc.SetRectEmpty();
m_scrollInfo.btnUp.m_rc.SetRectEmpty();
int nCount = GetControlCount();
CRect rcBorders = GetBorders();
int nSeparator = GetPaintManager()->DrawCommandBarSeparator(NULL, this, NULL, FALSE).cy;
CSize szTearOffGripper(0);
if (m_bTearOffPopup)
{
szTearOffGripper = GetPaintManager()->DrawTearOffGripper(NULL, 0, FALSE, FALSE);
rcBorders.top += szTearOffGripper.cy;
}
if (m_bResizable)
{
rcBorders.bottom += m_rcResizeGripper.Height();
}
CXTPControl* pButtonExpand = m_pControls->FindControl(XTP_ID_POPUPBAR_EXPAND);
CSize szButtonExpand(0);
if (m_bCollapsed)
{
szButtonExpand = GetPaintManager()->DrawSpecialControl(NULL, xtpButtonExpandMenu, NULL, this, FALSE, NULL);
rcBorders.bottom += szButtonExpand.cy;
if (!pButtonExpand)
pButtonExpand = m_pControls->Add(new CControlExpandButton(), XTP_ID_POPUPBAR_EXPAND, _T(""), -1, TRUE);
pButtonExpand->SetHideFlags(xtpHideGeneric);
}
else if (pButtonExpand) pButtonExpand->SetHideFlags(xtpHideGeneric);
int nScrollHeight = 16;
int i;
if (!bDown)
{
if (m_scrollInfo.nScrollFirst == 1)
m_scrollInfo.nScrollFirst = 0;
int nPos = rcBorders.top;
if (m_scrollInfo.nScrollFirst != 0)
{
nPos += nScrollHeight;
m_scrollInfo.btnDown.m_rc.SetRect(rcBorders.left, rcBorders.top, sz.cx - rcBorders.right, nPos);
}
ASSERT(m_scrollInfo.nScrollFirst < nCount && m_scrollInfo.nScrollFirst >= 0);
BOOL bFirst = TRUE;
for (i = m_scrollInfo.nScrollFirst; i < nCount ; i++)
{
CXTPControl* pControl = GetControl(i);
pControl->SetHideFlag(xtpHideScroll, FALSE);
if (!pControl->IsVisible())
continue;
int nItemHeight = pControl->GetRect().Height();
if (pControl->GetBeginGroup()) nPos += nSeparator;
if (sz.cy - (nPos + nItemHeight) < nScrollHeight + rcBorders.bottom)
{
if (!bFirst)
break;
else
nItemHeight = sz.cy - rcBorders.bottom - rcBorders.top;
}
bFirst = FALSE;
pControl->SetRect(CRect(rcBorders.left, nPos, sz.cx - rcBorders.right, nPos + nItemHeight));
nPos += nItemHeight;
}
for (int j = i; j < nCount; j++)
{
GetControl(j)->SetHideFlag(xtpHideScroll, TRUE);
}
m_scrollInfo.nScrollLast = i;
if (i != nCount)
{
m_scrollInfo.btnUp.m_rc.SetRect(rcBorders.left, sz.cy - rcBorders.bottom - nScrollHeight, sz.cx - rcBorders.right, sz.cy - rcBorders.bottom);
}
}
else
{
if (m_scrollInfo.nScrollLast == nCount - 1)
m_scrollInfo.nScrollLast = nCount;
int nPos = sz.cy - rcBorders.bottom;
if (m_scrollInfo.nScrollLast != nCount)
{
nPos -= nScrollHeight;
m_scrollInfo.btnUp.m_rc.SetRect(rcBorders.left, sz.cy - rcBorders.bottom - nScrollHeight, sz.cx - rcBorders.right, sz.cy - rcBorders.bottom);
}
ASSERT(m_scrollInfo.nScrollLast <= nCount && m_scrollInfo.nScrollLast > 0);
for (i = m_scrollInfo.nScrollLast - 1 ; i >= 0 ; i--)
{
CXTPControl* pControl = GetControl(i);
pControl->SetHideFlag(xtpHideScroll, FALSE);
if (!pControl->IsVisible())
continue;
int nItemHeight = pControl->GetRect().Height();
if (nPos - nItemHeight < nScrollHeight)
{
break;
}
pControl->SetRect(CRect(rcBorders.left, nPos - nItemHeight, sz.cx - rcBorders.right, nPos));
nPos -= nItemHeight;
if (pControl->GetBeginGroup()) nPos -= nSeparator;
}
for (int j = i; j >= 0; j--)
{
GetControl(j)->SetHideFlag(xtpHideScroll, TRUE);
}
m_scrollInfo.nScrollFirst = i + 1;
if (i != -1)
{
m_scrollInfo.btnDown.m_rc.SetRect(rcBorders.left, rcBorders.top, sz.cx - rcBorders.right, rcBorders.top + nScrollHeight);
}
}
if (m_bCollapsed)
{
pButtonExpand->SetHideFlags(xtpNoHide);
pButtonExpand->SetRect(CRect(rcBorders.left, sz.cy - rcBorders.bottom, sz.cx - rcBorders.right, sz.cy - rcBorders.bottom + szButtonExpand.cy));
}
m_rcTearOffGripper.SetRect(rcBorders.left, rcBorders.top - szTearOffGripper.cy, sz.cx - rcBorders.right, rcBorders.top);
if (m_bResizable) m_rcResizeGripper.SetRect(rcBorders.left, sz.cy - rcBorders.bottom, sz.cx - rcBorders.right, sz.cy - rcBorders.bottom + m_rcResizeGripper.Height());
if (bInvalidate) Redraw();
}
void CXTPCommandBar::UpdateShortcuts()
{
CXTPCommandBars* pCommandBars = GetCommandBars();
if (!pCommandBars)
return;
if (!pCommandBars->GetCommandBarsOptions()->bAutoUpdateShortcuts)
return;
BOOL bHideAccelerators = DYNAMIC_DOWNCAST(CXTPPopupBar, GetRootParent()) != NULL &&
!pCommandBars->GetCommandBarsOptions()->bShowContextMenuAccelerators;
for (int i = 0; i < GetControlCount(); i++)
{
CXTPControl* pControl = GetControl(i);
if (!pControl || pControl->GetParent() != this || !pControl->IsVisible())
continue;
if (bHideAccelerators)
{
pControl->m_strShortcutTextAuto.Empty();
continue;
}
CString strShortcut;
if (pControl->GetID() != 0)
{
pCommandBars->GetShortcutManager()->FindDefaultAccelerator(pControl->GetID(), strShortcut);
pControl->m_strShortcutTextAuto = strShortcut;
}
}
}
void CXTPPopupBar::AdjustExcludeRect(CRect& rc, BOOL bVertical)
{
m_pControlPopup->AdjustExcludeRect(rc, bVertical);
}
AFX_INLINE BOOL IsVerticalPosition(CXTPCommandBar* pCommandBar)
{
return IsVerticalPosition(pCommandBar->GetPosition()) ||
(pCommandBar->GetType() == xtpBarTypePopup && pCommandBar->GetPosition() == xtpBarFloating);
}
void CXTPPopupBar::UpdateFlags()
{
if (m_pControlPopup)
{
BOOL bLayoutRTL = IsLayoutRTL();
CXTPCommandBar* pParent = GetParentCommandBar();
ASSERT(pParent);
if (!pParent)
return;
m_popupFlags = xtpPopupRight;
if (m_pControlPopup->m_dwFlags & xtpFlagLeftPopup || bLayoutRTL) m_popupFlags |= xtpPopupLeft;
if (pParent->GetFlags() & xtpFlagSmartLayout && pParent->GetPosition() == xtpBarPopup)
{
m_popupFlags |= xtpPopupDown;
}
else if (!IsVerticalPosition(pParent))
{
m_popupFlags |= xtpPopupDown;
}
else
{
if (pParent->GetPosition() == xtpBarRight || (pParent->GetType() == xtpBarTypePopup &&
pParent->IsPopupBar() && ((CXTPPopupBar*)pParent)->m_popupFlags & xtpPopupLeft))
m_popupFlags = xtpPopupLeft;
}
m_rcExclude = m_pControlPopup->GetRect();
if (m_pControlPopup->GetType() == xtpControlComboBox && pParent->GetType() != xtpBarTypePopup)
{
m_popupFlags |= xtpPopupDown;
}
else AdjustExcludeRect(m_rcExclude, IsVerticalPosition(pParent));
pParent->ClientToScreen(m_rcExclude);
m_ptPopup.x = (m_popupFlags & xtpPopupDown) ? m_rcExclude.left : m_rcExclude.right;
m_ptPopup.y = (m_popupFlags & xtpPopupDown) ? m_rcExclude.bottom : m_rcExclude.top;
}
}
void CXTPPopupBar::UpdateExpandingState()
{
CXTPCommandBars* pCommandBars = GetCommandBars();
if (!pCommandBars)
return;
int i;
if (pCommandBars->GetCommandBarsOptions()->bAlwaysShowFullMenus)
{
for (i = 0; i < GetControlCount(); i++)
{
CXTPControl* pControl = GetControl(i);
if (!pControl || pControl->GetParent() != this)
continue;
pControl->SetExpanded(FALSE);
}
m_bExpanded = TRUE;
return;
}
m_bCollapsed = FALSE;
BOOL bCollapsedExists = FALSE;
for (i = 0; i < GetControlCount(); i++)
{
CXTPControl* pControl = GetControl(i);
if (!pControl || pControl->GetParent() != this)
continue;
BOOL bVisible = pControl->IsVisible(xtpHideExpand | xtpHideScroll);
if (pCommandBars->IsControlHidden(pControl))
{
pControl->SetExpanded(bVisible);
}
else
{
pControl->SetExpanded(FALSE);
if (pControl->GetID() != XTP_ID_POPUPBAR_EXPAND && bVisible)
bCollapsedExists = TRUE;
}
}
for (i = 0; i < GetControlCount(); i++)
{
CXTPControl* pControl = GetControl(i);
if (!pControl || pControl->GetParent() != this)
continue;
pControl->SetHideFlag(xtpHideExpand, FALSE);
if (pControl->GetExpanded())
{
if (!m_bExpanded && bCollapsedExists)
{
pControl->SetHideFlag(xtpHideExpand, TRUE);
m_bCollapsed = TRUE;
}
}
}
}
void CXTPPopupBar::Animate()
{
CXTPCommandBar* pParentCommandBar = GetParentCommandBar();
BOOL bAnimate = pParentCommandBar ? pParentCommandBar->m_bAnimatePopup : TRUE;
if (bAnimate)
{
if (IsCustomizeMode() || GetWindow(GW_CHILD))
bAnimate = FALSE;
}
BOOL bRegionChanged = FALSE;
if (bAnimate)
{
XTPAnimationType animationType = GetAnimationType();
if (IsAnimateType(animationType))
{
if (m_pControlPopup)
{
m_pControlPopup->RedrawParent();
m_pControlPopup->GetParent()->UpdateWindow();
}
GetSite()->UpdateWindow();
CClientDC paintDC(this);
CXTPClientRect rcClient(this);
CXTPWindowRect rcWindow(this);
CXTPBufferDC animationDC(paintDC, rcClient);
DrawCommandBar(&animationDC, rcClient);
CDC* pDC = GetDesktopWindow()->GetDC();
BOOL dwLayout = CXTPDrawHelpers::IsContextRTL(&paintDC);
CXTPDrawHelpers::SetContextRTL(&paintDC, FALSE);
paintDC.BitBlt(0, 0, rcClient.Width(), rcClient.Height(), pDC, rcWindow.left, rcWindow.top, SRCCOPY);
GetDesktopWindow()->ReleaseDC(pDC);
CXTPDrawHelpers::SetContextRTL(&paintDC, dwLayout);
GetPaintManager()->SetCommandBarRegion(this);
bRegionChanged = TRUE;
// Animation
GetPaintManager()->Animate(&paintDC, &animationDC, rcClient, animationType);
}
}
if (pParentCommandBar) pParentCommandBar->m_bAnimatePopup = FALSE;
if (!bRegionChanged) GetPaintManager()->SetCommandBarRegion(this);
}
BOOL CXTPPopupBar::Popup(CXTPControlPopup* pControlPopup, BOOL bSelectFirst)
{
m_pControlPopup = pControlPopup;
if (!Create())
return FALSE;
if (m_pToolTipContext)
{
m_pToolTipContext->CancelToolTips();
}
LockRedraw();
CWnd* pWndOwner = GetOwnerSite();
if (pWndOwner) pWndOwner->SendMessage(WM_XTP_INITCOMMANDSPOPUP, 0, (LPARAM)this);
m_bTearOffSelected = FALSE;
m_bCollapsed = FALSE;
m_bExpanded = IsCustomizeMode() || XTPMouseManager()->IsForceExpanded();
UpdateFlags();
UpdateLocation(CalcDynamicLayout(0, 0));
if (!m_hWnd)
{
UnlockRedraw();
return FALSE;
}
if (m_pControlPopup && m_pControlPopup->m_pParent->GetSafeHwnd() == NULL)
{
UnlockRedraw();
DestroyWindow();
return FALSE;
}
SetTrackingMode(TRUE, bSelectFirst, bSelectFirst);
m_nIdleFlags &= ~xtpIdleLayout;
OnIdleUpdateCmdUI(TRUE, 0L);
if (!m_hWnd)
{
UnlockRedraw();
return FALSE;
}
Animate();
XTPSoundManager()->PlaySystemSound(xtpSoundMenuPopup);
CXTPPaintManager* pPaintManager = GetPaintManager();
if (pPaintManager && m_barPosition == xtpBarPopup && m_bShowShadow && pPaintManager->m_bShowShadow && !IsCustomizeMode())
{
pPaintManager->GetShadowManager()->RemoveShadow(this);
pPaintManager->GetShadowManager()->SetShadow(this, m_rcExclude, m_bRecursePopup ? 1 : 0);
}
m_nIdleFlags |= xtpIdleLayout;
UnlockRedraw();
return TRUE;
}
BOOL CXTPPopupBar::Popup(int x, int y, LPCRECT rcExclude)
{
m_ptPopup = CPoint(x, y);
if (rcExclude) m_rcExclude = *rcExclude;
return Popup(NULL);
}
BEGIN_MESSAGE_MAP(CXTPPopupBar, CXTPCommandBar)
ON_WM_MOUSEMOVE()
ON_WM_MOUSEACTIVATE()
ON_WM_LBUTTONDOWN()
ON_WM_SETCURSOR()
ON_WM_TIMER()
ON_WM_NCACTIVATE()
ON_WM_NCCREATE()
ON_MESSAGE(WM_FLOATSTATUS, OnFloatStatus)
END_MESSAGE_MAP()
void CXTPPopupBar::SwitchTearOffTracking(BOOL bShow, CPoint point)
{
CXTPCommandBars* pCommandBars = GetCommandBars();
ASSERT(pCommandBars);
if (!pCommandBars)
return;
ShowWindow(bShow ? SW_SHOWNA : SW_HIDE);
if (!bShow)
{
if (m_pTearOffBar == NULL)
{
m_pTearOffBar = pCommandBars->GetToolBar(m_nTearOffID);
if (m_pTearOffBar != NULL)
{
m_pTearOffBar->SetPosition(xtpBarFloating);
m_pTearOffBar->SetVisible(TRUE);
pCommandBars->RecalcFrameLayout();
}
}
if (m_pTearOffBar == NULL)
{
m_pTearOffBar = pCommandBars->AddCustomBar(m_strTearOffCaption, m_nTearOffID, TRUE);
m_pTearOffBar->m_nMRUWidth = m_nTearOffWidth;
for (int i = 0; i < GetControlCount(); i++)
{
CXTPControl* pControl = GetControl(i);
if (!pControl || pControl->GetParent() != this)
continue;
if (pControl->GetID() != XTP_ID_POPUPBAR_EXPAND)
{
CXTPControl* pControlClone = m_pTearOffBar->GetControls()->AddClone(pControl);
pControlClone->SetHideFlags(pControlClone->GetHideFlags() & ~(xtpHideScroll | xtpHideExpand));
}
}
}
ASSERT(m_pTearOffBar);
pCommandBars->GetSite()->SendMessage(WM_XTP_TEAROFFDONE, (WPARAM)m_pTearOffBar, (LPARAM)this);
m_szTearOffBar = m_pTearOffBar->CalcDynamicLayout(-1, LM_MRUWIDTH | LM_HORZ | LM_COMMIT);
CPoint pt(point.x - m_szTearOffBar.cx / 2, point.y - 10);
m_pTearOffBar->MoveWindow(pt.x, pt.y, m_szTearOffBar.cx, m_szTearOffBar.cy);
m_pTearOffBar->OnInitialUpdate();
m_pTearOffBar->Redraw();
}
else
{
if (m_pTearOffBar)
{
m_pTearOffBar->SetVisible(FALSE);
m_pTearOffBar = 0;
}
}
}
void CXTPPopupBar::TrackResize()
{
// don't handle if capture already set
if (::GetCapture() != NULL)
return;
BOOL bLayoutRTL = IsLayoutRTL();
CXTPControl* pControl = GetControls()->FindControl(xtpControlGallery, -1, TRUE, FALSE);
if (!pControl)
return;
CSize szControl(pControl->GetWidth(), pControl->GetRect().Height());
CSize szControlInit = szControl;
CSize szControlMin(pControl->GetCustomizeMinWidth(), pControl->GetCustomizeMinHeight());
SetPopuped(-1);
SetSelected(-1);
BOOL bResizeWidth = m_bResizable & 1;
BOOL bResizeHeight = m_bResizable & 2;
// set capture to the window which received this message
SetCapture();
ASSERT(m_hWnd == ::GetCapture());
CPoint pt(0, 0);
GetCursorPos(&pt);
// get messages until capture lost or cancelled/accepted
while (::GetCapture() == m_hWnd)
{
MSG msg;
if (!::GetMessage(&msg, NULL, 0, 0))
{
AfxPostQuitMessage((int)msg.wParam);
break;
}
if (msg.message == WM_LBUTTONUP)
break;
else if (msg.message == WM_MOUSEMOVE && pt != msg.pt)
{
if (bLayoutRTL)
szControl += CSize(pt.x - msg.pt.x, msg.pt.y - pt.y);
else
szControl += CSize(msg.pt.x - pt.x, msg.pt.y - pt.y);
if (bResizeWidth) pControl->SetWidth(max(szControl.cx, szControlMin.cx));
if (bResizeHeight) pControl->SetHeight(max(szControl.cy, szControlMin.cy));
RecalcSizeLayout();
pt = msg.pt;
}
else if (msg.message == WM_KEYDOWN)
{
if (msg.wParam == VK_ESCAPE)
{
if (bResizeWidth) pControl->SetWidth(szControlInit.cx);
if (bResizeHeight) pControl->SetHeight(szControlInit.cy);
RecalcSizeLayout();
break;
}
}
else
DispatchMessage(&msg);
}
ReleaseCapture();
}
void CXTPPopupBar::TrackTearOff()
{
m_pTearOffBar = NULL;
CRect rcGripper = m_rcTearOffGripper;
ClientToScreen(&rcGripper);
BOOL bShow = TRUE;
// don't handle if capture already set
if (::GetCapture() != NULL)
return;
// set capture to the window which received this message
SetCapture();
ASSERT(this == CWnd::GetCapture());
CPoint pt(0, 0);
// get messages until capture lost or cancelled/accepted
while (CWnd::GetCapture() == this)
{
MSG msg;
if (!::GetMessage(&msg, NULL, 0, 0))
{
AfxPostQuitMessage((int)msg.wParam);
break;
}
if (msg.message == WM_LBUTTONUP)
break;
else if (msg.message == WM_MOUSEMOVE && pt != msg.pt)
{
pt = msg.pt;
BOOL bState = !(pt.x > rcGripper.right + 10 || pt.x < rcGripper.left - 10 ||
pt.y > rcGripper.bottom + 10 || pt.y < rcGripper.top - 10);
if (bState != bShow)
{
bShow = bState;
SwitchTearOffTracking(bState, pt);
}
if (m_pTearOffBar != NULL)
{
CPoint point(pt.x - m_szTearOffBar.cx / 2, pt.y - 10);
m_pTearOffBar->MoveWindow(point.x, point.y, m_szTearOffBar.cx, m_szTearOffBar.cy);
}
}
else if (msg.message == WM_KEYDOWN)
{
if (msg.wParam == VK_ESCAPE)
{
break;
}
}
else
DispatchMessage(&msg);
}
ReleaseCapture();
if (m_pTearOffBar)
{
GetCommandBars()->ClosePopups();
}
}
BOOL CXTPPopupBar::_MouseInResizeGripper(const POINT& pt)
{
if (m_rcResizeGripper.PtInRect(pt))
{
if (m_bResizable == 2)
{
return TRUE;
}
CRect rcResizeGripper(m_rcResizeGripper);
rcResizeGripper.left = rcResizeGripper.right - rcResizeGripper.Height();
if (rcResizeGripper.PtInRect(pt))
{
return TRUE;
}
}
return FALSE;
}
BOOL CXTPPopupBar::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
if (m_bResizable)
{
POINT pt;
GetCursorPos(&pt);
ScreenToClient(&pt);
if (_MouseInResizeGripper(pt))
{
SetCursor(AfxGetApp()->LoadStandardCursor(m_bResizable == 2 ? IDC_SIZENS : IsLayoutRTL() ? IDC_SIZENESW : IDC_SIZENWSE));
return TRUE;
}
}
return CXTPCommandBar::OnSetCursor(pWnd, nHitTest, message);
}
void CXTPPopupBar::OnLButtonDown(UINT nFlags, CPoint point)
{
if (m_bTearOffPopup && m_rcTearOffGripper.PtInRect(point) && !IsCustomizeMode())
{
SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZEALL));
CXTPMouseManager* pMouseManager = XTPMouseManager();
pMouseManager->LockMouseMove();
m_bTearOffTracking = TRUE;
TrackTearOff();
m_bTearOffTracking = FALSE;
pMouseManager->UnlockMouseMove();
pMouseManager->RefreshCursor();
return;
}
if (m_bResizable && _MouseInResizeGripper(point))
{
CXTPMouseManager* pMouseManager = XTPMouseManager();
pMouseManager->LockMouseMove();
TrackResize();
pMouseManager->UnlockMouseMove();
pMouseManager->RefreshCursor();
return;
}
CXTPCommandBar::OnLButtonDown(nFlags, point);
}
BOOL CXTPPopupBar::DestroyWindow()
{
if (!GetSafeHwnd())
return CXTPCommandBar::DestroyWindow();
CWnd* pWnd = GetWindow(GW_CHILD);
if (!pWnd)
return CXTPCommandBar::DestroyWindow();
CWnd* pWndParent = GetSite();
while (pWnd)
{
CWnd* pWndNext = pWnd->GetWindow(GW_HWNDNEXT);
pWnd->ShowWindow(SW_HIDE);
pWnd->SetParent(pWndParent);
pWnd = pWndNext;
}
return CXTPCommandBar::DestroyWindow();
}
BOOL CXTPPopupBar::SetTrackingMode(int bMode, BOOL bSelectFirst, BOOL bKeyboard)
{
if (!CXTPCommandBar::SetTrackingMode(bMode, bSelectFirst, bKeyboard))
return FALSE;
CWnd* pWnd = GetSite();
if (!bMode)
{
AccessibleNotifyWinEvent(EVENT_SYSTEM_MENUPOPUPEND, m_hWnd, OBJID_MENU, 0);
DestroyWindow();
CXTPCommandBar* pParentCommandBar = GetParentCommandBar();
if (pParentCommandBar)
pParentCommandBar->SetPopuped(-1);
if (pWnd && ::IsWindow(pWnd->m_hWnd)) pWnd->SendMessage(WM_XTP_UNINITCOMMANDSPOPUP, 0, (LPARAM)this);
Sleep(1);
m_pControlPopup = 0;
}
else
{
AccessibleNotifyWinEvent(EVENT_SYSTEM_MENUPOPUPSTART, m_hWnd, OBJID_MENU, 0);
}
if (pWnd && ::IsWindow(pWnd->m_hWnd)) pWnd->UpdateWindow();
return TRUE;
}
void CXTPPopupBar::OnMouseMove(UINT nFlags, CPoint point)
{
if (m_nLockRecurse > 0)
return;
if (GetParentCommandBar() != NULL && CXTPClientRect(this).PtInRect(point))
{
// restore selection
GetParentCommandBar()->SetSelected(m_pControlPopup->GetIndex());
}
if (m_scrollInfo.bScroll)
{
if (m_scrollInfo.btnUp.OnMouseMove(point) ||
m_scrollInfo.btnDown.OnMouseMove(point))
{
SetPopuped(-1);
}
}
if (m_bTearOffPopup && !IsCustomizeMode() && m_rcTearOffGripper.PtInRect(point) && !m_bTearOffSelected)
{
SetSelected(-1);
SetPopuped(-1);
m_nTearOffTimer = SetTimer(TID_TEAROFFSELECTED, 80, NULL);
}
CXTPCommandBar::OnMouseMove(nFlags, point);
}
CXTPCommandBar* CXTPPopupBar::GetParentCommandBar() const
{
return m_pControlPopup ? m_pControlPopup->GetParent() : NULL;
}
int CXTPPopupBar::OnMouseActivate(CWnd* /*pDesktopWnd*/, UINT /*nHitTest*/, UINT /*message*/)
{
return MA_NOACTIVATE;
}
BOOL CXTPPopupBar::OnNcActivate(BOOL bActive)
{
return bActive ? FALSE : CWnd::OnNcActivate(bActive);
}
BOOL CXTPPopupBar::OnNcCreate(LPCREATESTRUCT lpCreateStruct)
{
if (!CXTPCommandBar::OnNcCreate(lpCreateStruct))
return FALSE;
if (GetStyle() & MFS_SYNCACTIVE)
{
// syncronize activation state with top level parent
CWnd* pParentWnd = GetTopLevelParent();
ASSERT(pParentWnd != NULL);
if (!pParentWnd)
return FALSE;
CWnd* pActiveWnd = GetForegroundWindow();
BOOL bActive = (pParentWnd == pActiveWnd) ||
(pParentWnd->GetLastActivePopup() == pActiveWnd &&
pActiveWnd->SendMessage(WM_FLOATSTATUS, FS_SYNCACTIVE) != 0);
// the WM_FLOATSTATUS does the actual work
SendMessage(WM_FLOATSTATUS, bActive ? FS_ACTIVATE : FS_DEACTIVATE);
}
return TRUE;
}
LRESULT CXTPPopupBar::OnFloatStatus(WPARAM wParam, LPARAM)
{
// FS_SYNCACTIVE is used to detect MFS_SYNCACTIVE windows
LRESULT lResult = ((GetStyle() & MFS_SYNCACTIVE) && (wParam & FS_SYNCACTIVE));
return lResult;
}
void CXTPPopupBar::DrawCommandBar(CDC* pDC, CRect rcClipBox)
{
CXTPCommandBar::DrawCommandBar(pDC, rcClipBox);
if (m_scrollInfo.bScroll)
{
if (!m_scrollInfo.btnUp.m_rc.IsRectEmpty())
{
CPoint pt = m_scrollInfo.btnUp.m_rc.CenterPoint();
GetPaintManager()->Triangle(pDC, CPoint(pt.x - 3, pt.y), CPoint(pt.x + 3, pt.y), CPoint(pt.x, pt.y + 3), GetXtremeColor(COLOR_BTNTEXT));
}
if (!m_scrollInfo.btnDown.m_rc.IsRectEmpty())
{
CPoint pt = m_scrollInfo.btnDown.m_rc.CenterPoint();
GetPaintManager()->Triangle(pDC, CPoint(pt.x - 3, pt.y), CPoint(pt.x + 3, pt.y), CPoint(pt.x, pt.y - 3), GetXtremeColor(COLOR_BTNTEXT));
}
}
if (m_bTearOffPopup && GetControlCount() > 0)
{
GetPaintManager()->DrawTearOffGripper(pDC, m_rcTearOffGripper, m_bTearOffSelected, TRUE);
}
if (!m_rcResizeGripper.IsRectEmpty() && m_bResizable)
{
GetPaintManager()->DrawPopupResizeGripper(pDC, m_rcResizeGripper, m_bResizable);
}
}
BOOL CXTPPopupBar::SetSelected(int nSelected, BOOL bKeyboard)
{
if (!CXTPCommandBar::SetSelected(nSelected, bKeyboard))
return FALSE;
if (m_nSelected != -1 && !bKeyboard && (GetControl(m_nSelected)->GetID() == XTP_ID_POPUPBAR_EXPAND))
{
CXTPCommandBars* pCommandBars = GetCommandBars();
ASSERT(pCommandBars);
if (pCommandBars->GetCommandBarsOptions()->bShowFullAfterDelay)
{
SetTimer(TID_EXPANDHOVER, s_nExpandHoverDelay, NULL);
}
}
else
{
KillTimer(TID_EXPANDHOVER);
}
if (m_scrollInfo.bScroll && m_nSelected != -1)
{
if (GetControl(m_nSelected)->GetHideFlags() & xtpHideScroll)
{
if (m_nSelected >= m_scrollInfo.nScrollLast)
{
m_scrollInfo.nScrollLast = m_nSelected + 1;
AdjustScrolling(NULL, TRUE, TRUE);
}
else
{
m_scrollInfo.nScrollFirst = m_nSelected;
AdjustScrolling(NULL, FALSE, TRUE);
}
}
}
return TRUE;
}
void CXTPPopupBar::OnTimer(UINT_PTR nIDEvent)
{
int nCount = GetControlCount();
switch (nIDEvent)
{
case TID_HOVERUP:
if (m_scrollInfo.nScrollLast == nCount)
{
m_scrollInfo.btnUp.KillTimer();
return;
}
m_scrollInfo.nScrollLast++;
AdjustScrolling(NULL, TRUE, TRUE);
break;
case TID_HOVERDOWN:
if (m_scrollInfo.nScrollFirst == 0)
{
m_scrollInfo.btnDown.KillTimer() ;
return;
}
m_scrollInfo.nScrollFirst--;
AdjustScrolling(NULL, FALSE, TRUE);
break;
case TID_TEAROFFSELECTED:
{
CPoint pt;
GetCursorPos(&pt);
ScreenToClient(&pt);
if (!m_bTearOffSelected && m_rcTearOffGripper.PtInRect(pt))
{
m_bTearOffSelected = TRUE;
Redraw();
}
if (m_bTearOffSelected && !m_rcTearOffGripper.PtInRect(pt) && !m_bTearOffTracking)
{
m_bTearOffSelected = FALSE;
Redraw();
KillTimer(m_nTearOffTimer);
}
}
break;
case TID_EXPANDHOVER:
if (m_nSelected != -1 && GetControl(m_nSelected)->GetID() == XTP_ID_POPUPBAR_EXPAND)
{
GetControl(m_nSelected)->OnExecute();
}
KillTimer(TID_EXPANDHOVER);
break;
}
CXTPCommandBar::OnTimer(nIDEvent);
}
BOOL CXTPPopupBar::OnHookKeyDown(UINT nChar, LPARAM lParam)
{
if (m_bCollapsed)
{
if (nChar == VK_DOWN)
{
if (GetKeyState(VK_CONTROL) < 0 || m_pControls->GetNext(m_nSelected, +1) <= m_nSelected)
{
ExpandBar();
}
}
}
return CXTPCommandBar::OnHookKeyDown(nChar, lParam);
}
void CXTPPopupBar::SetDefaultItem(UINT uItem, BOOL fByPos)
{
CXTPControl* pControl = fByPos ? m_pControls->GetAt(uItem) : m_pControls->FindControl(xtpControlError, uItem, TRUE, FALSE);
if (pControl)
{
pControl->SetItemDefault(TRUE);
}
}
UINT CXTPPopupBar::GetDefaultItem(UINT /*gmdiFlags*/, BOOL fByPos)
{
for (int i = 0; i < GetControlCount(); i++)
{
CXTPControl* pControl = GetControl(i);
if (!pControl || pControl->GetParent() != this || !pControl->IsVisible())
continue;
if (pControl->IsItemDefault())
{
return fByPos ? pControl->GetIndex() : pControl->GetID();
}
}
return (UINT)-1;
}
void CXTPPopupBar::Copy(CXTPCommandBar* pCommandBar, BOOL bRecursive)
{
ASSERT_KINDOF(CXTPPopupBar, pCommandBar);
CXTPCommandBar::Copy(pCommandBar, bRecursive);
m_bTearOffPopup = ((CXTPPopupBar*)pCommandBar)->m_bTearOffPopup;
m_strTearOffCaption = ((CXTPPopupBar*)pCommandBar)->m_strTearOffCaption;
m_nTearOffID = ((CXTPPopupBar*)pCommandBar)->m_nTearOffID;
m_nTearOffWidth = ((CXTPPopupBar*)pCommandBar)->m_nTearOffWidth;
m_bShowShadow = ((CXTPPopupBar*)pCommandBar)->m_bShowShadow;
m_rcBorders = ((CXTPPopupBar*)pCommandBar)->m_rcBorders;
m_bContextMenu = ((CXTPPopupBar*)pCommandBar)->m_bContextMenu;
}
void CXTPPopupBar::SetPopupToolBar(BOOL bToolBarType)
{
m_barType = bToolBarType ? xtpBarTypeNormal : xtpBarTypePopup;
}
////////////////////////////////////////////////////////////////////////////
//
IMPLEMENT_XTP_COMMANDBAR(CXTPPopupToolBar, CXTPPopupBar)
CXTPPopupToolBar::CXTPPopupToolBar()
{
m_barType = xtpBarTypeNormal;
}
CSize CXTPPopupToolBar::CalcDynamicLayout(int, DWORD /*nMode*/)
{
return CXTPPopupBar::CalcDynamicLayout(0, 0);
}
CXTPPopupToolBar* CXTPPopupToolBar::CreatePopupToolBar(CXTPCommandBars* pCommandBars)
{
CXTPPopupToolBar* pPopupBar = (CXTPPopupToolBar*)CXTPCommandBars::m_pPopupToolBarClass->CreateObject();
pPopupBar->SetCommandBars(pCommandBars);
return pPopupBar;
}