// 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; }